The global $user object that exists on each page is not a complete user object, contrary to what one might think. The only time the user object is complete is after user_load() is called, because user_load() fires (calls) all of the hook_user() hooks, allowing modules to add whatever data they wish to the user object. Without user_load() being called, none of the module-added data for the user object will exist.

This task is to add documentation about this inconsistent and potentially misleading situation to the contrib/docs/core.php documentation.


g011um’s picture

Interestingly, with the addition of some watchdog() calls I see that hook_user() is being fired in my module during a normal request. However, any fields added to the $user object in hook_user() seem to disappear at some later point (confirmed by creating a page node that simply dumps the contents of $user).

brunodbo’s picture

Project: Documentation » Drupal core
Version: » 7.x-dev
Component: Documentation in CVS » documentation
brunodbo’s picture

Changed the component to reflect the new component categorization. See

nterbogt’s picture

I've noticed the same thing as g011um. If it's getting fired anyway, why not just write it to the global, because you're not saving any time if it's happening at some point. Either that or just don't ever run it until you need it.

jhodgdon’s picture

Component: documentation » user.module
Assigned: Chris Johnson » Unassigned
Category: task » bug

Looks like this should be documented somewhere, or perhaps fixed in the user module? Temporarily assigning to the user module to see if it should be fixed or documented.

jwilson3’s picture

I am also seeing the same situation as comment #1, It puzzles me why if hook_user() gets run anyway that it doesnt actually update the global user object. I was able to solve this in my module's hook_user() in the following way... I've documented it here in a way that you could drop this in as a completely new module called force_userload.module. Just make sure to set the weight of this module heavier than all others, so it gets run later.

 * Implementation of hook_user().
 * Ensures global $user gets completely loaded.
function force_userload_user($op, $edit, &$account, $category = NULL) {
  global $user;
  switch ($op) {
    case 'load':
      // Optionally, add/modify the $account object eg,
      // $account->custom_field = 'mystuff';
      if ($user->uid == $account->uid) {
        $user = $account;

UPDATE: this worked flawlessly on my development machine, but didnt seem to work so great on my production machine. I tried the sample code here #361471: Global $user object should be a complete entity which worked better.

ohnobinki’s picture