【问题标题】:Symfony/Doctrine/authentication, I can't recover the rolesSymfony/Doctrine/authentication,我无法恢复角色
【发布时间】:2020-02-20 19:22:30
【问题描述】:

我想连接时遇到问题。让我解释一下,我有两个 User 和 Role 实体,它们链接到 ManyToMany 关系,所以我有一个动态 user_role 表。我想与拥有 ROLE_ADMIN 的用户联系,但问题是我无法读取该对象,因此它会读取此角色。这向我显示了这个错误。

警告:isset 中的偏移类型非法或为空

我认为问题出在“$role = $this->roles->toArray();”这行在 getRoles 中。

这是 User.php 的代码

class User implements UserInterface, \Serializable
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

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

    /**
     * @var string The hashed password
     * @ORM\Column(type="string")
     */
    private $password;

    /**
     * @ORM\Column(type="boolean", nullable=false, options={"default" : 0})
     */
    private $isActive;

    /**
     * @ORM\Column(type="string", unique=true, length=64)
     */
    private $token;

    /**
     * @ORM\Column(type="datetime")
     */
    private $expiresAt;

    /**
     * @ORM\ManyToMany(targetEntity="Role", inversedBy="users", fetch="LAZY")
     * @ORM\JoinTable(name="user_role",
     *     joinColumns={
     *      @ORM\JoinColumn(name="user_id", referencedColumnName="id")
     *   },
     *   inverseJoinColumns={
     *     @ORM\JoinColumn(name="role_id", referencedColumnName="id")
     *   }
     *  )
     */
    private $role;

    public function __construct()
    {
        //$this->repository = $repository;
        $this->role = new ArrayCollection();
        //$this->roles = new Role();
    }

    /**
     * Add userRoles
     *
     * @param \App\Entity\Role $roles
     * @return User
     */
    public function addRoles(\App\Entity\Role $role)
    {
        $this->role[] = $role;

        return $this;
    }


    /**
     * Remove userRoles
     *
     * @param \App\Entity\Role $roles
     */
    public function removeRoles(\App\Entity\Role $role)
    {
        $this->role->removeElement($role);
    }

    /**
     * Get Role
     */
    public function getRoles() : array //Role return
    {
        //$role = $this->repository->find($this->getId());
        //$role = $role->getName();
        $role = $this->role->toArray();

        //$roles = ['ROLE_ADMIN'];
        //$role = $this->serialize($role);
        var_dump($role);
        //$role = $role[0]['name'];

        if (empty($role)) {
            $role[] = ['ROLE_ADMIN'];
        }
        return array_unique($role);
    }

    public function setRoles($role): self
    {
        //$this->roles = $roles;
        if (is_array($role)) {
            $this->role = $role;
        } else {
            $this->role->clear();
            $this->role->add($role);
        }
        return $this;
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    /**
     * A visual identifier that represents this user.
     *
     * @see UserInterface
     */
    public function getUsername(): string
    {
        return (string)$this->username;
    }

    public function setUsername(string $username): self
    {
        $this->username = $username;

        return $this;
    }




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

    public function setPassword(string $password): self
    {
        $this->password = $password;

        return $this;
    }

    /**
     * @see UserInterface
     */
    public function getSalt()
    {
        // not needed when using the "bcrypt" algorithm in security.yaml
    }

    /**
     * @see UserInterface
     */
    public function eraseCredentials()
    {
        // If you store any temporary, sensitive data on the user, clear it here
        // $this->plainPassword = null;
    }

    public function getIsActive(): ?bool
    {
        return $this->isActive;
    }

    public function setIsActive(bool $isActive): self
    {
        $this->isActive = $isActive;

        return $this;
    }

    public function getToken(): ?string
    {
        return $this->token;
    }

    public function setToken(string $token): self
    {
        $this->token = $token;

        return $this;
    }

    public function getExpiresAt(): ?\DateTimeInterface
    {
        return $this->expiresAt;
    }

    public function setExpiresAt(\DateTimeInterface $expiresAt): self
    {
        $this->expiresAt = $expiresAt;

        return $this;
    }

    public function isExpired(): bool
    {
        return $this->getExpiresAt() <= new \DateTime();
    }

    public function createToken()
    {
        return substr(str_replace(['+', '/'], ['-', '_'], base64_encode(random_bytes(50))), 0, 63);
    }


    /**
     * String representation of object
     * @link https://php.net/manual/en/serializable.serialize.php
     * @return string the string representation of the object or null
     * Transform object to string
     */
    public function serialize()
    {
        return serialize([
            $this->id,
            $this->username,
            $this->password,
            $this->isActive,
            $this->token,
            $this->expiresAt
        ]);
    }

    /**
     * @param string $serialized
     * Transform string to object
     */
    public function unserialize($serialized)
    {
        list(
            $this->id,
            $this->username,
            $this->password,
            $this->isActive,
            $this->token,
            $this->expiresAt
            ) = unserialize($serialized, ['allowed_classes' => false]);
    }

}

这里是 Role.php 的代码

class Role implements \Serializable
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

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

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

    /**
     * @ORM\ManyToMany(targetEntity="User", mappedBy="roles")
     */
    private $users;

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

    public function getUsers()
    {
        return $this->users;
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getRole(): ?string
    {
        return $this->role;
    }

    public function setRole($role)
    {
        $this->role = $role;

        return $this;
    }

    public function getDescription(): ?string
    {
        return $this->description;
    }

    public function setDescription(string $description): self
    {
        $this->description = $description;

        return $this;
    }

    /*
    * methods for RoleInterface
    */
    /*public function getRoles()
    {
        return $this->getRole();
    }*/

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

        return $this;
    }

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



    /**
     * String representation of object
     * @link https://php.net/manual/en/serializable.serialize.php
     * @return string the string representation of the object or null
     * Transform object to string
     */
    public function serialize()
    {
        return serialize([
            $this->id,
            $this->role,
            $this->description
        ]);
    }

    /**
     * @param string $serialized
     * Transform string to object
     */
    public function unserialize($serialized)
    {
        list(
            $this->id,
            $this->role,
            $this->description
            ) = unserialize($serialized, ['allowed_classes' => false]);
    }
}

然后在我的控制器中我做了一个 findAll

/**
* @Route("/admin/user", name="admin_user_index")
* @return \Symfony\Component\HttpFoundation\Response
*/
public function listUser(UserRepository $user)
{
return $this->render('admin/security_user/list_user.html.twig', ['user' => $user->findAll()]);
}

var_dump($role)

/var/www/api/symfony/src/Entity/User.php:108:
array (size=1)
  0 => 
    object(App\Entity\Role)[423]
      private 'id' => int 2
      private 'role' => string '['ROLE_ADMIN']' (length=14)
      private 'description' => string 'administrateur' (length=14)
      private 'users' => 
        object(Doctrine\ORM\PersistentCollection)[425]
          private 'snapshot' => 
            array (size=0)
              ...
          private 'owner' => 
            &object(App\Entity\Role)[423]
          private 'association' => 
            array (size=16)
              ...
          private 'em' => 
            object(Doctrine\ORM\EntityManager)[205]
              ...
          private 'backRefFieldName' => string 'roles' (length=5)
          private 'typeClass' => 
            object(Doctrine\ORM\Mapping\ClassMetadata)[262]
              ...
          private 'isDirty' => boolean false
          protected 'collection' => 
            object(Doctrine\Common\Collections\ArrayCollection)[426]
              ...
          protected 'initialized' => boolean false

这是用户列表代码:

{% extends '/admin/base_admin.html.twig' %}

{% block style %}
    <style>
        h1#titlelist{
            float: left;
        }
        button#edit {
            float: right;
        }
        button#create{
            float: right;
            margin-left: 15px;
        }
    </style>
{% endblock %}

{% block logout %}
    <a style="color: grey" href="{{ path('security_logout') }}">Deconnexion</a>
{% endblock %}

{% block body %}
    <br /><br />
    <h1 id="titlelist" class="h3 mb-3 font-weight-normal">Liste des utilisateurs</h1>
    {% for message in app.flashes('success') %}
        <div class="alert alert-success">
            {{ message }}
        </div>
    {% endfor %}
    <a href="{{ path('admin_index') }}">
        <button id="create" class="btn btn-lg btn-primary">
            Annuler
        </button>
    </a>
    <a href="{{ path('admin_user_create') }}">
        <button id="create" class="btn btn-lg btn-primary">
            Ajouter
        </button>
    </a>

    <br />
    <br />
    <br />
    <TABLE  class="table table-striped">
        <thead>
        <TR>
            <TH>ID</TH>
            <TH>Utilisateur</TH>
            <TH>Password</TH>
            <TH>Rôles</TH>
            <TH>Actif</TH>
            <TH>Editer</TH>
        </TR>
        </thead>
        <tbody>
        {% for list in user %}
            <TR>
                <TD>{{ list.id }}</TD>
                <TD>{{ list.username }}</TD>
                <TD>{{ list.password }}</TD>
                <TD>
                    {% for role in list.roles %}
                        {{ role.name }},
                    {% endfor %}
                </TD>
                <TD>{{ list.isActive }}</TD>

                <TD>
                    <a href="{{ path('admin_user_edit', {id: list.id}) }}" class="btn btn-primary">Editer</a>
                    <form method="post" action="{{ path('admin_user_delete', {id: list.id}) }}" style="display: inline-block"
                          onsubmit="return confirm('Voulez-vous vraiment supprimer l\'utilisateur ?')">
                        <input type="hidden" name="_method" value="DELETE">
                        <input type="hidden" name="_token" value="{{ csrf_token('delete' ~ list.id) }}">
                        <button class="btn btn-primary">Supprimer</button>
                    </form>
                </TD>
            </TR>
        {% endfor %}
        </tbody>
    </TABLE>
{% endblock %}

我想检索角色表中的角色存储。

如果有哪位能赐教,先谢谢了。

【问题讨论】:

  • 代码的哪一部分抛出警告?
  • 用户类中的getRoles
  • 您可以dump($this-&gt;role) 并将输出添加到您的问题中吗?
  • 很好,我加了它
  • 您确定$this-&gt;role-&gt;toArray();正在发出警告吗?您的 var_dump 在此调用之后,所以我希望稍后会出现警告?你有没有机会得到堆栈跟踪?

标签: php symfony doctrine


【解决方案1】:

没有什么帮助,这里是解决方案

/**
 * Get Role
 * @return array
 */
public function getRoles() : array
{
    $roles = $this->roles;
    $name = $roles;
    $name = $name->first()->getName();

    $roles = $roles->first()->getRole();
    $roles = [$roles, $name];

    //dump($roles);
    if (empty($roles)){
        $roles = ['ROLE_USER'];
    }
    return $roles;
}

还有树枝的代码

{% for list in user %}
        <TR>

            <TD>{{ list.id }}</TD>
            <TD>{{ list.username }}</TD>
            <TD>{{ list.password }}</TD>
            <TD>{{ list.roles[1] }}</TD>
            <TD>{{ list.isActive }}</TD>

            <TD>
                <a href="{{ path('admin_user_edit', {id: list.id}) }}" class="btn btn-primary">Editer</a>
                <form method="post" action="{{ path('admin_user_delete', {id: list.id}) }}" style="display: inline-block"
                      onsubmit="return confirm('Voulez-vous vraiment supprimer l\'utilisateur ?')">
                    <input type="hidden" name="_method" value="DELETE">
                    <input type="hidden" name="_token" value="{{ csrf_token('delete' ~ list.id) }}">
                    <button class="btn btn-primary">Supprimer</button>
                </form>
            </TD>
        </TR>
    {% endfor %}

【讨论】:

    【解决方案2】:

    例如对于那些想要为模块添加多个角色的人

    public function getRoles() : array //Role return
        {
            $role = [];
            $name = [];
            $roles = $this->roles;
    
            $tab = $roles->toArray();
            dump($tab);
            $longTab = count($tab);
    
            for ($i = 0; $i < $longTab; $i++){
                $role[] = $roles->get($i)->getRole();
                $name[] = $roles->get($i)->getName();
            }
    
            $role = [$role, $name];
    
            if (empty($roles)){
                $role = ['ROLE_USER'];
            }
            return $role;
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-24
      • 1970-01-01
      • 2022-07-24
      • 1970-01-01
      • 1970-01-01
      • 2015-10-01
      • 2013-05-10
      • 2016-08-04
      相关资源
      最近更新 更多