Php Zend框架数据访问层(DAL)

Php Zend框架数据访问层(DAL),php,oop,zend-framework,data-access-layer,dao,Php,Oop,Zend Framework,Data Access Layer,Dao,翻阅了几本关于Zend Framework中数据访问的教程和书籍,似乎大多数人都在他们的模型(活动记录模式)甚至控制器中进行数据访问。我强烈反对这一点。因此,我希望有一个数据访问层(DAL),这样我的域层就可以通过不包含任何“ZF内容”而保持可移植性。我四处寻找,但没有真正找到我想要的东西。注意:我是ZF的新手 DAL结构 因此,第一个问题是将数据访问层放置在何处。虽然它当然可以放在库文件夹中,并向自动加载程序添加名称空间,但这似乎不符合逻辑,因为它特定于我的应用程序(因此应用程序文件夹是合适的

翻阅了几本关于Zend Framework中数据访问的教程和书籍,似乎大多数人都在他们的模型(活动记录模式)甚至控制器中进行数据访问。我强烈反对这一点。因此,我希望有一个数据访问层(DAL),这样我的域层就可以通过不包含任何“ZF内容”而保持可移植性。我四处寻找,但没有真正找到我想要的东西。注意:我是ZF的新手

DAL结构

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

/application/modules/default/dal/

但是,我不确定如何包含此文件夹,以便访问控制器中的类(无需使用includes/requires)。如果有人知道如何做到这一点,那就太棒了!当然,任何其他想法都是受欢迎的

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

实施

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

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

抱歉问了这么多问题。我只需要朝正确的方向努力。

在我看来,每个模型都应该有网关抽象(而不仅仅是数据库访问)。一把刀是不够的。如果您需要在某个时候从云中获取数据,该怎么办?这很快就会成为现实。如果您将网关逻辑抽象为某种通用逻辑,然后使用数据库实现它,那么您就可以两全其美

如果您选择,特定网关接口的实现可以使用通用数据映射器。我在一家小公司工作,总是使用PDO创建我的实现。这使我能够接近数据库,处理可能需要的任何有趣的SQL,但能够支持非常抽象的接口


我根本没有使用Zend框架。我不知道他们是否有数据映射工具可以帮助您实现网关接口。

在我看来,每个模型都应该有网关抽象(不仅仅是数据库访问)。一把刀是不够的。如果您需要在某个时候从云中获取数据,该怎么办?这很快就会成为现实。如果您将网关逻辑抽象为某种通用逻辑,然后使用数据库实现它,那么您就可以两全其美

如果您选择,特定网关接口的实现可以使用通用数据映射器。我在一家小公司工作,总是使用PDO创建我的实现。这使我能够接近数据库,处理可能需要的任何有趣的SQL,但能够支持非常抽象的接口



我根本没有使用Zend框架。我不知道他们是否有数据映射器工具可以帮助您实现网关接口。

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

第二,关于
ActiveRecord
,您必须知道,默认情况下,Zend Framework并没有实现它。。大多数教程都采用最简单的方法来教授新概念。通过简单的示例,业务逻辑的数量非常少,因此不需要增加另一层复杂性(数据库和模型对象之间的映射)它们组成了
域层
(模型),有两个基本模式:and。这对于初学者来说已经足够了

分析后,您将看到ActiveRecord行数据网关模式。主要区别在于 ActiveRecord对象(持久实体)承载业务逻辑和 行数据网关仅表示数据库中的一行 表示数据库行的对象上的业务逻辑,然后 成为ActiveRecord对象

此外,继Zend FrameworkQuick Start之后,您将认识到还有第三个组件,它使用

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

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);

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

$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