2017-09-10 7 views
0

Zend Framework 3 앱이 있습니다. module.config.php에 ViewJsonStrategy를 추가했습니다. 내 컨트롤러상대방과 ZF3의 직렬화 MVC 응답 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) { 
$directorio = $directorio->getPadre(); 
$directorio->getDirectoriosHijos(); 
$directorio->getArchivosHijos(); 
} 
} 
$hydrator = new Reflection; 
return new JsonModel($hydrator->extract($directorio)); 
} 

엔터티 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 
을하지만 난 그들의 관계와 JSON 개체가 배열에 많은 하나의 개체를 반환 원

관계가있는 객체는 Array와 (과) 같지 않습니다. Json Array()와 마찬가지로 관련 객체가 도착할 수 있습니까?

답변

1

반사 수액 기 자체는 중첩 된 수화/추출을 허용하지 않습니다. 그러나 Hydrator Aggregates 이렇게하십시오, 그러나 당신은 그 후에 다만 그것을 간단하게 인스턴스화하는 그것으로 더 많은 일을 투자해야합니다. 이 경로를 선택하면 테스트 시간을 높이기 위해 조금 더 투자하고 컨트롤러에 주입합니다.

doctrine/doctrine-module 작성자 패키지에서 제공하는 Doctrine Hydrator 사용을 고려해보십시오. 이 프로젝트는 또한 짧은 문서를 가지고 있습니다 hydration

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; 

}