namespace Album\Model;
class Album
{
public $id;
public $artist;
public $title;
public function exchangeArray($data)
{
$this->id = (!empty($data['id'])) ? $data['id'] : null;
$this->artist = (!empty($data['artist'])) ? $data['artist'] : null;
$this->title = (!empty($data['title'])) ? $data['title'] : null;
}
}
我们的Album实体对象是一个简单的PHP类。为了使用Zend \ Db的TableGateway类,我们需要实现exchangeArray()方法。此方法只是将传入数组中的数据复制到实体的属性
好的,我们需要。但是这个功能的目的是什么呢?
我的意思是,我已经理解了 这个函数的作用,但我无法理解为什么它以这种方式做事。
是否真的有必要声明所有变量?
假设我有一个包含20列的表格,我想全部选择它们。 然后我应该声明20个命名变量。
如果我想区分公共(打印)和私人(内部)变量,这是有道理的。
还有其他原因吗?
答案 0 :(得分:1)
它不仅仅是定义班级成员。它更多地涉及面向对象的好处,如封装,继承等。 让我们假设您的实体如下所示:
declare(strict_types=1);
namespace Application\Entity;
class Album
{
protected $id;
protected $artist;
protected $title;
public function getId() : int
{
return $this->id;
}
public function setId(int $id) : Album
{
$this->id = $id;
return $this;
}
public function getArtist() : string
{
return $this->artist;
}
public function setArtist(string $artist) : Album
{
$this->artist = $artist;
return $this;
}
public function getTitle() : string
{
return $this->title;
}
public function setTitle(string $title) : Album
{
$this->title = $title;
return $this;
}
}
使用实体的第一个好处:没有可能进行拼写错误。 $data['atrist'] = 'Marcel'
在大多数情况下都适用。 $album->setAtrist('Marcel')
会抛出错误。
第二个优点是类型提示。特别是当您使用PHP7时,您可以使用类型提示的优势。 $album->setId('1')
会抛出错误,因为此方法需要一个整数值。
第三个优势是可以向您的实体添加一些额外的代码。如果我们需要发布日期并且没有发布日期怎么办?您可以在实体中验证事物。
protected $releaseDate;
public function getReleaseDate() : \DateTime
{
if ($this->releaseData == null) {
throw new \Exception('no release date given. evacuate!');
}
return $this->releaseDate;
}
另一个优点是zend框架中的水合作用。尽管exchangeArray
方法是一种简单的水合作用,但zend框架提供了更复杂的水合方式。例如,如果数据库表中的发布日期列是DATE类型,并且您希望实体中的releaseDate成员是表示此日期的\DateTime
对象吗?
// data from your database
$data = [
'id' => 1,
'artist' => 'the outside agency',
'title' => 'scenocide 202',
'releaseDate' => '2010-06-30',
];
// hydration of your entity with zend 's own hydrator classes
$album = (new ClassMethods())
->addStrategy('releaseDate', new DateTimeStrategy('Y-m-d'))
->hydrate($data, new Album());
$releaseDate = $album->getReleaseDate()->format('d.m.Y');
正如您所看到的,发布日期是一个简单的字符串。在为您的实体保湿时,发布日期将通过水化器策略转换为\DateTime
对象。
这些好处不仅仅是区分公共变量,受保护变量和私有变量。实体只接受并提供应该在您的实体中的变量。你可以使用所有的东西,比如继承(有时候实现\JsonSerializable
接口很神奇),类型提示,封装,多态等等......
最后但并非最不重要:IDE支持。如果你的实体对象是严格的php doc注释,你的IDE知道你可以用你的实体做什么。减少你的工作量。 ;)
编辑:具有保湿结果集的表网关实例化
要在表网关中使用上述带有水合器的实体对象的优点,您必须实例化表网关,如下例所示。
class AlbumTableGateway extends TableGateway
{
public function __construct(Adapter $adapter)
{
$resultset = new HydratingResultset(
(new ClassMethods())->addStrategy('releaseDate', new DateTimeFormatter()),
new AlbumEntity()
);
parent::__construct('album_table', $adapter, null, $resultset);
}
public function fetchById($id)
{
$select = $this->getSql()->select();
$select->columns([
'id',
'artist',
'title',
'releaseDate',
]);
$select->where->equalTo('id', $id);
$result = $this->selectWith($select);
// get the found resultset with $result->current()->getId();
return $result;
}
}
此示例假定表网关是通过相应的工厂创建的。