如何序列化一个(复杂的)条令2对象


How can I serialize a (complex) doctrine 2 object?

我正在使用Doctrine2(在Zend框架内,没有Symfony2)。

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

我的对象结构如下:

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

我想以某种方式将它存储到Zend缓存中。序列化完整对象的最佳方式是什么?我还试图弄清楚如何将其编码为JSON以获得提示,但还没有成功。

与其他人的建议不同,仅仅使用serialize()是行不通的,因为它序列化了许多您不需要的内部原则。

IIRC,没有简单的方法来序列化一个条令实体。可以使用EntityManager检索类元数据,从中可以循环遍历属性并将它们检索到数组中。您还必须递归地嵌套到相关实体中才能获得它们的值。

我启动了一个库来帮助序列化复杂对象(但从未完成)。如果你深入研究该项目中的最小源代码,你就可以了解如何提取值。您还可以看看这个类,它做的是相反的(但不嵌套到相关对象中)。

我强烈建议深入研究Doctrine的源代码,它很有教育意义。还可以看看API文档,特别是Doctrine'ORM'Mapping'ClassMetadataInfo

我也面临同样的问题。正在等待序列化Doctrine对象的更好解决方案。我已经编写了将条令对象转换为Array〔Array==>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;
    }
}

在创建条令实体时扩展此类

 /**
 * @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')); 

只需初始化集合的每个代理对象和相关实体。对它调用一些方法(除了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;

您要做的是"规范化"实体。

在您的ZF2项目的作曲家:

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

在您的代码中:

use Symfony'Component'Serializer'Normalizer'PropertyNormalizer;
$normalizer = new PropertyNormalizer();
$array      = $normalizer->normalize( $entity );

这给了你一个数组,从那里开始,你的选择是无限的。

祝你好运。Alex