2

使用 Zend(1 或 2),在模型映射器中抽象公共代码的最佳方法是什么?在控制器/视图中有相关的助手,在映射器中呢......

4

4 回答 4

3

我倾向于将我的映射器基于两个示例:

  1. Padraic Brady在深海中求生
  2. Dasprid的博客源码

Padraic 允许每个映射器组合其他映射器,保持代码 DRY 并将每个映射器精确地集中在它需要知道的那些数据库字段上。

Daspid 使用一个基本的映射器类来包含处理数据库连接的通用代码。

总之,应该有足够的地方来保存通用代码。

当然,Doctrine2 ORM通过配置管理其中的大部分内容。在几次尝试自己绘制地图后,我发现自己对 Doctrine 更满意。

于 2013-04-27T15:41:35.560 回答
1

只需在您的库或存储通用代码的任何地方创建一个类,可能类似于:

//library/My/Model/Mapper/Abstract.php
<?php

abstract class My_Model_Mapper_Abstract
{
    /**
     * Instance of Zend_Db_Table_Abstract
     *
     * @var Zend_Db_Table_Abstract $tableGateway
     */
    protected $tableGateway = null;
    /**
     * sets up the identity map
     */
    protected $map          = array();

    /**
     * Will accept a DbTable model passed or will instantiate
     * a Zend_Db_Table_Abstract object from table name.
     *
     * @param Zend_Db_Table_Abstract $tableGateway
     */
    public function __construct(Zend_Db_Table_Abstract $tableGateway = null)
    {
        if (is_null($tableGateway)) {
            $this->tableGateway = new Zend_Db_Table($this->tableName);
        } else {
            $this->tableGateway = $tableGateway;
        }
    }

    /**
     * Get the default database table adapter.
     *
     * @return Zend_Db_Table_Abstract
     */
    protected function getGateway()
    {
        return $this->tableGateway;
    }

    //truncated for space

    public function findById($id)
    {
        if ($this->getMap($id)) {
            return $this->getMap($id);
        }

        $select = $this->getGateway()->select();
        $select->where('id = ?', $id);

        $row = $this->getGateway()->fetchRow($select);

        $entity = $this->createEntity($row);

        $this->setMap($row->id, $entity);

        return $entity;
    }

    //truncated for space

    /**
     * Abstract method to be implemented by concrete mappers.
     */
    abstract protected function createEntity($row);
}

那么具体的实现可能类似于:

//application/modules/users/model/mappers/User.php
<?php

class Users_Model_Mapper_User extends My_Model_Mapper_Abstract
{
    protected $tableName = 'users';

    public function __construct(Zend_Db_Table_Abstract $tableGateway = null)
    {
        if (is_null($tableGateway)) {
            //TODO: inject this resource
            $tableGateway = new Application_Model_DbTable_User();
        } else {
            $tableGateway = $tableGateway;
        }

        parent::__construct($tableGateway);
    }

    protected function createEntity($row)
    {
        $data = array(
            'id'       => $row->id,
            'username' => $row->username,
            'password' => $row->password
        );
        $user = new Users_Model_User($data);

        return $user;
    }

    private function hashPassword($password)
    {
        return Password::createPasswordHash($password);
    }

    public function saveUser(My_Model_Entity_Abstract $user)
    {
        if (!is_null($user->id)) {

            $select = $this->getGateway()->select();
            $select->where('id = ?', $user->id);

            $row = $this->getGateway()->fetchRow($select);
        } else {
            $row = $this->getGateway()->createRow();
            $row->password = $this->hashPassword($user->password);
        }
        $row->username = $user->username;

        $row->save();
        return $row;
    }
}

这些是为了利用 ZF1 中常用的 DbTable 模型而创建的,并且仍在进行中。

ZF2 模型可能会有所不同,因为 ZF2 实现并扩展了更多 PHP SPL 库,因此进行一些修改可能会有用。

祝你好运!

于 2013-04-27T07:02:37.123 回答
0

Hydrators 看起来像一个有趣的解决方案http://framework.zend.com/manual/2.2/en/modules/zend.stdlib.hydrator.html

于 2013-05-21T19:03:24.300 回答
-1

实际上 Zend Framework 并没有提供任何内置的 ORM。只有Zend_Db_Table(and Zend_Db_Table_Row) 实现了Table Gateway模式。

在 ZF 项目中使用数据模型的常用方法之一是使用Doctrine 2 ORM。Doctrine 的第一个版本(Doctrine 1)实现了活动记录模式,第二个版本与Data Mapper一起使用。

在 Zend Framework 1 Quick Start 部分的创建模型和数据库表中,描述了数据映射器模式的可能的自我开发实现:

class Application_Model_Guestbook
{
    protected $_comment;
    protected $_created;
    protected $_email;
    protected $_id;

    public function __set($name, $value);
    public function __get($name);

    public function setComment($text);
    public function getComment();

    public function setEmail($email);
    public function getEmail();

    public function setCreated($ts);
    public function getCreated();

    public function setId($id);
    public function getId();
}

class Application_Model_GuestbookMapper
{
    public function save(Application_Model_Guestbook $guestbook);
    public function find($id);
    public function fetchAll();
}
于 2013-04-26T20:08:31.883 回答