我正在根据Apigility开发Zend Framework 2驱动的应用程序。
目前,我将数据库中检索到的数据直接发送到客户端:请求进入,MyResource#fetch(...)
或MyResource#fetchAll(...)
被触发,并在{{1}上调用适当的方法} class,调用MyService
以使用MyMapper
等方法来淘汰数据。
现在我想在发送响应之前处理数据。我怎么能这样做?
Apigility ZF HAL documentation显示,如何检索它之间的实体数据已被检索并发送到客户端。好吧,我试过这个。它的丑陋和许多代码都是为了这样的任务。并且......它不起作用。但是我想在这里发帖,我的出席了:
findFooByBar(...)
答案 0 :(得分:0)
我认为使用renderEntity
和renderCollection
事件不是添加此类资源特定逻辑的正确位置。它更适合更一般的更改或偶然的定制。
您可以将此逻辑添加到资源侦听器。因此,在fetch
课程的fetchAll
和MyResource
方法中,您可以添加当前在这些onRenderEntity
和onRenderCollection
方法中添加的自定义代码。
这样的事情:
class MyResource extends AbstractResourceListener
{
/**
* Your image service dependency
*/
protected $imageService;
/* ... */
public function fetch($id)
{
$project = $this->projectMapper->fetch($id);
$imageCollection = $this->imageService->getImagesForProject($project);
$project->setImages($imageCollection);
return $project;
}
/* ... */
public function fetchAll($params = array())
{
$projects = $this->projectMapper->fetchAll();
foreach ($projects as $key => $project) {
$imageCollection = $this->imageService->getImagesForProject($project);
$project->setImages($imageCollection);
}
return $projects;
}
/* ... */
}
答案 1 :(得分:0)
一种可能的解决方案是处理Hydrator中的数据。因此,我们编写一个自定义的Hydrator类,并使用嵌套对象和列表来丰富项目。它看起来像这样:
<强> Portfolio\V2\Rest\Project\ProjectHydrator
强>
...
class ProjectHydrator extends ClassMethods {
/**
* @var ImageService
*/
protected $imageService;
...
/*
* Doesn't need to be implemented:
* the ClassMethods#hydrate(...) handle the $data already as wished.
*/
/*
public function hydrate(array $data, $object) {
$object = parent::hydrate($data, $object);
if ($object->getId() !== null) {
$images = $this->imageService->getImagesForProject($object->getId());
$object->setImages($images);
}
return $object;
}
*/
/**
* @see \Zend\Stdlib\Hydrator\ClassMethods::extract()
*/
public function extract($object) {
$array = parent::extract($object);
if ($array['id'] !== null) {
$images = $this->imageService->getImagesForProject($array['id']);
$array['images'] = $images;
}
return $array;
}
}
这不是一个好的解决方案,因为那时模型/数据检索逻辑的一部分被移动到水化器。但它的确有效。 Here显示了此方法的实现,here是对GitHub上此主题的讨论。
答案 2 :(得分:0)
如果您正在使用ClassMethods
Hydrator并且Collection
扩展\Zend\Paginator\Paginator
一个不错的解决方案而不会失去Collection的一致性并且不更改任何人的代码就是覆盖 getCurrentItems() 方法。
public class MyResourceCollection // most likely extends Paginator
{
public function getCurrentItems()
{
// getting the original items
$items = parent::getCurrentItems();
// as we work with objects $item will be an object
// when working with objects we use references to them not clones of objects
// so changes to $item are also present in the collection
foreach ($collection as $item) {
$oldSomething = $item->getSomething();
$item->setSomething('['.$oldSomething.']');
}
// $items are now changed, return them
return $items;
}
}
我已将密钥something
命名为不与其他地方的getValue
方法混淆。
这使something
值看起来像[something]
。