29

I've always gone with this global $user;. However, I seem to remember seeing something in a contributed module that returned the current user object without using the global $user.

Does such a function exist in Drupal 7 core, or is using the global variable the de-facto recommended way to get the current user object?

  • why wouldnt you just use global $user? – saadlulu Feb 19 '12 at 14:14
  • 5
    Using global $user can create potential unwanted behavior if it is carelessly changed later on in the code. – Alex Weber Feb 19 '12 at 19:53
22

The function you could use is user_uid_optional_load(); without arguments, it returns the user object for the currently logged-in user. It still uses the global $user, and loads the full object from the database, including the fields associated to users, but it avoids your code accidentally change the content of the global variable $user, as it is not referenced from your code.

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

If you don't need the full object, then you can use the code already reported in the other answers. If you want to be sure you don't alter the global object, you can copy the global variable into a local variable, as in the following snippet.

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

In Drupal 8, you simply use the static method \Drupal::currentUser() to get the equivalent of Drupal 7 $GLOBALS['user'] and \Drupal\user\Entity\User::load(\Drupal::currentUser()->id()) to get a fully loaded object with all its field API fields. There isn't anymore the risk of overriding a global variable with all the consequences.
In the case you need to switch the current user with, for example, the anonymous user, the code you use in Drupal 8 is the following one.

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

// Your code here.

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

The $user object is declared as a global variable, so if you want to access it you need to use either:

global $user;
$account = $user;

or

$account = $GLOBALS['user'];

There doesn't actually seem to be a standard way to do this in Drupal. If you look at the node module for example, the node_access_grants() function uses this code:

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

Whereas the very next function in the file, node_access_view_all_nodes(), uses this:

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

The simple answer is that both are valid. I think the use of $GLOBALS is so that the variable named $user is not active in the current scope and therefore can't be overwritten by a careless call to, for example, $user = NULL further on in the function. I'm not 100% on that though.

  • thats what I know and agree on in your last statement. – saadlulu Feb 19 '12 at 14:14
  • 1
    global $user; should be generally used when the variable is referred more than once, and $GLOBALS['user'] should be used when it is used only once in the function code; Drupal code is not constant in that. There is a case where global $user; is necessary: when the user object is passed to drupal_alter() for allowing third-party modules to alter the currently active user (which is not something actually implemented in Drupal). – kiamlaluno Feb 19 '12 at 16:00
  • 1
    global $user is not the same thing as user_uid_optional_load(). The first is loaded from the session and is not a fully loaded user object (with fields and hooks invoked upon) while the second is. So I would not list this as an option. The purpose of that function is to be used for named menu arguments which can optionally accept a user id and otherwise default to the current user. /user/uid is the primary example. – Berdir Feb 19 '12 at 17:04
  • @Berdir Thanks I didn't know the global $user wasn't fully loaded by default (although it makes sense and explains a couple of things I'd wondered about before). I've taken it out of the answer. – Clive Feb 19 '12 at 17:14
  • Thanks Clive, I suppose using global $user and copying it to an $account variable is probably the safest alternative. I was actually lookng for user_uid_optional_load() though :) – Alex Weber Feb 19 '12 at 19:54
3

It is as simple as declaring the (existing) global $user object within the scope of your function:

global $user;

Keep in mind that changes made to this object affect it globally, i.e.

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

just gave the current user uid 1 privileges. This is why typically $user is assigned to $account so that data can be tinkered with without actually affecting the currently logged in user (unless, of course, you wanted to).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.