【问题标题】:Persisting unserialized object持久化未序列化的对象
【发布时间】:2016-08-25 19:37:55
【问题描述】:

我需要在 Symfony2 命令中保留未序列化的对象 whit Doctrine:

/* create object */
$e = new Event();
$u = $em->getRepository('TestWebBundle:User')->findOneByUsername('test_user');
$e->setUser($u);
$e->setCompany($u->getCompany());
$e->setType(Event::TYPE_COMPANY);
$e->setTime(new \DateTime());
/* serialize  */
$es = serialize($e);
/* unserialize */
$esu = unserialize($es);
/* try to store in db */
$em->persist($esu); // error appears here
$em->flush();

$em 是EntityManager,一切正常,包括序列化(我认为),但出现警告

[Symfony\Component\Debug\Exception\ContextErrorException]
Warning: in_array() expects parameter 2 to be array, null given  

并且对象本身不保存。如果我尝试坚持 $e 它工作正常。知道有什么问题吗?

【问题讨论】:

  • 可能会丢失与相关对象(用户和公司)的链接尝试刷新它们
  • 代码:echo $e->getUser();回声 $e->getCompany();回声 $esu->getUser();回声 $esu->getCompany();给出 test_user_name comp_name test_user_name [Symfony\Component\Debug\Exception\ContextErrorException] 可捕获的致命错误:方法 Proxies__CG__\TCom\TestWebBundle\Entity\Company::__toString() 必须返回字符串值 Company 类有 __toString,所以我会尝试“实现 __sleep()"

标签: symfony doctrine-orm symfony-2.7


【解决方案1】:

我通过实现自己的序列化和反序列化解决了这个问题:

function cserialize($o,$raw=false){
  static $fn=__FUNCTION__;
  $otype = strtolower(gettype($o));
  // Simple types
  if(in_array($otype,array('null','boolean','integer','float','string','double'))){
    $r = array(
      'type'=>'raw',
      'value'=>$o
    );
    if($raw)return $r;
    return serialize($r);
  }
  //
  if($otype == 'object'){
    $oclass = get_class($o);
  } else {
    $oclass = null;
  }
  // Arrays
  if(is_array($o) || $oclass == 'Doctrine\Common\Collections\ArrayCollection' ){
    $t = array();
    foreach ($o as $element)
      $t[] = $fn($element,true);
    $r = array(
      'type'=>'array',
      'value'=>$t
    );
    if($raw)return $r;
    return serialize($r);
  }
  // Objects
  if($otype == 'object'){
    $isEntity = (strpos($oclass, '\\Entity\\') !== false);
    if($isEntity && $o->getId()!==null){
      // Entity whit id - keep just id
      $repository = explode('\\Entity\\',$oclass);
      $repository[0] = implode('',explode('\\',$repository[0]));
      $repository[1] = implode('',explode('\\',$repository[1]));
      $repository = implode(':',$repository);
      $repository = str_replace('Proxies__CG__','',$repository);
      $r = array(
        'type'=>'entity-stored',
        'repository'=>$repository,
        'id'=>$o->getId()
      );
      if($raw)return $r;
      return serialize($r);
    }
    if(!$isEntity){
      // Some kind of object - use normal serialization
      $r = array(
        'type'=>'raw',
        'value'=>$o
      );
      if($raw)return $r;
      return serialize($r);
    } else {
      $t = array();
      foreach (get_class_methods($o) as $method) {
          if(strncmp('get',$method,3)!=0 ||
            $method == 'getAsFlatArray' ||
            $method == 'getId'
          )
            continue;
          $val = $o->$method();
          $name = 'set'.substr($method,3);
          if($val !== null)
            $t[$name] = $fn($val,true);
      }
      $r = array(
        'type'=>'entity-new',
        'class'=>$oclass,
        'value'=>$t
      );
      if($raw)return $r;
      return serialize($r);
    }
  }
  throw new Exception("Error in serializer", 1);
}
function cunserialize($o,$em,$raw=false){
  static $fn = __FUNCTION__;
  if(!$raw)$o=unserialize($o);
  switch ($o['type']) {
    case 'array':
      $t=array();
      foreach ($o['value'] as $element)
        $t[] = cunserialize($element,$em,$raw);
      return $t;
    case 'entity-new':
      $class = '\\'.$o['class'];
      $r = new $class();
      foreach ($o['value'] as $method => $value)
        $r->$method($fn($value,$em,true));
      return $r;
    case 'entity-stored':
      return $em->getRepository($o['repository'])->findOneById($o['id']);
    case 'raw';
      return $o['value'];
    default:
      throw new Exception("Error in unserializer", 1);

  }
}

所以现在我可以打电话了:

$es = cserialize($e);
$esu = cunserialize($es,$em);

问题在于属性的休眠和唤醒。

【讨论】:

    猜你喜欢
    • 2011-02-05
    • 1970-01-01
    • 2011-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-21
    相关资源
    最近更新 更多