2

假设我有三个表:usersbooksusers_books

在我的一个观点中,我想显示当前用户可以访问的所有书籍的列表。如果 中存在与用户和书籍匹配的行,则用户有权访问书籍users_books

我有(至少)两种方法可以做到这一点:

  • 在我在模型fetchAll()中的方法中,在表上执行某种类型的操作。booksjoinusers_books
  • 在 Acl 插件中,首先从每本书中创建一个资源。然后,从每个用户中创建一个角色。接下来,根据表允许或拒绝用户访问每个资源users_books。最后,在模型的fetchAll()方法中books,调用isAllowed()我们找到的每一本书,使用当前用户作为角色。

我认为最后一个选项是最好的,因为这样我就可以在我的应用程序的其他地方使用 Acl。这将消除执行重复访问检查的需要。

你有什么建议?

4

2 回答 2

1

我会将其全部推送到数据库中:

  1. 通过 JOIN 在数据库中执行此操作将比在 PHP 中过滤内容要快得多。
  2. 在数据库中执行此操作可以让您正确地对事物进行分页,而无需跳过诸如获取比您需要的更多数据(如果最终抛出太多数据,则获取更多数据)这样的麻烦。

我可以想到两种可以用来管理 ACL 的广泛策略。

您可以在数据库中使用类似这样的单个表设置显式 ACL:

  • id: 有问题的事物(书、图片……)的 id。
  • id_type: id 来自的类型或表。
  • user: 可以看东西的用户。

( id, id_type) 对为您提供了一个伪 FK,您可以使用它来检查数据库的完整性,并且id_type可以用于选择一个类以提供必要的胶水来交互 ACL 的特定于类型的部分并将 SQL 片段添加到查询以正确连接 ACL 表。

或者,您可以使用命名约定将 ACL sidecar 表附加到每个表而不需要 ACL。对于 table t,您可以有一个t_acl包含以下列的表:

  • id:事物的 id t(具有真实的外键以确保完整性)。
  • user: 用户可以看东西。

然后,您可以拥有一个 ACL 类,该类可以根据基表名称调整您的 SQL。

第一种方法的主要优点是您对所有内容都有一个 ACL 存储,因此很容易回答诸如“用户 X 可以看什么?”之类的问题。第二种方法的主要优点是您可以拥有真正的引用完整性和更少的代码(通过命名约定)将它们粘合在一起。

希望以上内容对您的思考有所帮助。

于 2011-05-24T22:17:44.527 回答
1

我会通过在存储库类中创建一个查找器方法,使用 getBooksByUser(User $user) 之类的添加方法来返回书籍对象的集合,从而将您的数据库访问代码与您的模型分开。

不完全确定您需要所描述的 ACL。我可能错了。

于 2011-05-24T22:24:45.103 回答