Typically your entity models will not exist in void they will exist in concert with some type of Data Mapper Model. The Mapper will typically be charged with gathering the data from whatever source is handy and then constructing the entity model.
For example I have a music collection that has an album entity:
<?php class Music_Model_Album extends Model_Entity_Abstract implements Interface_Album { //id is supplied by Entity_Abstract protected $name; protected $art; protected $year; protected $artist; //alias of artist_id in Database Table, foreign key protected $artistMapper = null; /** * Constructor, copied from Entity_Abstract */ //constructor is called in mapper to instantiate this model public function __construct(array $options = null) { if (is_array($options)) { $this->setOptions($options); } } /** * Truncated for brevity. * Doc blocks and normal getters and setters removed */ public function getArtist() { //if $this->artist is set return if (!is_null($this->artist) && $this->artist instanceof Music_Model_Artist) { return $this->artist; } else { //set artist mapper if needed if (!$this->artistMapper) { $this->artistMapper = new Music_Model_Mapper_Artist(); } //query the mapper for the artist table and get the artist entity model return $this->artistMapper->findById($this->getReferenceId('artist')); } } //set the artist id in the identity map public function setArtist($artist) { //artist id is sent to identity map. Can be called later if needed - lazy load $this->setReferenceId('artist', $artist); return $this; } //each album will have multiple tracks, this method allows retrieval as required. public function getTracks() { //query mapper for music track table to get tracks from this album $mapper = new Music_Model_Mapper_Track(); $tracks = $mapper->findByColumn('album_id', $this->id, 'track ASC'); return $tracks; } }
In the mapper I would build the entity model like:
//excerpt from Model_Mapper_Album //createEntity() is declared abstract in Model_Mapper_Abstract public function createEntity($row) { $data = array( 'id' => $row->id, 'name' => $row->name, 'art' => $row->art, 'year' => $row->year, 'artist' => $row->artist_id,// ); return new Music_Model_Album($data); }
to use this method in a mapper method, might look like:
//this is actually from Model_Mapper_Abstract, b ut give the correct idea and will work in any of my mappers. //this returns one and only one entity public function findById($id) { //if entity id exists in the identity map if ($this->getMap($id)) { return $this->getMap($id); } //create select object $select = $this->getGateway()->select(); $select->where('id = ?', $id); //fetch the data $row = $this->getGateway()->fetchRow($select); //create the entity object $entity = $this->createEntity($row); //put it in the map, just in case we need it again $this->setMap($row->id, $entity); // return the entity return $entity; }
I have seen Entities and Mappers built in many different ways, find the method that you like and have fun.
A lot of code has been left out of this demonstration as it doesn't really apply to the question. If you need to see the complete code see it at GitHub.