如何序列化(复杂)学说2对象?

时间:2012-02-04 22:38:48

标签: php zend-framework doctrine-orm

我正在使用Doctrine2(在Zend Framework中,没有Symfony2)。

我有一个“复杂的”doctrine2对象,它与另外两个对象有一对多的关系。

我的对象的结构如下所示:

   $object->attribute1 = "foo";
   $object->attribute2 = "bar";
   $object->doctrineCollection1 = <DOCTRINE_COLLECTION2>;
   $object->doctrineCollection1 = <DOCTRINE_COLLECTION2>;

我想以某种方式将它存储到Zend Cache中。序列化整个对象的最佳方法是什么?我还试图找出如何将其编码为JSON以获得提示,但尚未成功。

4 个答案:

答案 0 :(得分:1)

与其他人的建议不同,仅使用serialize()将无效,因为它序列化了许多您不需要的内部教义。

IIRC,没有简单的方法来序列化一个Doctrine实体。您可以使用EntityManager检索类元数据,您可以从中循环属性并将其检索到数组中。您必须以递归方式嵌套到相关实体中以获取其值。

有点已启动a library to help with serializing complex objects(但从未完成)。如果您深入研究该项目中的最小源代码,您就可以了解如何将值拉出来。您还可以查看反向(但不嵌套到相关对象中)的class

我强烈建议深入学习Doctrine的源代码,这很有教育意义。另请查看API docs,具体来说,您应该查看Doctrine\ORM\Mapping\ClassMetadataInfo

答案 1 :(得分:0)

我面临同样的问题。等待序列化Doctrine对象的更好解决方案。 我编写了将doctrine对象转换为Array的代码[array ==&gt; JSON]

<?php
use Doctrine\ORM\PersistentCollection;

class MyDoctrineEntity
{
    public function arrayFy($level=1 ,array $ignore=array()){
        $maxLevel=3;
        $dateFormat='Y-m-d H:i:s';
        if(is_array($level)){
            $ignore=$level;
            $level=1;
        }
        $level=$level>$maxLevel?$maxLevel:$level;
        $arr=array();
        foreach($this as $key=>$val){
            if(in_array($key ,$ignore))
                continue;
            elseif(is_bool($val)|| is_int($val)||is_string($val)||is_null($val)|| is_float($val) )
                $arr[$key]=$val;
            elseif( $val instanceof  \DateTime)
                $arr[$key]=$val->format($dateFormat);

            elseif($val instanceof PersistentCollection && $level>0 )
            {   
                $childArr=array();
                if( count($val))
                    foreach($val as $x)
                        $childArr[]=$x->arrayFy($level-1,$ignore);

                $arr[$key]=$childArr;
            }elseif($key!='_entityPersister'&&$key!='_identifier'&&$key!='__isInitialized__' && !($val instanceof PersistentCollection))

                $arr[$key]=$val->arrayFy($level-1,$ignore);
        }
        return $arr;
    }
}

在创建Doctrine实体时扩展此类

 /**
 * @Entity
 * @Table(name="user")
 */
class User  extends MyDoctrineEntity
{

将教条转换为数组

$user->arrayFy(); //
$user->arrayFy(2); // how deep you want to print ; default value : 1 , max value:3
$user->arrayFy( array('created_by','salary'));  // columns that you dont want to store 
$user->arrayFy(1,arra('created_by')); 

答案 2 :(得分:0)

只需初始化集合的每个代理对象及相关实体。在它上面调用一些方法(getId除外)。然后,您可以序列化和反序列化您的对象。例如:

class Shop {
    protected $owner;
    protected $visitors;
}

// get shop from databse
...
// initialize proxy entitites
$shop->getOwner()->getName();
$shop->getVisitors()->forAll(function($key, $visitor) {
     $visitor->getName();
})

// then you can serialize;

答案 3 :(得分:0)

您要做的是“规范化”您的实体。

在ZF2项目的作曲家中:

"symfony/serializer" : "dev-master",

在您的代码中:

use Symfony\Component\Serializer\Normalizer\PropertyNormalizer;

$normalizer = new PropertyNormalizer();
$array      = $normalizer->normalize( $entity );

这会给你一个阵列,从那里你的选择是无限的。

祝你好运。 亚历