我有一个Zend Framework 3应用程序。我将ViewJsonStrategy添加到module.config.php。但我想返回一个JSON对象,它们的关系对象在数组中是ONE TO MANY:
在我的控制器上
public function getdirectoriojsonAction(){
$idraiz = $this->cfgGral->getIdDirectorioRaiz();
if ($idraiz <= 0) {
return $this->redirect()->toRoute('configuracion', ['action' => 'index']);
} else {
if ($this->params()->fromRoute('id') > 0) {
$idraiz = $this->params()->fromRoute('id');
}
$directorio = $this->em->find($this->rutaEntityDirectorio, $idraiz);
if ($directorio->getEstado() != 0) {
$directorio = $directorio->getPadre();
$directorio->getDirectoriosHijos();
$directorio->getArchivosHijos();
}
}
$hydrator = new Reflection;
return new JsonModel($hydrator->extract($directorio));
}
实体总监
<?php
namespace Directorios\Entity;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Zend\Form\Annotation as ZendAnnotation;
use Directorios\Model\ArchivoInterface;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @ORM\Entity
* @ORM\Table (name="directorio")
*
*/
class Directorio
{
/**
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
* @ORM\Column(type="integer")
* @ZendAnnotation\Exclude()
* @var int|null
*/
private $id;
/**
* @ORM\Column(type="string")
* @var string
* @Required
* @ZendAnnotation\Filter({"name":"StringTrim"})
* @ZendAnnotation\Validator({"name":"StringLength", "options":{"min":1, "max":60}})
* @ZendAnnotation\Validator({"name":"Regex", "options":{"pattern":"/^[a-zA-Z][a-zA-Z0-9_-]{0,24}$/"}})
* @ZendAnnotation\Attributes({"type":"text"})
* @ZendAnnotation\Options({"label":"Nombre:"})
*/
private $nombre;
/**
* @ORM\ManyToOne(targetEntity="Directorios\Entity\Directorio", inversedBy="directoriosHijos")
* @ORM\JoinColumn(name="padre", referencedColumnName="id")
*/
private $padre;
/**
* @ORM\OneToMany(targetEntity="Directorios\Entity\Directorio", mappedBy="padre",cascade={"persist", "remove"})
*/
private $directoriosHijos;
/**
* @ORM\OneToMany(targetEntity="Directorios\Entity\Archivo", mappedBy="padre", cascade={"persist", "remove"})
*/
private $archivosHijos;
/**
* @ORM\Column(type="datetime")
* @var \DateTime
*/
private $fechaCreacion;
/**
* @ORM\Column(type="datetime")
* @var \DateTime
*/
private $fechaModificacion;
/**
* @ORM\Column(name="ruta_real")
* @ORM\Column(type="text")
*/
private $ruta_real;
/**
*
* @ORM\Column(type="integer")
*
*/
private $estado=0;
/**
*
* @ORM\Column(type="integer")
*
*/
private $tipo;
//....... methods
public function __construct(){
$this->archivosHijos=new ArrayCollection();
$this->directoriosHijos=new ArrayCollection();
}
}
JSON回复:
id 2
nombre "Nuevo directorio"
padre Object <- Returns Objects
directoriosHijos Object <- Returns Objects
archivosHijos Object <- Returns Objects
fechaCreacion
date "2017-09-09 21:23:20.000000"
timezone_type 3
timezone "Europe/Berlin"
fechaModificacion
date "2017-09-09 21:23:20.000000"
timezone_type 3
timezone "Europe/Berlin"
ruta_real "D:\\testDirectorioRaiz"
estado 0
tipo 0
关联的对象就像Object而不是Array()。 我怎么能这样的关系对象到达像Json Array()?
答案 0 :(得分:1)
反射水合器本身不允许嵌套水合/提取。 但是Hydrator Aggregates会这样做,但你必须投入更多的工作,然后只是简单地实例化它。如果你选择这条路线,我会投入更多的时间并将其注入控制器以保持高可测试性
还要考虑使用doctrine / doctrine-module composer包提供的Doctrine Hydrator。该项目还有关于hydration
的简短文档答案 1 :(得分:0)
谢谢jeger,我正在寻找一个最简单的解决方案,但我发现这不是针对这种情况。刚才我开始调查学说水合物,但是现在我用一个质朴的递归XD修复。我让这里的代码吼叫,也许会有所帮助。
在我的控制器中......
// Method with response JSON
public function getdirectoriojsonAction(){
$idraiz = $this->cfgGral->getIdDirectorioRaiz();
if ($idraiz <= 0) {
return $this->redirect()->toRoute('configuracion', ['action' => 'index']);
} else {
if ($this->params()->fromRoute('id') > 0) {
$idraiz = $this->params()->fromRoute('id');
}
$directorio = $this->em->find($this->rutaEntityDirectorio,$idraiz);
if ($directorio->getEstado() == 0) {
$hydrator = new Reflection();
$dir = $hydrator->extract($directorio);
$dir = $this->getArrayHijosRec($dir, $hydrator);
}else{
return $this->redirect()->toRoute('directorios',['action'=>'error','id'=>2]);
}
}
return new JsonModel($dir);
}
// recursive method ... is not the best practice but works ...
private function getArrayHijosRec($directorioArray, Reflection $hydrator){
$directoriosHijos=$directorioArray['directoriosHijos'];
$archivosHijos=$directorioArray['archivosHijos'];
$padre=$directorioArray['padre'];
$directorioArray['directoriosHijos']=[];
$directorioArray['archivosHijos']=[];
$directorioArray['padre']=[];
$padre=(is_object($padre))?$hydrator->extract($padre):[];
$directorioArray['padre']=$padre;
foreach ($archivosHijos as $archHijo){
$archHijo=$hydrator->extract($archHijo);
$archHijo['padre']=$padre;
array_push($directorioArray['archivosHijos'],$archHijo);
}
foreach ($directoriosHijos as $dirHijo) {
$dirHijo=($hydrator->extract($dirHijo))
array_push($directorioArray['directoriosHijos'],($this->getArrayHijosRec($dirHijo,$hydrator)));
}
return $directorioArray;
}