Php 如何防止FOSUserbundle在Symfony3.3中重复角色

Php 如何防止FOSUserbundle在Symfony3.3中重复角色,php,symfony,doctrine-orm,orm,fosuserbundle,Php,Symfony,Doctrine Orm,Orm,Fosuserbundle,我是编程新手,决定使用Symfony框架启动PHP 我的目标是建立一个用户系统,其中用户与其角色之间存在多对多关系。理想情况下,我希望角色存储在自己的表中 我已经设法设置了这些,但这里确实有一个问题。 每当FOSUserBundle创建一个用户并添加一个角色时,我的代码就会在Roles表中创建一个重复的条目。例如: 我创建一个user:User1,并分配角色“role\u ADMIN”-在roles表中创建一个“role\u ADMIN”记录 我创建了一个user:User2并分配了相同的角色

我是编程新手,决定使用Symfony框架启动PHP

我的目标是建立一个用户系统,其中用户与其角色之间存在多对多关系。理想情况下,我希望角色存储在自己的表中

我已经设法设置了这些,但这里确实有一个问题。 每当FOSUserBundle创建一个用户并添加一个角色时,我的代码就会在Roles表中创建一个重复的条目。例如:


我创建一个user:User1,并分配角色“role\u ADMIN”-在roles表中创建一个“role\u ADMIN”记录

我创建了一个user:User2并分配了相同的角色-创建了一个新的记录,而不是使用现有的role_ADMIN记录


我曾想过让实体经理在创建新角色之前检查角色表,但是,正如我在stackoverflow的其他响应中所读到的,这是非常不鼓励的。其他答案也不鼓励在实体内使用服务

这是我为这两个实体编写的代码(我是编程新手,不会原谅错误)

User.php

<?php
namespace ShagCore\MemberBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\Common\Collections\ArrayCollection as ArrayCollection;

/**
 * @ORM\Entity
 * @ORM\Table(name="member_user")
 */
class User extends BaseUser
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\ManyToMany(targetEntity="Role", inversedBy="users", cascade={"persist"})
     * @ORM\JoinTable(name="member_user_role")
     */
    protected $userRoles;

    public function __construct()
    {
        parent::__construct();
        $this->userRoles = new ArrayCollection();
    }

    public function addRole($roleStr)
    {
        //get the role as a string, loop through the $this->roles (Role Objects)
        //ensure that this role name isn't there, THEN add it as a new Role Obj 
        //to the $this->roles array

        $roleStr = strtoupper($roleStr);   

        $currRoles = [];

        foreach($this->userRoles as $userRole) {
            $currRoles[] = $userRole->getRole();
        }

        if(!in_array($roleStr, $currRoles)) {
            $role = new Role();
            $role->setRole($roleStr);
            $this->userRoles[] = $role;
        }
    }

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

        return array_unique($roles);
    }
}
<?php
namespace ShagCore\MemberBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection as ArrayCollection;


//TODO: removeRole()

/**
 * @ORM\Entity
 * @ORM\Table(name="member_role")
 */
class Role
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\Column(type="string", unique=TRUE, length=100)
     */
    protected $role;
    /**
     * @ORM\ManyToMany(targetEntity="User", mappedBy="userRoles", cascade={"persist"})
     */
    protected $users;

    /**
     * @ORM\Column(type="text", nullable=TRUE)
     */
    protected $description;

    public function __construct()
    {
        //parent::__construct();
        $this->users = new ArrayCollection();
    }


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

    /**
     * Set role
     *
     * @param string $role
     *
     * @return Role
     */
    public function setRole($role)
    {
        $this->role = $role;

        return $this;
    }

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

    /**
     * Set description
     *
     * @param string $description
     *
     * @return Role
     */
    public function setDescription($description)
    {
        $this->description = $description;

        return $this;
    }

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

    /**
     * Add user
     *
     * @param \ShagCore\MemberBundle\Entity\User $user
     *
     * @return Role
     */
    public function addUser(\ShagCore\MemberBundle\Entity\User $user)
    {
        $this->users[] = $user;

        return $this;
    }

    /**
     * Remove user
     *
     * @param \ShagCore\MemberBundle\Entity\User $user
     */
    public function removeUser(\ShagCore\MemberBundle\Entity\User $user)
    {
        $this->users->removeElement($user);
    }

    /**
     * Get users
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getUsers()
    {
        return $this->users;
    }
}

您正在调用
新角色
,因此将创建(并持久化)一个新角色对象。如果您不想让addRole将
Role
对象作为参数,并将其添加到ArrayCollection中。这通常是某种UserManager的一部分。同意ccKep只是为了更清楚一点:让addRole接受现有的角色对象我考虑到这一点,我遇到的障碍是这些角色是由FOSUserBundle作为字符串提供的,而不是角色对象。确切地说,它只是数据库中的一个字符串,而不是对象。如果使用FOS用户包,则无需创建角色实体。我相信您可以通过user->getRole()获取角色。。