0

我有一个用外键表示用户模型的类,它是图片的 id。

class Model_User extends Model_AbstractEntity
{
    protected $u_id;
    protected $u_email;
    protected $u_firstname;
    protected $u_lastname;
    protected $u_password;
    protected $u_salt;
    protected $u_created_at;
    protected $u_updated_at;
    protected $u_fb;
    protected $u_status;
    protected $u_r_id;
    protected $u_p_id;
}

负责图片模型的类如下所示:

class Model_Picture extends Model_AbstractEntity
{
    protected $p_id;
    protected $p_created_at;
    protected $p_updated_at;
    protected $p_caption;
    protected $p_name;
    protected $p_basePath;
    protected $p_available;
    protected $p_u_id;
}

这只是从数据库获取数据的模型部分。外键是 u_p_id,图片中的键是 p_id 我的问题是,当 Zend db 表执行 select() 时,它会返回带有外键的数据,但是我怎么知道返回数据的哪一部分是图片部分来设置正确的图片模型。 ...如何以正确的方式做到这一点不做 2 个查询,一个为用户,第二个为图片,以创建 2 个关联对象。我现在谈论的是一对一的关系,但可能是一对多的关系。

4

1 回答 1

1

通常,您的实体模型不会以无效的形式存在,它们将与某种类型的数据映射器模型一起存在。Mapper 通常负责从任何方便的来源收集数据,然后构建实体模型。

例如,我有一个包含专辑实体的音乐收藏:

<?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;
    }
}

在映射器中,我将构建实体模型,例如:

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

要在映射器方法中使用此方法,可能如下所示:

 //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;
    }

我见过以许多不同方式构建的实体和映射器,找到你喜欢的方法并玩得开心。

此演示中省略了很多代码,因为它并不真正适用于该问题。如果您需要查看完整代码,请在GitHub 上查看。

于 2012-11-08T09:08:01.110 回答