Symfony2 用户有教义

Posted

技术标签:

【中文标题】Symfony2 用户有教义【英文标题】:Symfony2 users with doctrine 【发布时间】:2012-01-23 14:07:20 【问题描述】:

我正在寻找获取用户创建的内容的最佳做法。 我有 $user 对象形式'security.context',我需要通过一些 $record_id 获取该用户创建的单个记录,

那我该怎么办?

$this->getDoctrine()->getRepository('AcmeRecordBundle:Record')
->findOneBy(array( 'id' => $record_id, 'user' => $user->getId() ));

这对我来说看起来不太好,因为我还有很多信息需要获取以寻找用户(不要让其他用户尝试通过某个 id 获取它)。对于任何内容(个人照片,其他一些私人内容)我必须通过 'user' => $user->getId() ?

或者最好使用所有这些功能创建 UserRepository? getRecordById($id)、getPhotoById($id)、getPrivateInformationById($id) 等

我在 Rails 上工作了一点,在那里我能够定义 current_user 方法

def current_user
  return @current_user if defined?(@current_user)
  # ....
end

然后把它当作

current_account.records.find(params[:id])

有没有可能让它像 Doctrine2 和 Symfony2 一样工作?喜欢

$user->getRecords()->find($recordId)

【问题讨论】:

【参考方案1】:

在任何情况下,您都必须指定 user 传递给您的函数,该函数处理自定义存储库中的获取逻辑,如 Doctrine 的 official documentation 中指定的那样。

【讨论】:

不像我希望的那样优雅,但由于实体实际上并不了解数据库,因此自定义存储库是可行的方法。【参考方案2】:

当然,您必须为“WHERE” sql 子句传递用户 id,仅仅因为 ROR 在幕后神奇地做到了(这是 imo 的一个非常糟糕的做法),并不意味着它没有在全部。

至于其他问题,两种解决方案都可以:

    从特定存储库中获取数据,并传递对象 ID + 用户 ID,或者: 创建内部获取用户 ID 并将其放入查询的方法

请记住,用户的 id 在请求期间只获取一次,所以不要担心从安全上下文中获取太多。

【讨论】:

所以你建议的解决方案都是一样的我在想 - 每次都传递 $user->getId() ,或者为每个选择在一些 UserRepository 中创建单独的方法? 在存储库中的单独方法中,您仍然必须将用户的 id 传递给查询。否则就无法做到【参考方案3】:

您需要实现 Symfony 2 ACL 功能。这允许您指定“域对象”(DB 类的单个实例)的所有权以及用户对域对象具有何种访问权限。然后,您可以使用例如 JMSSecurityExtraBundle 并实现基于对象所有权的访问控制。实施后,您的用户将无法修改彼此的对象(通过参数操作),并且您在查询中不需要额外的参数。

以下是一些相关链接:

    Access Control Lists (ACLs) JMSSecurityExtraBundle

【讨论】:

【参考方案4】:

我个人发现存储库类在中小型应用程序中有点膨胀。不确定你的方法是什么,但我读过的大部分内容(以及我在最近的 Doctrine 2 应用程序中所做的)都是有一个操纵实体的“服务”层。这是 D2 中的 b/c,在实体中实现保存/删除等破坏了系统的目的,即减轻实体的持久性知识并将它们视为普通旧 php 对象 (TM) ;)

您的查询让我觉得奇怪的是传递主键 ID 和用户 ID 来获取用户。在我看来,用户表的 pk 将是用户 id,或者至少如果用户 id 不是 pk (不知道为什么会这样),您应该能够仅获取记录PK。这是在我的系统中获取用户对象的方法

/**
 * @param int $iId user id
 *
 * @return object
 */
public function fetch($iId)

    return $this->_oEm->find('AwesomeApp\Entity\User', $iId);

您正在寻找的当前用户类型的功能应该与您应用程序中的会话相关。在 zf 中,我创建了一个会话处理程序,它将原则用户对象保存到会话存储中,然后当读取会话时,我将用户对象重新附加到实体管理器。您可能想在 sf 中做类似的事情,然后“getCurrentUser”调用将返回与从数据库中提取相同的用户对象。在会话中存储一个用户对象可以避免在每次页面加载时为它返回数据库,例如,如果您只是将用户 ID 存储在会话中。

归根结底,您“应该”将复杂的选择查询放入存储库,但在最佳实践方面,这显然是由用户自行决定的。在这种情况下,当您只有一个 pk 时,我会说编写存储库类是没有意义的。

【讨论】:

以上是关于Symfony2 用户有教义的主要内容,如果未能解决你的问题,请参考以下文章

Symfony2 教义关联映射错误处理

Symfony2 - 奏鸣曲 Datagrid 过滤器操作符转换为教义_orm_class 字段失败

Symfony 2 教义左连接

教义自定义数据类型

多对多的 Symfony2 DQL 更新查询

Symfony2 & Doctrine:创建自定义 SQL 查询