是否有一个获取当前用户对象的函数,该函数避免访问全局变量?


29

我一直都这样global $user;。但是,我似乎还记得在一个贡献模块中看到了一些返回当前用户对象而不使用global的东西$user

这样的功能是否存在于Drupal 7内核中,或者实际上是建议使用全局变量来获取当前用户对象的实际方法?


你为什么不只使用全局$ user?
saadlulu 2012年

5
如果稍后在代码中不小心更改了全局$ user,则可能会导致潜在的有害行为。
亚历克斯·韦伯

Answers:


22

您可以使用的功能是user_uid_optional_load() ; 不带参数的情况下,它将返回当前登录用户的用户对象。它仍然使用global $user,并从数据库中加载完整的对象,包括与用户关联的字段,但是它避免了代码意外更改全局变量的内容的情况$user,因为未从代码中引用全局变量。

function user_uid_optional_load($uid = NULL) {
  if (!isset($uid)) {
    $uid = $GLOBALS['user']->uid;
  }
  return user_load($uid);
}

如果不需要完整的对象,则可以使用其他答案中已报告的代码。如果要确保不更改全局对象,可以将全局变量复制到局部变量中,如以下代码片段所示。

$account = $GLOBALS['user'];
// Use $account.

在Drupal 8中,您只需使用static方法\Drupal::currentUser()即可获得与Drupal 7等效的方法,$GLOBALS['user']\Drupal\user\Entity\User::load(\Drupal::currentUser()->id())获得具有其所有字段API字段的完全加载的对象。不再存在覆盖所有后果的全局变量的风险。
如果您需要使用匿名用户(例如,匿名用户)切换当前用户,则在Drupal 8中使用的代码如下。

$accountSwitcher = Drupal::service('account_switcher');
$accountSwitcher->switchTo(new Drupal\Core\Session\AnonymousUserSession());

// Your code here.

// Eventually, restore the user account.
$accountSwitcher->switchBack();

20

$user对象被声明为全局变量,因此,如果要访问它,则需要使用以下任一方法:

global $user;
$account = $user;

要么

$account = $GLOBALS['user'];

在Drupal中似乎实际上没有标准的方法来执行此操作。例如,如果您查看节点模块,该node_access_grants()函数将使用以下代码:

if (!isset($account)) {
  $account = $GLOBALS['user'];
}

而文件中的下一个函数则node_access_view_all_nodes()使用以下代码:

global $user;
if (!$account) {
  $account = $user;
}

简单的答案是两者都是有效的。我认为使用的目的$GLOBALS是使名为的变量$user在当前范围内不活动,因此不能被粗心的调用所覆盖,例如,$user = NULL进一步调用该函数。不过,我不是100%。


多数民众赞成在您的最后声明中我所知道并同意的。
saadlulu 2012年

1
global $user;通常在变量被多次$GLOBALS['user']引用时使用,并且在功能代码中仅使用一次时使用。Drupal代码在这方面不是恒定的。在某些情况下global $user;有必要:当将用户对象传递给,drupal_alter()以允许第三方模块更改当前活动的用户时(Drupal中实际上并未实现)。
kiamlaluno

1
global $user与user_uid_optional_load()不同。第一个是从会话中加载的,不是完全加载的用户对象(带有字段和挂钩),而第二个是。因此,我不会将此列为选项。该功能的目的是用于命名菜单参数,该菜单参数可以选择接受用户ID,否则默认为当前用户。/ user / uid是主要示例。
贝迪尔(Berdir)2012年

@Berdir谢谢,我不知道global $user默认情况下未完全加载该文件(尽管这很有意义,并解释了我之前想知道的几件事)。我把它排除在答案之外。
克莱夫(Clive)

感谢Clive,我想使用全局$ user并将其复制到$ account变量可能是最安全的选择。我实际上是在寻找user_uid_optional_load():)
Alex

3

就像在函数范围内声明(现有)全局$ user对象一样简单:

global $user;

请记住,对此对象所做的更改会全局影响它,即

global $user;
$user->uid = 1;

刚刚给当前用户uid 1特权。这就是为什么通常将$ user分配给$ account以便在不影响当前登录用户的情况下修改数据的原因(当然,除非您要这样做)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.