Zend framework2 zend framework 2了解exchangeArray方法
从: 我们的Album实体对象是一个简单的PHP类。为了使用Zend\Db的TableGateway类,我们需要实现exchangeArray()方法。此方法只是将传入数组中的数据复制到实体的属性中 好的,我们需要。但是这个函数的用途是什么 我的意思是,我已经理解了这个函数的功能,但是我不理解它为什么会这样做 真的有必要声明所有变量吗 假设我有一个包含20列的表,我想将它们全部选中。 然后我应该声明20个命名变量 如果我想区分公共(打印)变量和私有(内部)变量,这是有意义的Zend framework2 zend framework 2了解exchangeArray方法,zend-framework2,tablegateway,Zend Framework2,Tablegateway,从: 我们的Album实体对象是一个简单的PHP类。为了使用Zend\Db的TableGateway类,我们需要实现exchangeArray()方法。此方法只是将传入数组中的数据复制到实体的属性中 好的,我们需要。但是这个函数的用途是什么 我的意思是,我已经理解了这个函数的功能,但是我不理解它为什么会这样做 真的有必要声明所有变量吗 假设我有一个包含20列的表,我想将它们全部选中。 然后我应该声明20个命名变量 如果我想区分公共(打印)变量和私有(内部)变量,这是有意义的 还有其他原因吗?这不
还有其他原因吗?这不仅仅是定义类成员的问题。它更多地是关于面向对象的好处,如封装、继承等。 让我们假设您的实体如下所示:
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框架提供了更复杂的水合作用方式。如果数据库表中的releaseDate列的类型为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
接口有时非常神奇)、类型暗示、封装、多态性等所有oo功能
最后但并非最不重要的一点:IDE支持。如果您的实体对象是严格的php文档注释对象,那么您的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;
}
}
本例假设表网关是通过相应的工厂创建的。您的答案很好,但我有点困惑:您的话大体正确吗?我的意思是,据我所知,为了应用您的示例,我需要在给定的示例使用默认的ArraySerializable时,使用ClassMethods或来初始化TableGateway。我说的对吗?你在开场白中给出的例子是使用ArraySerializable接口。你完全正确。您必须使用类方法实例化表网关。我将编辑我的答案,并给出一个如何实例化表网关的示例。
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;
}
}