我试图在PHP7.0中序列化一组简单对象,但由于某种原因它无法正常工作。以下是var_dump
&n;对象数组:
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)
我在问题编写中没有提到这一点,但我在包装类'serialize
函数中调用了序列化函数。换句话说,子类具有serialize
函数,在其中调用parent::serialize
,我试图在嵌套父类serialize
函数内序列化我的数组。虽然不是未定义的行为,但这是PHP中的一个已知错误(是的,它有时实际上不是你的错)。此处列出了错误:https://bugs.php.net/bug.php?id=66052&edit=1
错误报告中的一些摘录:
当前序列化格式未指定值ids,而是依赖于数据开头的计数。虽然这适用于“标准”序列化,但当自定义序列化(通过Serializable)投入混合时,它会破坏性。
......和......
这个错误的影响是两件事之一:
- 这些值只是指向错误的变量。对于不熟悉序列化格式的人来说,很难调试并且令人难以置信的混淆。
- 值指向不存在的值(-1或最大+1)。这会导致错误,该错误会将字节偏移量报告给发生错误的序列化数据。
这解释了为什么问题中显示的序列化字符串中的引用被打破了。我不知道如何解决这个问题,除了手动扁平化所有序列化调用之外,我很惊讶它还没有得到那些从事PHP工作的优秀人员的解决。无论如何,如果您看到关于字符串/缓冲区的字节偏移的看似无法解释的错误消息,那么请确保您没有进行自定义嵌套序列化。