Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/230.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Symfony FOS捆绑包-如何选择具有特定角色的用户?_Symfony - Fatal编程技术网

Symfony FOS捆绑包-如何选择具有特定角色的用户?

Symfony FOS捆绑包-如何选择具有特定角色的用户?,symfony,Symfony,我正在使用FOS捆绑包,我希望从数据库中检索具有给定角色的所有用户 最好的方法是什么?如果您有此要求,并且您的用户列表将非常广泛,那么您将在性能方面遇到问题。我认为不应该将字段中的角色存储为序列化数组。您应该创建一个实体角色并与users表建立多对多关系。如果您有此要求,并且您的用户列表将非常广泛,那么您将遇到性能问题。我认为不应该将字段中的角色存储为序列化数组。您应该创建一个实体角色以及与users表的多对多关系。如果没有更好的解决方案,我想我将转到DQL查询: $query = $this-

我正在使用FOS捆绑包,我希望从数据库中检索具有给定角色的所有用户


最好的方法是什么?

如果您有此要求,并且您的用户列表将非常广泛,那么您将在性能方面遇到问题。我认为不应该将字段中的角色存储为序列化数组。您应该创建一个实体角色并与users表建立多对多关系。

如果您有此要求,并且您的用户列表将非常广泛,那么您将遇到性能问题。我认为不应该将字段中的角色存储为序列化数组。您应该创建一个实体角色以及与users表的多对多关系。

如果没有更好的解决方案,我想我将转到DQL查询:

$query = $this->getDoctrine()->getEntityManager()
            ->createQuery(
                'SELECT u FROM MyBundle:User u WHERE u.roles LIKE :role'
            )->setParameter('role', '%"ROLE_MY_ADMIN"%');

$users = $query->getResult();

好的,如果没有更好的解决方案,我想我将转到DQL查询:

$query = $this->getDoctrine()->getEntityManager()
            ->createQuery(
                'SELECT u FROM MyBundle:User u WHERE u.roles LIKE :role'
            )->setParameter('role', '%"ROLE_MY_ADMIN"%');

$users = $query->getResult();

只需将其添加到您的用户存储库中,或将
$this->\u entityName
替换为
YourUserBundle:User

/**
 * @param string $role
 *
 * @return array
 */
public function findByRole($role)
{
    $qb = $this->_em->createQueryBuilder();
    $qb->select('u')
        ->from($this->_entityName, 'u')
        ->where('u.roles LIKE :roles')
        ->setParameter('roles', '%"'.$role.'"%');

    return $qb->getQuery()->getResult();
}
如果使用FOSUser组,则应使用:

/**
 * @param string $role
 *
 * @return array
 */
public function findByRole($role)
{
    $qb = $this->_em->createQueryBuilder();
    $qb->select('u')
        ->from($this->_entityName, 'u')
        ->leftJoin('u.groups', 'g')
        ->where($qb->expr()->orX(
            $qb->expr()->like('u.roles', ':roles'),
            $qb->expr()->like('g.roles', ':roles')
        ))
        ->setParameter('roles', '%"'.$role.'"%');

    return $qb->getQuery()->getResult();
}

只需将其添加到您的用户存储库中,或将
$this->\u entityName
替换为
YourUserBundle:User

/**
 * @param string $role
 *
 * @return array
 */
public function findByRole($role)
{
    $qb = $this->_em->createQueryBuilder();
    $qb->select('u')
        ->from($this->_entityName, 'u')
        ->where('u.roles LIKE :roles')
        ->setParameter('roles', '%"'.$role.'"%');

    return $qb->getQuery()->getResult();
}
如果使用FOSUser组,则应使用:

/**
 * @param string $role
 *
 * @return array
 */
public function findByRole($role)
{
    $qb = $this->_em->createQueryBuilder();
    $qb->select('u')
        ->from($this->_entityName, 'u')
        ->leftJoin('u.groups', 'g')
        ->where($qb->expr()->orX(
            $qb->expr()->like('u.roles', ':roles'),
            $qb->expr()->like('g.roles', ':roles')
        ))
        ->setParameter('roles', '%"'.$role.'"%');

    return $qb->getQuery()->getResult();
}

正如@Tirithen所说,问题是由于角色层次结构,您将无法获得具有隐式角色的用户。但是有一种方法可以解决这个问题

Symfony安全组件提供了一个服务,为我们提供特定父角色的所有子角色。我们可以创建一个做几乎相同事情的服务,只是它为我们提供了给定子角色的所有父角色

创建新服务:

例如,在yaml中定义您的服务,并将角色层次结构注入其中:

# Provide a service that gives you all parent roles for a given role.
foo.bar.reversed_role_hierarchy:
    class: Foo\BarBundle\Role\ReversedRoleHierarchy
    arguments: ["%security.role_hierarchy.roles%"]
现在,您可以在自己的服务中使用该类了。通过调用
$injectedService->getParentRoles(['ROLE\u YOUR\u ROLE'])您将获得一个包含所有父角色的数组,该数组将导致“ROLE\u YOUR\u ROLE”权限。查询具有其中一个或多个角色的用户。。。利润

例如,使用MongoDB时,可以向用户文档存储库添加一个方法:

/**
 * Find all users with a specific role.
 */
public function fetchByRoles($roles = [])
{
    return $this->createQueryBuilder('u')
        ->field('roles')->in($roles)
        ->sort('email', 'asc');
}

我不喜欢ORM,但我相信它不会有太大的不同。

正如@Tirithen所说的,问题是由于角色层次结构,您将无法获得具有隐式角色的用户。但是有一种方法可以解决这个问题

Symfony安全组件提供了一个服务,为我们提供特定父角色的所有子角色。我们可以创建一个做几乎相同事情的服务,只是它为我们提供了给定子角色的所有父角色

创建新服务:

例如,在yaml中定义您的服务,并将角色层次结构注入其中:

# Provide a service that gives you all parent roles for a given role.
foo.bar.reversed_role_hierarchy:
    class: Foo\BarBundle\Role\ReversedRoleHierarchy
    arguments: ["%security.role_hierarchy.roles%"]
现在,您可以在自己的服务中使用该类了。通过调用
$injectedService->getParentRoles(['ROLE\u YOUR\u ROLE'])您将获得一个包含所有父角色的数组,该数组将导致“ROLE\u YOUR\u ROLE”权限。查询具有其中一个或多个角色的用户。。。利润

例如,使用MongoDB时,可以向用户文档存储库添加一个方法:

/**
 * Find all users with a specific role.
 */
public function fetchByRoles($roles = [])
{
    return $this->createQueryBuilder('u')
        ->field('roles')->in($roles)
        ->sort('email', 'asc');
}

我不喜欢ORM,但我相信它不会有太大的不同。

您可以在DQL上使用这个:

SELECT u FROM YourFavouriteBundle:User u WHERE u.roles [NOT] LIKE '%ROLE_YOUR_ROLE%'
当然,使用QueryBuilder更优雅:

// $role = 'ROLE_YOUR_ROLE';
$qb->where('u.roles [NOT] LIKE :role')
   ->setParameter('role', "%$role%");

您可以在DQL上使用此选项:

SELECT u FROM YourFavouriteBundle:User u WHERE u.roles [NOT] LIKE '%ROLE_YOUR_ROLE%'
当然,使用QueryBuilder更优雅:

// $role = 'ROLE_YOUR_ROLE';
$qb->where('u.roles [NOT] LIKE :role')
   ->setParameter('role', "%$role%");

最后我解决了它,下面是一个精确的解决方案:

public function searchUsers($formData)
{
    $em = $this->getEntityManager();
    $usersRepository = $em->getRepository('ModelBundle:User');
    $qb = $usersRepository->createQueryBuilder('r');

    foreach ($formData as $field => $value) {
        if($field == "roles"){
            $qb->andWhere(":value_$field MEMBER OF r.roles")->setParameter("value_$field", $value);
        }else{
            $qb->andWhere("r.$field = :value_$field")->setParameter("value_$field", $value);
        }
    }
    return $qb->getQuery()->getResult();
}

干杯

最后我解决了它,下面是一个精确的解决方案:

public function searchUsers($formData)
{
    $em = $this->getEntityManager();
    $usersRepository = $em->getRepository('ModelBundle:User');
    $qb = $usersRepository->createQueryBuilder('r');

    foreach ($formData as $field => $value) {
        if($field == "roles"){
            $qb->andWhere(":value_$field MEMBER OF r.roles")->setParameter("value_$field", $value);
        }else{
            $qb->andWhere("r.$field = :value_$field")->setParameter("value_$field", $value);
        }
    }
    return $qb->getQuery()->getResult();
}

干杯

如果您需要使用YAML文件中的DQL筛选器按角色筛选用户(例如在EasyAdminBundle中)


如果您需要使用YAML文件中的DQL筛选器按角色筛选用户(例如在EasyAdminBundle中)


在数据库中,角色字段是一个序列化数组,如:
a:2:{i:0;s:10:“角色管理”;i:1;s:9:“角色用户”}
方法和序列化目前在本期中讨论:在数据库中,角色字段是一个序列化数组,如:
a:2:{i:0;s:10:“角色管理”;i:1;s:9:“角色用户”}
方法和序列化目前在本期中讨论:是的,这可能是最好的解决方案,但我必须编写自己的用户管理!是的,这可能是最好的解决方案,但我必须编写自己的用户管理!此解决方案将有获取wring用户的风险,例如,如果某些用户具有角色\u ADMIN,而某些用户具有角色\u SUPER\u ADMIN,并且您运行$repository->findByRole('ADMIN'),则上述用户将匹配具有角色\u ADMIN和角色\u SUPER\u ADMIN的两个用户。除此之外,由于角色层次结构(),您将无法获得具有隐式角色的用户。我只是做了一个更正,以解决您担心的角色混淆问题。除此之外,它要求的是一个>specefic<角色,而不是一个层次结构。如果您不必对照角色层次结构进行检查,这个答案是可以的。如果你也要检查子角色,这个答案是没有用的。如果你有很多用户,这个解决方案在性能上是昂贵的。示例:#查询_时间:5.254861锁定_时间:0.000191行_发送:565行_检查:196442从用户u中选择*,其中u.roles如“%ROLE\u MANAGER%”或u.roles如“%ROLE\u ADMIN%”或u.roles如“%ROLE\u SUPER\u ADMIN%”;我必须更改setParameter上的引号以使其正常工作:
->setParameter('roles',“%.”$role.”%”
此解决方案将有获取wring用户的风险,例如,如果某些用户具有role\u ADMIN角色,而某些用户具有role\u SUPER\u ADMIN角色,而您运行$repository->findByRole('ADMIN'))以上内容将匹配具有角色_ADMIN和角色_SUPER_ADMIN的两个用户。除此之外,由于角色层次结构(),您将无法获得具有隐式角色的用户。我只是做了一个更正,以解决您担心的角色混淆问题。除此之外,它要求的是一个>specefic<角色,而不是一个层次结构