Str*_*yer 4 php zend-framework2
根据Zend用户指南,我的ZF2骨架应用程序工作正常.但现在我正在试图扩展应用程序,以便专辑的艺术家不再是字符串,而是我的数据库中艺术家表的外键.
我已经创建了所有必要的模型,控制器,视图来创建,编辑和查看艺术家,这也很好.但是如何将两者结合起来以便我的专辑列表显示艺术家的名字?
我是否按照此处的建议使用保湿策略?如果是这样,我该如何实现它?Zend\Stdlib\Hydrator\Strategy手册没有告诉我在哪里注册保湿剂策略.是的,有一个简短的实施代码:
$foo = new Foo();
$foo->setFoo("bar");
$foo->setBar("foo");
$hydrator = new ClassMethods();
$hydrator->addStrategy("foo", new Rot13Strategy());
Run Code Online (Sandbox Code Playgroud)
但这又往哪里了?在我的AlbumController中?为什么每个人都说水化器"主要用于表格"?
或者不是我想要的保湿剂?我在寻求解决方案时不断遇到的另一件事是依赖注入.我再次找到了这种教程,但是在使用A,B和C类并且没有告诉我所有这些代码片段在哪里时,它对于理解这个概念并没有多大帮助.
我想我想做的事情非常普遍,而且我错开了,我找不到任何真实世界的教程.经过几个小时的研究,我确信我已经非常接近突破 - 但我再也看不到了它需要推动.谢谢 :-)
当您需要将数据输入或输出对象/实体时,可以使用水合器,这可以在使用表单时,也可以在从存储中保存或加载实体时使用.
我不会使用Hydrator用相关对象填充对象(例如,为您的相册添加antist对象).我会把这个留给你的服务/地图制作者.
这是我如何做的一个例子:
Album.php
<?php
class Album
{
// .. properties / getters/setters etc ..
public function setArtist(ArtistInterface $artist)
{
$this->artist = $artist;
}
public function getArtist()
{
return $this->artist;
}
}
Run Code Online (Sandbox Code Playgroud)
AlbumHydrator.php
这可能会有所不同,您可以使用getters/setter或属性,看看基础水合器来决定您想要的路线.
您的Hydrator将获取Assembled对象,并返回显示表单所需的数据,或保存为持久性等.
<?php
class AlbumHydrator // extends Zend\Stdlib\Hydrator\ClassMethods
{
public function extract($object)
{
return array(
'artist_id' => $object->getArtist()->getId(),
'albumn_name' => $object->getAlbumName()
)
}
// .. etc
}
Run Code Online (Sandbox Code Playgroud)
AlbumService.php
<?php
use Zend\ServiceManager\ServiceManagerAwareInterface;
use Zend\ServiceManager\ServiceManager;
class AlbumService implements ServiceManagerAwareInterface
{
/**
* Get an album, we'll also load any related objects here
*
* @param int
*/
public function find($id)
{
$album = $this->_getAlbumMapper()->find($id);
$artist = $this->_getArtistMapper()->findByAlbum($id);
$album->setArtist($artist);
return $album;
}
/**
* Get the Mapper
*
* @return Application\Mappers\AlbumMapper
*/
protected function _getAlbumMapper()
{
return $this->getServiceManager()
->get('AlbumMapper')
;
}
// ..
}
Run Code Online (Sandbox Code Playgroud)
您可以在Service Manager配置中设置服务,如下所示:
'AlbumService' => function($sm) {
$mapper = $sm->get('AlbumMapper');
$service = new Application\Service\AlbumService();
$service->setAlbumMapper($mapper);
return $service;
},
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用您的服务来创建所需的对象图.您可以为每个实体分别使用映射器,服务可以使用映射器生成所需的对象.
您通常会为每个实体配备一个Hydrator,并且映射器会使用这些实体为您填充对象.这将取决于您的实现,您可能正在使用TableGateway或其他东西而不是映射器,这仍然可以正常工作.
现在可以在控制器内部访问对象的示例
SomeController.php
public function albumAction()
{
$id = (int) $this->params()->fromRoute('id', FALSE);
if( ! $id) {
// do something with errors etc ..
return $this->redirect()->toRoute('default_route', array(
'controller' => 'index',
'action' => 'index'
));
}
$request = $this->getRequest();
$album = $this->getServiceLocator()->get('AlbumService')->find($id);
$artistName = $album->getArtist()->getName();
return new ViewMdoel(
'album' => $ablum,
'artistName' => $artistName
);
}
Run Code Online (Sandbox Code Playgroud)
在使用集合时填充对象图表有点棘手,但我倾向于使用延迟加载和虚拟代理进行这种设置,这将基本上推迟加载您需要的对象直到需要它们,检查这些:
http://phpmaster.com/intro-to-virtual-proxies-1/ http://phpmaster.com/intro-to-virtual-proxies-2/