我正在研究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上的非对象上调用成员函数getRole() 57
读取SecurityDataCollector类时,Closure抛出错误
array_map(function ($role){ return $role->getRole();}, $token->getRoles()
现在我将其更改为
array_map(function ($role){ var_dump($role); return $role->getRole();}, $token->getRoles()
令我惊讶的是,$role
是一个对象Rol,但我无法理解为什么会收到错误。
答案 0 :(得分:14)
我发现解决方案问题是PHP 5.4中的错误(我正在使用的php)序列化方法 github用户yoannch提出了这个问题{ {3}},使用serialize/unserialize
方法
json_encode/json_decode
方法
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);
}
只需更改正确的名称属性
答案 1 :(得分:11)
我有同样的问题(Windows,PHP 5.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_ADMIN
)。
答案 2 :(得分:6)
User
和Role
个对象的循环引用相关的所有问题。
因此,您无需序列化User::$roles
和Role::$users
字段。
查看Symfony\Component\Security\Core\Authentication\Token\AbstractToken::__construct()
和Symfony\Component\Security\Core\Authentication\Token\AbstractToken::serialize()
。
如何看待,Symfony通过在序列化之前调用UserInterface::getRoles()
来获取用户的角色。并分别序列化User
和Roles
。
您必须在\Serializable
和User
个实体中实施Role
界面。
/**
* Acme\Bundle\UserBundle\Entity\User
*
* @ORM\Table(name="`user`")
* @ORM\Entity(repositoryClass="Acme\Bundle\UserBundle\Entity\UserRepository")
*/
class User implements AdvancedUserInterface, EquatableInterface, \Serializable
{
/**
* @var integer $id
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string $username
*
* @ORM\Column(type="string", length=30, unique=true)
*/
private $username;
/**
* @var string $email
*
* @ORM\Column(type="string", length=100, unique=true)
*/
private $email;
/**
* @var string $salt
*
* @ORM\Column(type="string", length=40)
*/
private $salt;
/**
* @var string $password
*
* @ORM\Column(type="string", length=128)
*/
private $password;
/**
* @var boolean $isActive
*
* @ORM\Column(type="boolean")
*/
private $isActive;
/**
* User's roles. (Owning Side)
*
* @var ArrayCollection
*
* @ORM\ManyToMany(targetEntity="Role", inversedBy="users")
*/
private $roles;
// .....
/**
* @see \Serializable::serialize()
*/
public function serialize()
{
/*
* ! Don't serialize $roles field !
*/
return \serialize(array(
$this->id,
$this->username,
$this->email,
$this->salt,
$this->password,
$this->isActive
));
}
/**
* @see \Serializable::unserialize()
*/
public function unserialize($serialized)
{
list (
$this->id,
$this->username,
$this->email,
$this->salt,
$this->password,
$this->isActive
) = \unserialize($serialized);
}
}
/**
* Acme\Bundle\UserBundle\Entity\Role
*
* @ORM\Table(name="role")
* @ORM\Entity
*
*/
class Role implements RoleInterface, \Serializable
{
/**
* @var integer $id
*
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string $role
*
* @ORM\Column(name="role", type="string", length=20, unique=true)
*/
private $role;
/**
* Users in group (Inverse Side)
*
* @var ArrayCollection
*
* @ORM\ManyToMany(targetEntity="User", mappedBy="roles")
*/
private $users;
// .....
/**
* @see \Serializable::serialize()
*/
public function serialize()
{
/*
* ! Don't serialize $users field !
*/
return \serialize(array(
$this->id,
$this->role
));
}
/**
* @see \Serializable::unserialize()
*/
public function unserialize($serialized)
{
list(
$this->id,
$this->role
) = \unserialize($serialized);
}
}
所有这些都将被正确序列化/反序列化。
上的铁饼