最近,我终于开始将注意力从D7转移到D8,并将网站转换为D8。在D7中,我将帐户对象键入\ stdClass,因为它们不是任何类的成员。但是,在D8中,它们现在是User类的成员。
就是说,我在网上的某些代码中发现人们在键入提示,例如Drupal \ Core \ Session \ AccountInterface,在其他地方则键入了Drupal \ user \ UserInterface。我们应该如何确定要使用哪种类型的类型提示,两种对象之间的区别是什么?
最近,我终于开始将注意力从D7转移到D8,并将网站转换为D8。在D7中,我将帐户对象键入\ stdClass,因为它们不是任何类的成员。但是,在D8中,它们现在是User类的成员。
就是说,我在网上的某些代码中发现人们在键入提示,例如Drupal \ Core \ Session \ AccountInterface,在其他地方则键入了Drupal \ user \ UserInterface。我们应该如何确定要使用哪种类型的类型提示,两种对象之间的区别是什么?
Answers:
UserInterface
延伸ContentEntityInterface
,EntityChangedInterface
和AccountInterface
。这意味着实现对象的对象UserInterface
需要有一些方法,而实现对象的对象AccountInterface
则不需要。例如,有UserInterface::hasRole()
,但AccountInterface::getRoles()
;在第一种情况下,有一个帮助程序方法可以检查对象是否具有特定角色,而在第二种情况下,您需要为此编写代码,并使用来获取角色列表AccountInterface::getRoles()
。
文档中给出了应该使用的提示。例如,由于hook_user_logout()
实现\Drupal\Core\Session\AccountProxyInterface
了从返回的对象,因此获取了一个实现的对象Drupal::currentUser()
。参见user_logout()
,函数调用hook_user_logout()
。
$user = \Drupal::currentUser();
\Drupal::logger('user')->notice('Session closed for %name.', array('%name' => $user->getAccountName()));
\Drupal::moduleHandler()->invokeAll('user_logout', array($user));
有时,钩子文档没有显示特定提示,例如hook_user_login()
。在这种情况下,可以帮助查看该挂钩的实现中使用了哪个提示,例如system_user_login()
,哪个挂钩UserInterface
用作其参数的提示。
如果您不确定传递给函数的对象(包括钩子)所实现的接口正确,请使用最通用的接口作为提示。在您描述的情况下,该值为AccountInterface
。
检查文档AccountInterface
:
定义一个具有用户ID,角色并且可以具有会话数据的对象。该接口由全局会话和用户实体共同实现
它Session
之所以在名称空间中是有原因的-它表示可以包含会话数据的内容。
该ContentEntityInterface
和EntityChangedInterface
接口扩展的UserInterface
告诉你,它代表一个不同的概念:
内容实体将字段用于其所有实体属性,并且可以翻译和修订,而可以按实体类型启用翻译和修订。
定义用于实体更改时间戳跟踪的接口。
此数据对于更精确的缓存无效化(尤其是在客户端)和并发编辑锁定很有用。
A UserInterface
代表完整的Drupal用户帐户,其中可以包含修订,字段,翻译等。
我无法告诉您哪个更适合您的用例,但我鼓励您考虑以下哪个接口最适合您正在编写的代码。
我的直觉告诉我,您将使用AccountInterface
最少“已登录”的内容(例如,登录用户,在线用户列表,通过SSO登录的人)以及除此以外UserInterface
的其他内容(例如,用户个人资料,关联的作者,实时数据,这是我们在Drupal中所做的大多数事情)。