Existe-t-il une fonction pour obtenir l'objet utilisateur actuel qui évite d'accéder à la variable globale?


29

Je suis toujours allé avec ça global $user;. Cependant, je me souviens avoir vu quelque chose dans un module contribué qui renvoyait l'objet utilisateur actuel sans utiliser le global $user.

Une telle fonction existe-t-elle dans le noyau Drupal 7, ou utilise-t-elle la variable globale de facto pour obtenir l'objet utilisateur actuel?


pourquoi ne voudriez-vous pas utiliser global $ user?
saadlulu

5
L'utilisation de $ global user peut créer un comportement indésirable potentiel s'il est modifié sans précaution plus tard dans le code.
Alex Weber

Réponses:


22

La fonction que vous pourriez utiliser est user_uid_optional_load () ; sans arguments, il renvoie l'objet utilisateur pour l'utilisateur actuellement connecté. Il utilise toujours le global $useret charge l'objet complet à partir de la base de données, y compris les champs associés aux utilisateurs, mais il évite que votre code modifie accidentellement le contenu de la variable globale $user, car il n'est pas référencé à partir de votre code.

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

Si vous n'avez pas besoin de l'objet complet, vous pouvez utiliser le code déjà signalé dans les autres réponses. Si vous voulez être sûr de ne pas modifier l'objet global, vous pouvez copier la variable globale dans une variable locale, comme dans l'extrait de code suivant.

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

Dans Drupal 8, vous utilisez simplement la méthode statique \Drupal::currentUser()pour obtenir l'équivalent de Drupal 7 $GLOBALS['user']et \Drupal\user\Entity\User::load(\Drupal::currentUser()->id())pour obtenir un objet entièrement chargé avec tous ses champs API de champ. Il n'y a plus de risque de surcharger une variable globale avec toutes les conséquences.
Dans le cas où vous devez changer l'utilisateur actuel avec, par exemple, l'utilisateur anonyme, le code que vous utilisez dans Drupal 8 est le suivant.

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

// Your code here.

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

20

L' $userobjet est déclaré comme une variable globale, donc si vous voulez y accéder, vous devez utiliser soit:

global $user;
$account = $user;

ou

$account = $GLOBALS['user'];

Il ne semble pas y avoir de méthode standard pour le faire dans Drupal. Si vous regardez le module de noeud par exemple, la node_access_grants()fonction utilise ce code:

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

Alors que la toute prochaine fonction du fichier,, node_access_view_all_nodes()utilise ceci:

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

La réponse simple est que les deux sont valides. Je pense que l'utilisation de $GLOBALSest pour que la variable nommée $userne soit pas active dans la portée actuelle et ne puisse donc pas être écrasée par un appel imprudent à, par exemple, $user = NULLplus loin dans la fonction. Mais je ne suis pas à 100% là-dessus.


c'est ce que je sais et je suis d'accord dans votre dernière déclaration.
saadlulu

1
global $user;doit être généralement utilisé lorsque la variable est référencée plusieurs fois, et $GLOBALS['user']doit être utilisée lorsqu'elle n'est utilisée qu'une seule fois dans le code de fonction; Le code Drupal n'est pas constant en cela. Il y a un cas où cela global $user;est nécessaire: lorsque l'objet utilisateur est passé à drupal_alter()pour permettre à des modules tiers de modifier l'utilisateur actuellement actif (ce qui n'est pas réellement implémenté dans Drupal).
kiamlaluno

1
global $usern'est pas la même chose que user_uid_optional_load (). Le premier est chargé à partir de la session et n'est pas un objet utilisateur entièrement chargé (avec des champs et des hooks invoqués) tandis que le second l'est. Je n'inscrirais donc pas cela comme une option. Le but de cette fonction est d'être utilisé pour des arguments de menu nommés qui peuvent éventuellement accepter un identifiant d'utilisateur et par défaut par défaut pour l'utilisateur actuel. / user / uid est le principal exemple.
Berdir

@Berdir Merci, je ne savais pas que le global $usern'était pas complètement chargé par défaut (bien que cela ait du sens et explique quelques choses que je me demandais auparavant). Je l'ai retiré de la réponse.
Clive

Merci Clive, je suppose que l'utilisation de $ global user et sa copie dans une variable $ account est probablement l'alternative la plus sûre. Je cherchais en fait user_uid_optional_load () cependant :)
Alex Weber

3

C'est aussi simple que de déclarer l'objet global $ user (existant) dans le cadre de votre fonction:

global $user;

Gardez à l'esprit que les modifications apportées à cet objet l'affectent globalement, c'est-à-dire

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

vient de donner à l'utilisateur actuel les privilèges uid 1. C'est pourquoi généralement $ user est affecté à $ account afin que les données puissent être bricolées sans affecter réellement l'utilisateur actuellement connecté (sauf si, bien sûr, vous le vouliez).

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.