php - Symfony 按角色查找用户(JSON 数组 Doctrine 属性)

标签 php symfony doctrine-orm

我正在做一个小项目,其中我有一个具有由数组组成的角色属性的实体。
我想要做的是,在某个 Controller 中,找到一个在角色数组中具有特定角色的现有实体。
我正在尝试使用 findOneBy()方法,但我似乎无法使其工作,即使存在我试图找到的具有特定角色的实体,它也总是返回 null。
这是我的实体及其属性:

/**
 * @ORM\Entity(repositoryClass=SalarieRepository::class)
 */
class Salarie
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

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

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

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

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

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

    /**
     * @ORM\Column(type="json")
     */
    private $roles = [];

    // Getters & setters
}
这是我尝试过的示例 findOneBy()在 Controller 内部,返回 null :
$rolecheck = $this->salarieRepository->findOneBy(["roles" => ["ROLE_RESPONSABLE_RH"]]);
当我尝试使用不是数组的实体的任何其他属性时,它运行良好,如果我这样做:
$rolecheck = $this->salarieRepository->findOneBy(["nom" => "test"]);
dd($rolecheck);
它将显示正确的实体:
SalarieController.php on line 47:
App\Entity\Salarie {#1501 ▼
  -id: 6
  -nom: "test"
  -prenom: "test"
  -email: "test@test.test"
  -telephone: null
  -service: "Graphisme"
  -roles: array:3 [▼
    0 => "ROLE_RESPONSABLE_RH"
    1 => "ROLE_RESPONSABLE_SERVICE"
    2 => "ROLE_SALARIE"
  ]
}
我们还可以看到它确实有角色数组,其中包含我试图在其中找到的角色。
关于我如何尝试找到具有特定角色的实体的任何线索 "ROLE_RESPONSABLE_RH" ?

最佳答案

您的 $roles属性类型为 json ,这意味着它在您的数据库中存储为:

["ROLE_RESPONSABLE_RH", "ROLE_RESPONSABLE_SERVICE", "ROLE_SALARIE"]
您需要询问 Doctrine JSON 数组是否包含角色,但您不能使用 findOneBy() 来做到这一点。方法。
当您遇到 ORM 限制时,您可以使用 Native Query with ResultSetMapping .它允许您使用 DBMS 的特定功能编写纯 SQL 查询,但仍然可以获取实体对象。
在您的 SalarieRepository 中创建此方法类(class):
public function findByRole(string $role): array
{
    // The ResultSetMapping maps the SQL result to entities
    $rsm = $this->createResultSetMappingBuilder('s');

    $rawQuery = sprintf(
        'SELECT %s
        FROM salarie s 
        WHERE /* your WHERE clause depending on the DBMS */',
        $rsm->generateSelectClause()
    );

    $query = $this->getEntityManager()->createNativeQuery($rawQuery, $rsm);
    $query->setParameter('role', $role);
    return $query->getResult();
}
然后你需要替换我放在WHERE中的评论子句取决于 DBMS:
MariaDB - JSON_SEARCH() :
SELECT %s
FROM salarie s 
WHERE JSON_SEARCH(s.roles, 'one', :role) IS NOT NULL
MySQL - JSON_CONTAINS() :
SELECT %s
FROM salarie s 
WHERE JSON_CONTAINS(s.roles, :role, '$')

Warning: you must enclose the role parameter with double quotes:

$query->setParameter('role', sprintf('"%s"', $role));

PostgreSQL - jsonb escaped "?" operator :
SELECT %s
FROM salarie s 
WHERE s.roles::jsonb ?? :role

Warning: will require PHP 7.4+. See the RFC

关于php - Symfony 按角色查找用户(JSON 数组 Doctrine 属性),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67725384/

相关文章:

php - 需要一种有选择地杀死休眠的 php 进程的方法

php - 为什么mysql不存储 "#"字符后的数据?

php - 有学说回滚事件吗?即对有回滚的更改列表中的实体执行操作

symfony - getUser() 方法在 Controller 构造函数中不起作用

php - ZF + 学说 2 : Heavy model classes or Lightweight model + Service layer?

zend-framework - Doctrine2 大集合

php - 为什么 laravel 5.7 基本路由重定向到 404?

php - 如何在 PHP 中检查我是否处于静态上下文中(或不在)?

git - 我能看到最后部署在 Capistrano 的哪个分支吗

php - 学说迁移 : How to avoid SQL errors in the postUp step?