更改实体关系后的意外行为

时间:2014-11-12 17:29:24

标签: php symfony doctrine-orm

我的噩梦继续......

在我需要更改我的实体间关系的早期线程中实现成功的解决方案后,当我尝试将用户登录到应用程序时,我现在收到此错误:

CRITICAL - Uncaught PHP Exception Symfony\Component\Debug\Exception\UndefinedMethodException: "Attempted to call method "getRole" on class "Closure"." at C:\Dropbox\xampp\htdocs\etrack3\src\Ampisoft\Bundle\etrackBundle\Entity\Users.php line 234

我从manyToMany关系改为用户/角色实体之间的manyToOne / OneToMany。

我读过序列化可能导致问题,但我把它拿出来并没有任何区别。序列化所需方法的残余仍在那里,所以请忽略(除非它们是问题)。

请有人告诉我,我做错了什么?我想知道是否最好废弃所有数据库表并重新开始!!!!

这是实体类。

/**
 * user
 *
 * @ORM\Table(name="users")
 * @ORM\Entity(repositoryClass="Ampisoft\Bundle\etrackBundle\Entity\UsersRepository")
 */
class Users implements UserInterface
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="username", type="string", length=25, unique=true)
     */
    private $username;

    /**
     * @var string
     *
     * @ORM\Column(name="password", type="string", length=64)
     */
    private $password;

    /**
     * @ORM\Column(name="firstname", type="string", length=25)
     */
    private $firstname;

    /**
     * @ORM\Column(name="surname", type="string", length=25)
     */
    private $lastname;

    /**
     * @var boolean
     *
     * @ORM\Column(name="isActive", type="boolean")
     */
    private $isActive = 1;

    /**
     * @var string
     *
     * @ORM\Column(name="email", type="string", length=255, unique=true)
     */
    private $email;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="lastLogged", type="string")
     */
    private $lastLogged = '-0001-11-30 00:00:00';

    /**
     * @var string;
     *
     * @ORM\Column(name="salt", type="string", length=255)
     */
    private $salt;

    /**
     * @ORM\ManyToOne(targetEntity="Roles", inversedBy="users")
     *
     */
    private $roles;

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set Id
     *
     * @return integer
     */
    public function setId($id)
    {
        $this->id = $id;
        return $this;
    }

    /**
     * Set username
     *
     * @param string $username
     * @return user
     */
    public function setUsername($username)
    {
        $this->username = $username;

        return $this;
    }

    /**
     * Get username
     *
     * @return string
     */
    public function getUsername()
    {
        return $this->username;
    }

    /**
     * Set password
     *
     * @param string $password
     * @return user
     */
    public function setPassword($password)
    {
        $this->password = $password;

        return $this;
    }

    /**
     * Get password
     *
     * @return string
     */
    public function getPassword()
    {
        return $this->password;
    }

    /**
     * Set isActive
     *
     * @param boolean $isActive
     * @return user
     */
    public function setIsActive($isActive)
    {
        $this->isActive = $isActive;

        return $this;
    }

    /**
     * Get isActive
     *
     * @return boolean
     */
    public function getIsActive()
    {
        return $this->isActive;
    }

    /**
     * Set email
     *
     * @param string $email
     * @return user
     */
    public function setEmail($email)
    {
        $this->email = $email;

        return $this;
    }

    /**
     * Get email
     *
     * @return string
     */
    public function getEmail()
    {
        return $this->email;
    }

    /**
     * Set lastLogged
     *
     * @param \DateTime $lastLogged
     * @return user
     */
    public function setLastLogged($lastLogged)
    {
        $this->lastLogged = $lastLogged;

        return $this;
    }

    /**
     * Get lastLogged
     *
     * @return \DateTime
     */
    public function getLastLogged()
    {
        return $this->lastLogged;
    }

    public function __construct()
    {
        $this->roles = new ArrayCollection();
        $this->isActive = true;
    }


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

        return $roles;
    }

    /**
     * @param $roles
     * @return $this
     */
    public function setRoles($roles)
    {
        $this->roles = $roles;
        return $this;
    }

    /**
     * @inheritDoc
     */
    public function eraseCredentials()
    {
    }

    /**
     * @inheritDoc
     */
    public function getSalt()
    {
        return $this->salt;
    }

    public function setSalt($salt)
    {
        $this->salt = $salt;
        return $this;
    }

    public function isAccountNonExpired()
    {
        return true;
    }

    public function isAccountNonLocked()
    {
        return true;
    }

    public function isCredentialsNonExpired()
    {
        return true;
    }

    public function isEnabled()
    {
        return $this->isActive;
    }

    /**
     * Add roles
     *
     * @param \Ampisoft\Bundle\etrackBundle\Entity\Roles $roles
     * @return users
     */
    public function addRoles(Roles $roles)
    {
        $this->roles[] = $roles;

        return $this;
    }

    /**
     * Remove roles
     *
     * @param \Ampisoft\Bundle\etrackBundle\Entity\Roles $roles
     */
    public function removeRoles(Roles $roles)
    {
        $this->roles->removeElement($roles);
    }

    /**
     * Set firstname
     *
     * @param string $firstname
     * @return users
     */
    public function setFirstname($firstname)
    {
        $this->firstname = $firstname;

        return $this;
    }

    /**
     * Get firstname
     *
     * @return string
     */
    public function getFirstname()
    {
        return $this->firstname;
    }

    /**
     * Set lastname
     *
     * @param string $lastname
     * @return users
     */
    public function setLastname($lastname)
    {
        $this->lastname = $lastname;

        return $this;
    }

    /**
     * Get lastname
     *
     * @return string
     */
    public function getLastname()
    {
        return $this->lastname;
    }


    /**
     * @see \Serializable::serialize()
     */
    /**
     * Serializes the content of the current User object
     * @return string
     */
    public function serialize()
    {
        return \json_encode(
            array($this->username, $this->password, $this->salt,
                $this->roles, $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->roles, $this->id) = \json_decode(
            $serialized);
    }

}

更新1 这已经奏效但产生了一个新的错误我会在后期计时器让我把它转移到一个新问题。

Catchable Fatal Error: Argument 4 passed to Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken::__construct() must be of the type array, object given, called in C:\Dropbox\xampp\htdocs\etrack3\vendor\symfony\symfony\src\Symfony\Component\Security\Core\Authentication\Provider\UserAuthenticationProvider.php on line 96 and defined

1 个答案:

答案 0 :(得分:1)

我觉得你想要的不是这个

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

    return $roles;
}

但是这个

public function getRoles()
{
    return $this->roles;
}

角色应该已经是一个ArrayCollection,所以在(我假设)角色类上调用getRole似乎是可能的问题。

如果您正在使用Eclipse之类的IDE,那么类Doctrine\Common\Collections\ArrayCollection;这应该是您的角色集合,我建议您使用IDE来执行此类操作(用于类型提示)< / p>

//... at the top of the class file before the class deceleration
use Doctrine\Common\Collections\ArrayCollection;

/**
* @param ArrayCollection $roles
*/
public function setRoles(ArrayCollection $roles)
{
   //.. type cast the input to allow only use of ArrayCollection class
    $this->roles = $roles;
}

/**
* @return ArrayCollection
*/
public function getRoles()
{
    return $this->roles;
}

此外,您很有可能在某些时候将$this->roles设置为标准数组。如果只能接受该类型的类以排除错误(例如使用普通数组),则应始终将输入类型转换为特定类。

最后一件事,通常是受保护的属性是首选,因为后者你可以扩展类,它不像私有那样在类外部访问,但与私有不同,它可以在继承类中访问。