模型映射器,抽象公共代码的最佳方法是什么,即帮助器,装饰器

时间:2013-04-26 19:42:16

标签: php zend-framework model-view-controller mapper

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

4 个答案:

答案 0 :(得分:3)

我倾向于将我的地图制作者基于两个例子:

    Padraic Brady的
  1. Survive the Deep End
  2. Dasprid's blog source
  3. Padraic允许每个映射器组成其他映射器,保持代码DRY并将每个映射器精确地聚焦在它需要知道的那些数据库字段上。

    Dasprid使用基本映射器类来包含用于处理数据库连接的公共代码。

    应该有足够的地方来保存公共代码。

    当然,Doctrine2 ORM通过配置管理大部分内容。经过几次令人满意的尝试来映射自己之后,我发现自己对Doctrine很开心。

答案 1 :(得分: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库,因此一些修改可能会有用。

祝你好运!

答案 2 :(得分:0)

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

答案 3 :(得分:-1)

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

在ZF项目中使用数据模型的常用方法之一是使用Doctrine 2 ORM。第一版Doctrine(Doctrine 1)实现了Active record模式,第二版使用Data Mapper

Create a Model and Database Table部分的Zend Framework 1快速入门中,描述了可能自行开发的Data Mapper模式实现:

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