我有一个ZF2应用程序,它有用于posts的数据库表和具有多对多关系的散列标记。表格定义为:
CREATE TABLE `hash_tag` (
`id` int(11) NOT NULL,
`tag` varchar(255) NOT NULL
)
CREATE TABLE `post` (
`id` int(11) NOT NULL,
`text` varchar(255)NOT NULL,
`addedOn` datetime NOT NULL
)
CREATE TABLE `post_hashtag` (
`post_id` int(11) NOT NULL,
`hashtag_id` int(11) NOT NULL
)
我还按照ZF2文档的用户指南中解释的模式创建了模型。HashTag模型如下:
namespace Application'Model;
use Application'Model'Post;
class HashTag
{
public $id;
public $tag;
protected $posts = array();
public function exchangeArray($data)
{
$this->id = empty($data['id']) ? null : $data['id'];
$this->tag = empty($data['tag']) ? null : $data['tag'];
}
public function getPosts()
{
return $this->posts;
}
public function addPost(Post $post)
{
$this->posts[] = $post;
return $this;
}
}
虽然指南对如何处理基本数据库模型给出了很好的解释,但我希望做一些更复杂的事情。
基本上,当我检索哈希标签记录时,我还想检索它们相关的帖子,并以某种方式将它们存储在每个单独的HashTag对象中。执行普通的联接查询会为每个哈希标记及其附带的post生成一个新记录,这并没有真正的帮助。文档中也没有详细介绍如何做到这一点,我在谷歌上也找不到任何关于它的像样的例子。
我过去使用过条令2,通常会继续这样做。然而,我正在为一份新工作做准备,我的新雇主使用Zend''Db。我这样做基本上是为了练习在不使用Doctrine的情况下处理数据库操作。
遇到了同样的问题,我仍然不知道我的方法是否是一个好方法,但它有效。我为每个需要处理m-m关系的实体创建了一个"映射器"(Generic names ftw)。这里有一些例子:
class AddresseeMapper {
private $resultSet;
private $addresseeArray = array();
private $addreseeObjectsArray = array();
public function __construct($resultSet)
{
$this->resultSet = $resultSet;
}
public function init()
{
foreach($this->resultSet as $key => $result)
{
$addressee = array();
if(!empty($this->addresseeArray[$result['AddresseeID']]))
{
$addressee = $this->addresseeArray[$result['AddresseeID']];
}
else
{
$addressee['id'] = $result['AddresseeID'];
$addressee['documentID'] = $result['AddresseeDocumentID'];
$addressee['communicationID'] = $result['AddresseeCommunicationID'];
$addressee['addressID'] = (!empty($result['AddresseeAddressID'])) ? $result['AddresseeAddressID'] : null;
$addressee['salutation'] = (!empty($result['AddresseeSalutation'])) ? $result['AddresseeSalutation'] : null;
$addressee['tempEmail'] = (!empty($result['AddresseeTempEmail'])) ? $result['AddresseeTempEmail'] : null;
if((!empty($result['ContactID'])) && $result['ContactID'])
{
$addressee['Contact'] = $this->setContact($this->resultSet);
}
if((!empty($result['MailingListID'])) && $result['MailingListID'])
{
$addressee['MailingList'] = $this->exchangeMailingList($result);
}
}
$this->addresseeArray[$result['AddresseeID']] = $addressee;
}
}
private function setContact($resultSet)
{
$contactMapper = new ContactMapper($resultSet);
$contactMapper->init();
$contactMapper->serilizeObjects();
return $contactMapper->getContact();
}
private function exchangeMailingList($result)
{
$mailingList = new MailingList();
$mailingList->exchangeArray($result);
return $mailingList;
}
public function serilizeObjects()
{
foreach($this->addresseeArray as $addresseeArray)
{
$addressee = new Addressee();
$addressee = $this->loop($addresseeArray, $addressee);
$this->addreseeObjectsArray[] = $addressee;
}
}
private function loop($array, $object)
{
foreach($array as $key => $value)
{
if(is_array($value) && is_object($object->$key))
{
$object->$key = $this->deepLoop($value, $object->$key);
}
elseif(is_array($object->$key))
{
foreach($value as $key2 => $value2)
{
array_push($object->$key, $value2);
}
}
else
{
$object->$key = $value;
}
}
return $object;
}
private function deepLoop($array, $object)
{
foreach($array as $key => $value)
{
//var_dump($key);
//var_dump($value);
$object->$key = $value;
}
return $object;
}
public function getAddressees()
{
return $this->addreseeObjectsArray;
}
public function getAddressee()
{
foreach($this->addreseeObjectsArray as $addressee)
{
return $addressee;
}
return false;
}
}