Using Zend (1 or 2), what is the best way to abstract common code in the model mappers? In the controller/view there are the relevant helpers, what about in the mappers...
4 に答える
私はマッパーを次の 2 つの例に基づいて作成する傾向があります。
- パドレイク・ブレイディによるディープエンドを生き残る
- Daspid のブログソース
Padraic を使用すると、各マッパーは他のマッパーを構成し、コードを DRY に保ち、各マッパーが知る必要のあるデータベース フィールドに正確に集中できます。
Daspirid は、基本マッパー クラスを使用して、db 接続を処理するための共通コードを含めます。
一緒に、共通のコードを保持するのに十分な場所があるはずです。
もちろん、Doctrine2 ORMは、構成によってこれらのほとんどを管理します。自分自身でマッピングを行うためのいくつかの半分満足のいく試みの後、私は Doctrine に満足していることに気づきました。
ライブラリまたは一般的なコードを保存する場所にクラスを作成するだけです。おそらく次のようなものです。
//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 は PHP SPL ライブラリの多くを実装および拡張しているため、ZF2 モデルは多少異なる可能性があるため、いくつかの変更が役立つ可能性があります。
幸運を!
ハイドレーターは興味深いソリューションのように見えますhttp://framework.zend.com/manual/2.2/en/modules/zend.stdlib.hydrator.html
実際、Zend Framework には組み込みの ORM はありません。テーブル ゲートウェイパターンを実装するZend_Db_Table
(および)だけがあります。Zend_Db_Table_Row
ZF プロジェクトでデータ モデルを操作する一般的な方法の 1 つは、Doctrine 2 ORMを使用することです。Doctrine の最初のバージョン (Doctrine 1) はActive recordパターンを実装し、2 番目のバージョンはData Mapperで動作します。
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();
}