我正在尝试使用Apigility中的Doctrine将一个实体链接到一个实体。关系是1幻灯片有很多子弹点。所以我希望返回json显示每个幻灯片及其所有相关的嵌套项目符号。但正如你从下面的输出中看到的那样,子弹总是返回空:
{
"_links": {
"self": {
"href": "http://0.0.0.0:8888/slide"
}
},
"_embedded": {
"slide": [
{
"id": "2",
"title": "Title",
"previous": "Previous",
"next": "Next",
"bullets": {},
"_links": {
"self": {
"href": "http://0.0.0.0:8888/slide/2"
}
}
},
{
"id": "3",
"title": "Title",
"previous": "Previous",
"next": "Next",
"bullets": {},
"_links": {
"self": {
"href": "http://0.0.0.0:8888/slide/3"
}
}
},
{
"id": "4",
"title": "Title",
"previous": "Previous",
"next": "Next",
"bullets": {},
"_links": {
"self": {
"href": "http://0.0.0.0:8888/slide/4"
}
}
},
{
"id": "5",
"title": "Title",
"previous": "Previous",
"next": "Next",
"bullets": {},
"_links": {
"self": {
"href": "http://0.0.0.0:8888/slide/5"
}
}
},
{
"id": "6",
"title": "Title",
"previous": "Previous",
"next": "Next",
"bullets": {},
"_links": {
"self": {
"href": "http://0.0.0.0:8888/slide/6"
}
}
}
]
},
"total_items": 5
}
子弹和幻灯片的幻灯片实体
namespace demo\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Sentence
*
* @ORM\Table(name="slide")
* @ORM\Entity(repositoryClass="demo\Repository\SlideRepository")
*/
class Slide
{
/**
* @var integer
*
* @ORM\Column(name="id", type="bigint", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var string
*
* @ORM\Column(type="string", length=45, nullable=true)
*/
private $title;
/**
* @var string
*
* @ORM\Column(type="string", length=45, nullable=true)
*/
private $previous;
/**
* @var string
*
* @ORM\Column(type="string", length=45, nullable=true)
*/
private $next;
/**
* @ORM\OneToMany(targetEntity="Bullet", mappedBy="slide")
*/
private $bullets;
public function __construct()
{
$this->bullets = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* @param string $title
*/
public function setTitle($title)
{
$this->title = $title;
}
/**
* @return string
*/
public function getTitle()
{
return $this->title;
}
/**
* @param string $previous
*/
public function setPrevious($previous)
{
$this->previous = $previous;
}
/**
* @return string
*/
public function getPrevious()
{
return $this->previous;
}
/**
* @param int $id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* @param string $next
*/
public function setNext($next)
{
$this->next = $next;
}
/**
* @return string
*/
public function getNext()
{
return $this->next;
}
/**
* Add bullets
*
* @param Bullet $bullets
* @return Slide
*/
public function addBullet(Bullet $bullets)
{
$this->bullets[] = $bullets;
return $this;
}
/**
* Remove bullets
*
* @param Bullet $bullets
*/
public function removeBullet(Bullet $bullets)
{
$this->bullets->removeElement($bullets);
}
/**
* Get bullets
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getBullets()
{
return $this->bullets;
}
}
namespace demo\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Sentence
*
* @ORM\Table(name="bullets")
* @ORM\Entity(repositoryClass="demo\Repository\BulletsRepository")
*/
class Bullet
{
/**
* @var integer
*
* @ORM\Column(name="id", type="bigint", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="bullet", type="string", length=45, nullable=true)
*/
private $bullet;
/**
* @ORM\ManyToOne(targetEntity="Slide", inversedBy="bullets")
* @ORM\JoinColumn(name="slide_id", referencedColumnName="id")
*/
protected $slide;
public function __construct()
{
var_dump('TEST!!');
exit();
}
/**
* @param int $id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* @param string $bullet
*/
public function setBullet($bullet)
{
$this->bullet = $bullet;
}
/**
* @return string
*/
public function getBullet()
{
return $this->bullet;
}
/**
* @return string
*/
public function getSlide()
{
return $this->slide;
}
/**
* @param string $slide
*/
public function setSlide(Slide $slide = null)
{
$this->slide = $slide;
return $this;
}
}
数据库条目
+----+-------+----------+------+
| id | title | previous | next |
+----+-------+----------+------+
| 2 | Title | Previous | Next |
| 3 | Title | Previous | Next |
| 4 | Title | Previous | Next |
| 5 | Title | Previous | Next |
| 6 | Title | Previous | Next |
+----+-------+----------+------+
+----+----------+---------------+
| id | slide_id | bullet |
+----+----------+---------------+
| 1 | 2 | Test Bullet |
| 2 | 3 | Test Bullet |
| 3 | 4 | Array |
| 4 | 5 | test Bullet 2 |
| 5 | 6 | test Bullet 2 |
+----+----------+---------------+
感谢任何帮助。
我还添加了application.config.php:
/**
* Configuration file generated by ZF Apigility Admin
*
* The previous config file has been stored in application.config.old
*/
return array(
'modules' => array(
'ZF\\DevelopmentMode',
'ZF\\Apigility',
'ZF\\Apigility\\Provider',
'ZF\\Apigility\\Documentation',
'AssetManager',
'ZF\\ApiProblem',
'ZF\\Configuration',
'ZF\\MvcAuth',
'ZF\\OAuth2',
'ZF\\Hal',
'ZF\\ContentNegotiation',
'ZF\\ContentValidation',
'ZF\\Rest',
'ZF\\Rpc',
'ZF\\Versioning',
'apiexample',
'DoctrineModule',
'DoctrineORMModule'
),
'module_listener_options' => array(
'module_paths' => array(
'./module',
'./vendor'
),
'config_glob_paths' => array(
'config/autoload/{,*.}{global,local}.php'
)
)
);
模块/ apiexample /配置/ module.config.php
return array(
'controllers' => array(
'factories' => array(
'apiexample\\V1\\Rpc\\Ping\\Controller' => 'apiexample\\V1\\Rpc\\Ping\\PingControllerFactory',
),
),
'router' => array(
'routes' => array(
'apiexample.rpc.ping' => array(
'type' => 'Segment',
'options' => array(
'route' => '/ping',
'defaults' => array(
'controller' => 'apiexample\\V1\\Rpc\\Ping\\Controller',
'action' => 'ping',
),
),
),
'apiexample.rest.user' => array(
'type' => 'Segment',
'options' => array(
'route' => '/user[/:user_id]',
'defaults' => array(
'controller' => 'apiexample\\V1\\Rest\\User\\Controller',
),
),
),
),
),
'zf-versioning' => array(
'uri' => array(
0 => 'apiexample.rpc.ping',
1 => 'apiexample.rest.user',
),
),
'zf-rpc' => array(
'apiexample\\V1\\Rpc\\Ping\\Controller' => array(
'service_name' => 'Ping',
'http_methods' => array(
0 => 'GET',
),
'route_name' => 'apiexample.rpc.ping',
),
),
'zf-content-negotiation' => array(
'controllers' => array(
'apiexample\\V1\\Rpc\\Ping\\Controller' => 'Json',
'apiexample\\V1\\Rest\\User\\Controller' => 'HalJson',
),
'accept_whitelist' => array(
'apiexample\\V1\\Rpc\\Ping\\Controller' => array(
0 => 'application/vnd.apiexample.v1+json',
1 => 'application/json',
2 => 'application/*+json',
),
'apiexample\\V1\\Rest\\User\\Controller' => array(
0 => 'application/vnd.apiexample.v1+json',
1 => 'application/hal+json',
2 => 'application/json',
),
),
'content_type_whitelist' => array(
'apiexample\\V1\\Rpc\\Ping\\Controller' => array(
0 => 'application/vnd.apiexample.v1+json',
1 => 'application/json',
),
'apiexample\\V1\\Rest\\User\\Controller' => array(
0 => 'application/vnd.apiexample.v1+json',
1 => 'application/json',
),
),
),
'zf-content-validation' => array(
'apiexample\\V1\\Rpc\\Ping\\Controller' => array(
'input_filter' => 'apiexample\\V1\\Rpc\\Ping\\Validator',
),
),
'input_filter_specs' => array(
'apiexample\\V1\\Rpc\\Ping\\Validator' => array(
0 => array(
'name' => 'ack',
'required' => true,
'filters' => array(),
'validators' => array(),
'description' => 'Acknowledge the request with a timestamp.',
),
),
),
'service_manager' => array(
'factories' => array(
'apiexample\\V1\\Rest\\User\\UserResource' => 'apiexample\\V1\\Rest\\User\\UserResourceFactory',
),
),
'zf-rest' => array(
'apiexample\\V1\\Rest\\User\\Controller' => array(
'listener' => 'apiexample\\V1\\Rest\\User\\UserResource',
'route_name' => 'apiexample.rest.user',
'route_identifier_name' => 'user_id',
'collection_name' => 'user',
'entity_http_methods' => array(
0 => 'GET',
1 => 'PATCH',
2 => 'PUT',
3 => 'DELETE',
4 => 'POST',
),
'collection_http_methods' => array(
0 => 'GET',
1 => 'POST',
),
'collection_query_whitelist' => array(),
'page_size' => '2',
'page_size_param' => null,
'entity_class' => 'apiexample\\Entity\\User',
'collection_class' => 'apiexample\\V1\\Rest\\User\\UserCollection',
'service_name' => 'user',
),
),
'zf-hal' => array(
'metadata_map' => array(
'apiexample\\V1\\Rest\\User\\UserEntity' => array(
'entity_identifier_name' => 'id',
'route_name' => 'apiexample.rest.user',
'route_identifier_name' => 'user_id',
'hydrator' => 'Zend\\Stdlib\\Hydrator\\ObjectProperty',
),
'apiexample\\V1\\Rest\\User\\UserCollection' => array(
'entity_identifier_name' => 'id',
'route_name' => 'apiexample.rest.user',
'route_identifier_name' => 'user_id',
'is_collection' => true,
),
'apiexample\\Entity\\User' => array(
'entity_identifier_name' => 'id',
'route_name' => 'apiexample.rest.user',
'route_identifier_name' => 'user_id',
'hydrator' => 'apiexample\\Hydrator\\UserHydrator',
),
),
),
'doctrine' => array(
'driver' => array(
'lanekeep_driver' => array(
'class' => 'Doctrine\\ORM\\Mapping\\Driver\\AnnotationDriver',
'cache' => 'array',
'paths' => array(
0 => __DIR__ . '/../src/apiexample/Entity',
),
),
'orm_default' => array(
'drivers' => array(
'apiexample\\Entity' => 'lanekeep_driver',
),
),
),
),
'view_manager' => array(
'display_not_found_reason' => true,
'display_exceptions' => true,
'doctype' => 'HTML5',
'not_found_template' => 'error/404',
'exception_template' => 'error/index',
'template_map' => array(
'layout/layout' => __DIR__ . '/../view/layout/layout.phtml',
'error/404' => __DIR__ . '/../view/error/404.phtml',
'error/index' => __DIR__ . '/../view/error/index.phtml',
),
'template_path_stack' => array(
0 => __DIR__ . '/../view',
),
),
);
答案 0 :(得分:0)
您的getBullets方法返回ArrayCollection
实例,Hal渲染器不知道如何渲染(序列化)此对象,这就是您看到{}
(json格式的对象)的原因。您应该添加一个自定义水合器/提取器,为您的bullits
返回一些可渲染值。例如,您可以将其设置为Hal\Collection
实例。
在您的保湿器/提取器中,您可以执行以下操作:
<?php
namespace Application\Extractor;
use Zend\Stdlib\Extractor\ExtractionInterface;
use ZF\Hal;
class SlideExtractor implements ExtractionInterface
public function extract($object){
$data = [];
$route = //...your route to bullits
$routeParams = //...route params if needed
$bullits = $object->getBullits()->toArray();
$collection = new Hal\Collection($bullits, $route, $routeParams);
$data['bullits'] = $collection;
//...other extractions from your slide ( $object )
return $data;
}
}