2017-05-10 10 views
0

PHP7.0で単純なオブジェクトの配列をシリアル化しようとしていますが、何らかの理由で動作しません。ここでは、オブジェクトのvar_dump」D列は次のとおりです。単純なPHP7.0クラスが正しくシリアル化されていません

array (size=3) 
    0 => 
    object(My\Bundle\Entity\Role)[504] 
     protected 'id' => int 2 
     protected 'role' => string 'ROLE_LDAP_CHECKIN_APP_ADMIN' (length=27) 
    1 => 
    object(My\Bundle\Entity\Role)[506] 
     protected 'id' => int 3 
     protected 'role' => string 'ROLE_LDAP_CHECKIN_APP_USER' (length=26) 
    2 => 
    object(My\Bundle\Entity\Role)[507] 
     protected 'id' => int 1 
     protected 'role' => string 'ROLE_USER' (length=9) 

これは、次のシリアル化された文字列を出力します

a:3:{i:0;r:18;i:1;r:22;i:2;r:26;} 

私はその文字列をアンシリアライズした場合、私はちょうど次のエラーを取得:

Notice: unserialize(): Error at offset 14 of 33 bytes 

クラスは、\Serializiableを実装します。

namespace My\Bundle\Entity; 

use Doctrine\Common\Collections\ArrayCollection; 
use Doctrine\ORM\Mapping as ORM; 
use Symfony\Component\Security\Core\Role\RoleInterface; 
use Symfony\Component\Validator\Constraints as Assert; 

/** 
* Role Entity 
* 
* @ORM\Entity 
* @ORM\Table(name="role") 
* 
*/ 
class Role implements \Serializable 
{ 

    /** 
    * @ORM\Id 
    * @ORM\Column(type="integer", name="id") 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    protected $id; 

    /** 
    * @ORM\Column(type="string", name="role", unique=true, length=255) 
    * @Assert\NotBlank() 
    */ 
    protected $role; 

    /** 
    * Populate the role field 
    * @param string $role ROLE_FOO etc 
    */ 
    public function __construct($role) 
    { 
     $this->role = $role; 
    } 

    /** 
    * Return the id field. 
    * 
    * @return string 
    */ 
    public function getId() 
    { 
     return $this->id; 
    } 

    /** 
    * Set the role field 
    * 
    * @param $role 
    */ 
    public function setRole($role) 
    { 
     $this->role = $role; 
    } 

    /** 
    * Return the role field. 
    * @return string 
    */ 
    public function getRole() 
    { 
     return $this->role; 
    } 

    /** 
    * Return the role field. 
    * @return string 
    */ 
    public function __toString() 
    { 
     return (string) $this->role; 
    } 

    public function serialize() 
    { 
     return serialize(array($this->id, $this->role)); 
    } 

    public function unserialize($serialized) 
    { 
     list($this->id, $this->role) = unserialize($serialized); 
    } 
} 

クラスがロードされていることを確認できます。

編集:http://www.phpinternalsbook.com/classes_objects/serialization.htmlによると、シリアル化された文字列の'r'エントリは「参照」を表し、そのエントリは配列またはオブジェクト内の他のエントリへの参照/ポインタにすぎないことを意味します。明らかに、18番、22番、26番のエントリへの参照は意味をなさない。これはPHPのバグですか?

+0

チェックするだけで、文字列をどのように格納/取得していますか?文字列はバイナリのヌル文字 '\ 0'を持つことがあります。文字列をコピー/ペーストすると、正しくシリアル化されません。 – Dennis

+0

文字列を' var_dump'で出力しています。文字通り'unserialize(serialize($ array))'を呼び出すだけです。私はバグを分離するためにそれをやっています。 – DIMMSum

+1

それでは、どのようにしてアレイを構築しますか?このオブジェクトの配列は、 'serialize'して、' unserialize'してください。https://3v4l.org/P1CNp – AbraCadaver

答えて

0

私は質問の書き込みにこれは言及していませんでしたが、私はラッパークラス 'serialize関数内の直列化関数を呼び出していました。つまり、子クラスはparent::serializeという名前のserialize関数を持っていて、その入れ子の親のserialize関数内で配列をシリアル化しようとしていました。未定義の動作ではありませんが、これはPHPの既知のバグです(はい、時には実際にあなたのせいではありません)。バグは以下のとおりです:https://bugs.php.net/bug.php?id=66052&edit=1

いくつかのバグレポートからの抜粋:

The current serialization format does not specify value ids and instead relies on a count from the beginning of the data. While this works fine for "standard" serialization, it breaks horribly when custom serialization (via Serializable) is thrown into the mix.

...と...

The effects of this bug are one of two things:

  • The values simply point to the wrong variables. Very hard to debug and incredibly confusing to anyone unfamiliar with the serialization format.
  • The values point to non-existent values (-1 or max +1). This causes an error which reports the byte offset into the serialized data where the error occurred.

シリアライズされた文字列内の参照を示す理由は説明してその質問は壊れてしまった。私は、あなたのシリアライゼーションコールをすべて手動で平坦化する以外に、これを回避する方法は知らないし、PHPで働いている素晴らしい人たちによってまだ修正されていないことにショックを受けました。とにかく、正しいことができない文字列/バッファのバイトオフセットに関する一見不可解なエラーメッセージが表示されている場合は、カスタムのネストされたシリアル化を行わないようにしてください。

関連する問題