简单PHP7.0类序列化错误

简单PHP7.0类序列化错误,php,symfony,serialization,doctrine,php-7,Php,Symfony,Serialization,Doctrine,Php 7,我试图在PHP7.0中序列化一个简单对象数组,但由于某些原因,它不起作用。以下是对象的var\u dump'd数组: 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 =>

我试图在PHP7.0中序列化一个简单对象数组,但由于某些原因,它不起作用。以下是对象的
var\u dump
'd数组:

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
该类实现了
\serializable

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);
    }
}
我可以确认该类正在加载


编辑:根据,序列化字符串中的
'r'
项代表“引用”,意味着该项只是数组或对象中某个其他项的引用/指针。显然,提及第18条、第22条和第26条是毫无意义的。这是一个PHP错误吗?

我在问题总结中没有提到这一点,但我调用了包装类“
serialize
函数”中的序列化函数。换句话说,子类有一个
serialize
函数,它在该函数中调用
parent::serialize
,我试图在嵌套父类的
serialize
函数中序列化我的数组。虽然不是未定义的行为,但这是PHP中的一个已知错误(是的,有时实际上不是您的错)。此处列出了错误:

错误报告的一些摘录:

当前序列化格式不指定值ID,而是依赖于数据开头的计数。虽然这对于“标准”序列化很好,但当自定义序列化(通过Serializable)被抛出到混合中时,它会严重崩溃

。。。而且

此错误的影响有两种:

  • 这些值只是指向错误的变量。很难调试,对于任何不熟悉序列化格式的人来说都令人难以置信地困惑
  • 这些值指向不存在的值(-1或max+1)。这会导致将字节偏移量报告到发生错误的序列化数据中的错误

这解释了问题中显示的序列化字符串中的引用被破坏的原因。除了手动平滑所有序列化调用之外,我不知道如何解决这个问题,我感到震惊的是,在PHP上工作的优秀人员还没有修复这个问题。无论如何,如果您看到关于字符串/缓冲区的字节偏移量的错误消息似乎无法解释,请确保您没有执行自定义嵌套序列化。

仅检查一下,您是如何存储/检索字符串的?有时字符串可能有空字符
\0
,它们是二进制的,如果复制/粘贴字符串,它将不会正确地取消序列化。我正在使用
var\u dump
打印字符串,在应用程序中,我实际上只是调用
unserialize(serialize($array))
。我这样做是为了隔离一个bug。那么如何构建阵列呢?对象数组应该
序列化
非序列化
很好,检查:我敢打赌这是Doctrine或Symfony正在做的事情,将角色作为引用传递进来,在序列化之前没有正确地取消引用。在7.0.0-7.0.5中似乎是固定的(并在7.0.6中重新出现)-有趣,我不知道这件事!谢谢你!