如何使用Symfony ACL过滤我的Doctrine查询

时间:2013-02-13 16:49:39

标签: php symfony doctrine-orm doctrine acl

Symfony ACL允许我授予对实体的访问权限,然后进行检查:

if (false === $securityContext->isGranted('EDIT', $comment)) {
    throw new AccessDeniedException();
}

但是,如果我在数据库中有数千个实体,并且用户只能访问其中的10个实体,我不想在内存中加载所有实体并为它们加水。

如何只过滤用户有权访问的实体(在SQL级别),我可以做一个简单的“SELECT * FROM X”吗?

3 个答案:

答案 0 :(得分:3)

那就是:不可能

在过去的一年里,我一直在研究一种可以直接过滤数据库查询的替代ACL系统。

我的公司最近同意开源,所以这里是:http://myclabs.github.io/ACL/

答案 1 :(得分:0)

正如@gregor在前面的讨论中指出的那样,

在第一个查询中,获取用户有权访问的所有object_identity_ids(针对特定实体/类X)的列表(带有自定义查询)。

然后,在查询实体/类X的对象列表时,在查询中添加“IN(object_identity_ids)”

Matthieu,我对回答更多猜想感到不满意(因为我的推测没有为对话添加任何有价值的内容)。所以我在这种方法上做了一些基准测试(Digital Ocean 5 $ / mo VPS)。

Benchmark

正如预期的那样,使用IN数组方法时,表大小无关紧要。但是一个大阵列确实让事情失去控制。

那么,Join approach vs IN array approach

当数组大小很大时,JOIN确实更好。但是,假设我们不应该考虑表格大小。事实证明,在实践中IN数组更快 - 除非有一个大的对象表,并且acl条目几乎涵盖了每个对象(参见链接的问题)。

我在一个单独的问题上扩展了我的推理。请参阅When using Symfony's ACL, is it better to use a JOIN query or an IN array query?

答案 2 :(得分:-1)

您可以查看Doctrine filters。这样你可以扩展所有查询。我还没有这样做,并且记录了一些限制。但也许它会帮助你。您将找到ACL数据库表here的描述。

<强>更新

每个过滤器都将返回一个字符串,所有这些字符串将被添加到SQL查询中,如下所示:

SELECT ... FROM ... WHERE ... AND (<result of filter 1> AND <result of filter 2> ...)

表别名也传递给filter方法。所以我认为你可以在这里添加子查询来过滤你的实体。