2017-09-10 5 views
0

私はZend Framework 3アプリケーションを持っています。私はmodule.config.phpにViewJsonStrategyを追加しました。しかし、私は彼らの関係は、アレイ内の多くの人にとってONEオブジェクトをJSONオブジェクトを返したい:私のコントローラでRelatioshipsを持つオブジェクトをZF3にシリアル化MVC 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) { 
$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 

オブジェクトは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; 

} 
関連する問題