这不仅仅是定义类成员。它更多的是关于面向对象的好处,如封装、继承等。假设您的实体如下所示:
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
策略转换为对象。
这些好处不仅仅是区分公共变量、受保护变量和私有变量。实体只接受和提供变量,这些变量应该在您的实体中。你可以使用所有 oo 的东西,比如继承(实现\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;
}
}
此示例假设 Table Gateway 是通过相应的工厂创建的。