まず、もう少し概念的な飛躍が必要なようです。データ マッパー パターンを使用すると、データベース テーブルではなくオブジェクトの観点から考えることができます。この 2 つの記事は、飛躍する必要があるときに役立ちました。
http://phpmaster.com/building-a-domain-model/
http://phpmaster.com/integrating-the-data-mappers/
そうは言っても、ZF 1 には、データ マッパー/ドメイン モデルを構築するための非常に便利なツールがいくつかあります。
ZF 1 での規則は、使用している各テーブルが Zend_Db_Table api を介してアクセスできるようにすることです。私が見つけた最も簡単な方法は、各テーブルにDbTable リソースを使用することです。Zend_Db::factory
また、またはnew Zend_Db_Table('tableName')
または またはその他の魅力的な方法を使用することもできます。
この例は、mp3 ソング トラックに基づいています。
//in effect this is the database adapter for database table 'track', This is $tableGateway used later.
<?php
class Application_Model_DbTable_Track extends Zend_Db_Table_Abstract
{
//name of database table, required to be set if name of class does not match name of table
protected $_name = 'track';
//optional, column name of primary key
protected $_primary = 'id';
}
テーブルを Db アダプタと Zend_Db_Table API にアタッチする方法はいくつかありますが、この方法は実装が簡単で、マッパーの設定も簡単だと思います。
マッパー クラスは、データ ソースとオブジェクト (ドメイン エンティティ) の間の架け橋です。この例では、マッパーは Zend_Db_Table の API と対話します。
理解しておくべき非常に重要なポイント: Zend_Db_Table_Abstract を拡張するクラスを使用すると、Zend_Db コンポーネントのすべての基本機能を自由に使用できます。(find()、fetchall()、fetchRow()、select() ...)
<?php
class Music_Model_Mapper_Track extends Model_Mapper_Abstract
{
//the mapper to access the songs artist object
protected $artistMapper;
//the mapper to access to songs album object
protected $albumMapper;
/**
* accepts instance of Zend_Db_Table_Abstract
*
* @param Zend_Db_Table_Abstract $tableGateway
*/
public function __construct(Zend_Db_Table_Abstract $tableGateway = null)
{
//at this point I tend to hardcode $tablegateway but I don't have to
$tableGateway = new Application_Model_DbTable_Track();
parent::__construct($tableGateway);
//parent sets the $tablegateway variable and provides an abstract requirement
//for createEntity(), which is the point of this class
}
/**
* Creates concrete object of Music_Model_Track
*
* @param object $row
* @return Music_Model_Track
*/
public function createEntity($row)
{
$data = array(
'id' => $row->id,
'filename' => $row->filename,
'format' => $row->format,
'genre' => $row->genre,
'hash' => $row->hash,
'path' => $row->path,
'playtime' => $row->playtime,
'title' => $row->title,
'track_number' => $row->track_number,
'album' => $row->album_id,//foriegn key
'artist' => $row->artist_id//foriegn key
);
//instantiate new entity object
return new Music_Model_Track($data);
}
/**
* findById() is proxy for find() method and returns
* an entity object.
*
* @param type $id
* @return object Model_Entity_Abstract
*/
public function findById($id)
{
//instantiate the Zend_Db_Select object
$select = $this->getGateway()->select();
$select->where('id = ?', $id);
//retrieve one database table row
$row = $this->getGateway()->fetchRow($select);
//create one entity object Music_Model_Track
$entity = $this->createEntity($row);
//return one entity object Music_Model_Track
return $entity;
}
//truncated
}
これまでに行ったことは、次のオブジェクトを構築するという明確な目的のためだけです。
<?php
class Music_Model_Track extends Model_Entity_Abstract
{
/**
* $id, __set, __get and toArray() are implemented in the parent
*/
protected $album;
protected $artist;
protected $filename;
protected $format;
protected $genre;
protected $hash;
protected $path;
protected $playtime;
protected $title;
protected $track_number;
//artist and album mappers
protected $albumMapper = null;
protected $artistMapper = null;
//these are the important accessors/mutators because they convert a foreign key
//in the database table to an entity object.
public function getAlbum()
{
//if the album object is already set, use it.
if(!is_null($this->album) && $this->album instanceof Music_Model_Album) {
return $this->album;
} else {
//else we make a new album object
if(!$this->albumMapper) {
$this->albumMapper = new Music_Model_Mapper_Album();
}
//This is the album object we get from the id in our reference array.
return $this->albumMapper->findById($this->getReferenceId('album'));
}
}
//same as above only with the artist object.
public function getArtist()
{
if(!is_null($this->artist) && $this->artist instanceof Music_Model_Artist) {
return $this->artist;
} else {
if(!$this->artistMapper) {
$this->artistMapper = new Music_Model_Mapper_Artist();
}
return $this->artistMapper->findById($this->getReferenceId('artist'));
}
}
//the setters record the foriegn keys recorded in the table row to an array,
//this allows the album and artist objects to be loaded only when needed.
public function setAlbum($album)
{
$this->setReferenceId('album', $album);
return $this;
}
public function setArtist($artist)
{
$this->setReferenceId('artist', $artist);
return $this;
}
//standard setter and getters truncated...
}
so when using the track object you would get album or artist info like:
//this would be used in a controller most likely.
$mapper = new Music_Model_Mapper_Track();
$track = $mapper->findById('1');
//all of the information contained in the album or artist object is
//available to the track object.
//echo album title, year or artist. This album object also contains the artist object
//so the artist object would be available in two ways.
echo $track->album->title; //or
echo $track->artist->name;
echo $track->album->artist->name;
echo $track->getAlbum()->getArtist()->getName();
したがって、実際に決定する必要があるのは、アプリケーションをどのように構築するかです。私が明らかだと思うことは、あなたが実装したいオプションではないかもしれません。あなたの質問に対する答えの多くは、これらのリソースがどのように使用されるかによって異なります。
これが少しでもお役に立てば幸いです。