php - Zend 框架数据访问层 (DAL)

标签 php oop zend-framework data-access-layer dao

浏览了一些有关 Zend Framework 中数据访问的教程和书籍,似乎大多数人都在他们的模型(事件记录模式)甚至 Controller 中进行数据访问。我强烈不同意这一点。因此,我想要一个数据访问层(DAL),这样我的域层就可以通过不包含任何“ZF 东西”来保持可移植性。我已经四处寻找,但还没有真正找到我想要的东西。注意:我是采埃孚的新手。

DAL结构

所以,第一个问题是在哪里放置数据访问层。虽然它当然可以放置在 library 文件夹中并向自动加载器添加命名空间,但这似乎不合逻辑,因为它特定于我的应用程序(因此 applications 文件夹是合适的)。我正在使用模块化结构。我正在考虑使用以下结构:

/application/modules/default/dal/

但是,我不确定如何包含此文件夹,以便我可以访问 Controller 中的类(不使用包含/需要)。如果有人知道如何实现这一点,那就太棒了!当然也欢迎任何其他想法。

这个想法是让我的 Controller 与数据访问对象(DAO)交互。然后 DAO 使用可以返回给 Controller 的模型。通过这样做,我可以保持我的模型完好无损。

实现

在其他语言中,我之前已经为每个模型实现了 DAO,例如DAL_User。这导致了大量的 DAO 类。有没有更聪明的方法来做到这一点(使用单个类使用外键似乎并不容易)?

我也非常感谢有关如何在 ZF 中实现我的 DAO 类的建议。我没有花太多时间阅读可用于数据库交互的所有组件,因此非常欢迎任何想法。我怀疑有比标准 PDO 更智能的东西(尽管它可能在内部使用 PDO)。名字掉落就足够了。

抱歉问了很多问题。我只需要朝着正确的方向插入。

最佳答案

嗯,在处理数据访问层时,您必须考虑的第一件事是该层也有子层,这是不寻常的发现现代框架中名为“dal”的文件夹(我以 Zend Framework 和 Symfony 为基础)。

其次,关于ActiveRecord,您必须知道默认情况下 Zend Frameworks 不实现它。大多数教程都采用最简单的方式来教授新概念。通过简单的示例,业务逻辑的数量是最少的,因此它们组成了域层(模型),而不是添加另一层复杂性(数据库和模型对象之间的映射)有两种基本模式:Table Data GatewayRow Data Gateway 。这对于初学者来说已经足够了。

After analyzing it, you will see some similarity between ActiveRecord and Row Data Gateway patterns. The main difference is that ActiveRecord objects (persistable entities) carries business logic and Row Data Gateway only represents a row in the database. If you add business logic on a object representing a database row, then it will become an ActiveRecord object.

此外,按照 Zend Framework 快速入门on the domain model section ,您会意识到还有第三个组件,它使用 Data Mapper Pattern .

因此,如果DAL的主要目的是在业务对象(模型)和存储之间映射数据,则此任务的责任委托(delegate)给数据映射器 如下:

class Application_Model_GuestbookMapper
{

    public function save(Application_Model_Guestbook $guestbook);

    public function find($id);

    public function fetchAll();

}

这些方法将与数据库抽象层交互并用数据填充域对象。类似这样的事情:

public function find($id, Application_Model_Guestbook $guestbook)
{

    $result = $this->getDbTable()->find($id);

    if (0 == count($result)) {

        return;

    }

    $row = $result->current();

    $guestbook->setId($row->id)

              ->setEmail($row->email)

              ->setComment($row->comment)

              ->setCreated($row->created);

}

如您所见,数据映射器Zend_Db_Table 交互。实例,它使用表数据网关模式。另一方面,$this->getDbTable->find() 返回 Zend_Db_Table_Row 的实例。 ,它实现了行数据网关模式(它是代表数据库行的对象)。

Tip: The domain object itself, the guestbook entity, was not created by the find() method on the DataMapper, instead, the idea is that object creation is a task of factories and you must inject the dependency in order to achieve the so called Dependency Inversion Principle (DIP) (part of the SOLID principles). But that's another subject, out of the scope of the question. I suggest you to access the following link http://youtu.be/RlfLCWKxHJ0

映射的内容从这里开始:

$guestbook->setId($row->id)
          ->setEmail($row->email)
          ->setComment($row->comment)
          ->setCreated($row->created);

到目前为止,我想我已经回答了您的主要问题,您的结构如下:

application/models/DbTable/Guestbook.php
application/models/Guestbook.php
application/models/GuestbookMapper.php

因此,如采埃孚快速入门中所示:

class GuestbookController extends Zend_Controller_Action
{

    public function indexAction()

    {
        $guestbook = new Application_Model_GuestbookMapper();

        $this->view->entries = $guestbook->fetchAll();

    }

}

也许您想要为数据映射器创建一个单独的文件夹。只需更改:

application/models/GuestbookMapper.php

application/models/DataMapper/GuestbookMapper.php

类名是

class Application_Model_DataMapper_GuestbookMapper

我发现您希望将域模型对象分成模块。这也是可能的,您所需要的只是遵循 ZF 的目录和 namespace guidelines for modules .

Final tip: I've spent a lot of time coding my own data mappers for finally realize that it's nightmare to maintain the object mapping when your application grows with a lot of correlated entities. (i.e Account objects that contain references to users objects, users that contain roles, and so on) It's not so easy to write the mapping stuff at this point. So I strongly recommend you, if you really want a true object-relational mapper, to first study how legacy frameworks perform such tasks and perhaps use it. So, take some spare time with Doctrine 2, which is the one of the best so far (IMO) using the DataMapper pattern.

就是这样。您仍然可以使用 /dal 目录来存储 DataMappers,只需 register the namespace ,以便自动加载器能够找到它。

关于php - Zend 框架数据访问层 (DAL),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12076949/

相关文章:

java - 如何在java中创建同一类对象的多个引用

php - 无法从自定义 Magento 模块将数据保存在 MySQL 中

php - 在 ubuntu 14.04 上编译带有 ZTS 支持的 PHP

javascript - 如何修复 JavaScript 中的 "this.property is not iterable at window.onload"

c++ - 设计一个好的 C++ 包装类来包装多种功能

zend-framework - 从 Zend 教程开始 - Zend_DB_Adapter 抛出异常 : "SQLSTATE[HY000] [2002] No such file or directory"

php - 如何在 zend 框架中的特定时间禁用网站?

php - 如何在mysql中没有子查询的情况下从两个表中获取计数

php - Htaccess 和水印

php - 文件存在于/tmp,但 PHP 在 CentOS 上返回 "No such file or directory"