Symfony 角色界面抛出“;调用非对象“;错误

Symfony 角色界面抛出“;调用非对象“;错误,symfony,Symfony,我正在研究Symfony 2.0.16 我的UserProvider中有getRoles方法 public function getRoles() { /** * @var \Doctrine\Common\Collections\ArrayCollection $rol */ return $this->rol->toArray(); } 我的Rol实体具有角色接口 class Rol implements \Symfony\Component

我正在研究Symfony 2.0.16

我的UserProvider中有getRoles方法

public function getRoles()
{
    /**
     * @var \Doctrine\Common\Collections\ArrayCollection $rol
     */
    return $this->rol->toArray();
}
我的Rol实体具有角色接口

class Rol implements \Symfony\Component\Security\Core\Role\RoleInterface
//...
public function getRole()
{
    return $this->getName();
}
但是当我尝试登录时,我得到以下错误

致命错误:在C:\Users\julian\Code\parqueadero\vendor\symfony\src\symfony\Bundle\SecurityBundle\DataCollector\SecurityDataCollector.php的第57行对非对象调用成员函数getRole()

读取SecurityDataCollector类时,闭包引发错误

array_map(function ($role){ return $role->getRole();}, $token->getRoles()
现在我把这个改成

array_map(function ($role){ var_dump($role); return $role->getRole();}, $token->getRoles()

令我惊讶的是,
$role
是一个对象Rol,但我不明白为什么会出现错误。

我找到了解决方案。问题是PHP5.4中的一个错误(我正在使用的PHP)序列化方法github用户提出了这个,正在使用
json\u encode/json\u decode
方法覆盖
serialize/unserialize
方法

class User implements \Serializable

//...

/**
 * Serializes the content of the current User object
 * @return string
 */
public function serialize()
{
    return \json_encode(
            array($this->username, $this->password, $this->salt,
                    $this->rol, $this->id));
}

/**
 * Unserializes the given string in the current User object
 * @param serialized
 */
public function unserialize($serialized)
{
    list($this->username, $this->password, $this->salt,
                    $this->rol, $this->id) = \json_decode(
            $serialized);
}
只需更改正确的名称属性

我也遇到了同样的问题(Windows,PHP5.4.5),已更新为5.4.7,但仍然无法工作。尽管如此,我还是想出了一个需要较少维护的解决方法(当您在文章中描述的重写序列化函数时,您必须在添加/删除字段时使它们保持最新)。到目前为止,它对我是有效的,我希望没有其他的问题产生于我可能已经忘记的解决方法。只需如下更改用户的
getRoles()
函数:

/**
 * @inheritDoc
 */
public function getRoles()
{
    $roles = array();
    foreach ($this->userRoles as $role) {
        $roles[] = $role->getRole();
    }

    return $roles;
}

请注意,
$role->getRole()
以字符串形式返回角色名称(例如
role\u ADMIN
)。

此问题的解决方法非常简单。 与您的
用户
角色
对象的循环引用相关的所有问题。 因此,您不必序列化
用户::$roles
角色::$users
字段

查看
Symfony\Component\Security\Core\Authentication\Token\AbstractToken::\uuu construct()
Symfony\Component\Security\Core\Authentication\Token\AbstractToken::serialize()

在序列化之前,Symfony通过调用
UserInterface::getRoles()
获取用户角色。并分别序列化
用户
角色

您必须在
用户
角色
实体中实现
\Serializable
接口

例子:
/**
*Acme\Bundle\UserBundle\Entity\User
* 
*@ORM\Table(name=“`user`”)
*@ORM\Entity(repositoryClass=“Acme\Bundle\UserBundle\Entity\UserRepository”)
*/
类用户实现AdvancedUserInterface、EqualTableInterface、\Serializable
{
/**
*@var整数$id
*
*@ORM\Column(name=“id”,type=“integer”)
*@ORM\Id
*@ORM\GeneratedValue(strategy=“AUTO”)
*/
私人$id;
/**
*@var string$username
* 
*@ORM\Column(type=“string”,length=30,unique=true)
*/
私有$username;
/**
*@var string$email
* 
*@ORM\Column(type=“string”,length=100,unique=true)
*/
私人电子邮件;
/**
*@var string$salt
*
*@ORM\Column(type=“string”,长度=40)
*/
私人食盐;;
/**
*@var字符串$password
*
*@ORM\Column(type=“string”,长度=128)
*/
私人$password;
/**
*@var boolean$isActive
*
*@ORM\Column(type=“boolean”)
*/
私人活动;
/**
*用户角色。(拥有方)
* 
*@var数组集合
* 
*@ORM\ManyToMany(targetEntity=“Role”,inversedBy=“users”)
*/
私人角色;
// .....
/**
*@see\Serializable::serialize()
*/
公共函数序列化()
{
/*
*!不要序列化$roles字段!
*/
返回\序列化(数组)(
$this->id,
$this->username,
$this->email,
$this->salt,
$this->password,
$this->isActive
));
}
/**
*@see\Serializable::unserialize()
*/
公共函数取消序列化($序列化)
{
名单(
$this->id,
$this->username,
$this->email,
$this->salt,
$this->password,
$this->isActive
)=\n取消序列化($serialized);
}
}
/**
*Acme\Bundle\UserBundle\Entity\Role
*
*@ORM\Table(name=“role”)
*@ORM\Entity
* 
*/
类角色实现角色接口,\n可序列化
{
/**
*@var整数$id
*
*@ORM\Column(type=“integer”)
*@ORM\Id
*@ORM\GeneratedValue(strategy=“AUTO”)
*/
私人$id;
/**
*@var字符串$role
*
*@ORM\Column(name=“role”,type=“string”,length=20,unique=true)
*/
私人角色;
/**
*组中的用户(反向侧)
* 
*@var数组集合
* 
*@ORM\ManyToMany(targetEntity=“User”,mappedBy=“roles”)
*/
私人用户;
// .....    
/**
*@see\Serializable::serialize()
*/
公共函数序列化()
{
/*
*!不要序列化$users字段!
*/
返回\序列化(数组)(
$this->id,
$this->role
));
}
/**
*@see\Serializable::unserialize()
*/
公共函数取消序列化($序列化)
{
名单(
$this->id,
$this->role
)=\n取消序列化($serialized);
}
}
所有这些都将被正确序列化/取消序列化

看铁饼

另见:

array\u map为getTokens返回的所有元素调用此函数。你确定它们都是Rol对象吗?很酷的解决方法。我已经测试了它,它的工作!谢谢你,迈克尔谢谢。这让我快发疯了!谢谢你帮我省下一天的时间来搜索我的代码到底出了什么问题。我将回到5.3.x。由于5.4,我遇到了很多问题。更多信息请参见“官方发行”:Thks供参考:)但作为Ztere0