Esiste una funzione per ottenere l'oggetto utente corrente che evita l'accesso alla variabile globale?


29

Sono sempre andato con questo global $user;. Tuttavia, mi sembra di ricordare di aver visto qualcosa in un modulo contribuito che ha restituito l'oggetto utente corrente senza usare il globale $user.

Esiste una tale funzione nel core di Drupal 7 o sta usando la variabile globale il modo di fatto raccomandato per ottenere l'oggetto utente corrente?


perché non usi semplicemente $ user globale?
Saadlulu,

5
L'uso di $ user globale può creare un potenziale comportamento indesiderato se viene modificato con noncuranza in seguito nel codice.
Alex Weber,

Risposte:


22

La funzione che potresti usare è user_uid_optional_load () ; senza argomenti, restituisce l'oggetto utente per l'utente attualmente connesso. Utilizza ancora il globale $usere carica l'intero oggetto dal database, inclusi i campi associati agli utenti, ma evita che il codice cambi accidentalmente il contenuto della variabile globale $user, in quanto non è referenziato dal codice.

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

Se non hai bisogno dell'oggetto completo, puoi usare il codice già riportato nelle altre risposte. Se vuoi essere sicuro di non modificare l'oggetto globale, puoi copiare la variabile globale in una variabile locale, come nel frammento seguente.

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

In Drupal 8, è sufficiente utilizzare il metodo statico \Drupal::currentUser()per ottenere l'equivalente di Drupal 7 $GLOBALS['user']e \Drupal\user\Entity\User::load(\Drupal::currentUser()->id())ottenere un oggetto completamente caricato con tutti i suoi campi API dei campi. Non c'è più il rischio di scavalcare una variabile globale con tutte le conseguenze.
Nel caso in cui sia necessario cambiare l'utente corrente con, ad esempio, l'utente anonimo, il codice che si utilizza in Drupal 8 è il seguente.

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

// Your code here.

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

20

L' $useroggetto viene dichiarato come variabile globale, quindi se si desidera accedervi è necessario utilizzare:

global $user;
$account = $user;

o

$account = $GLOBALS['user'];

In realtà non sembra esserci un modo standard per farlo in Drupal. Se ad esempio si osserva il modulo nodo, la node_access_grants()funzione utilizza questo codice:

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

Considerando che la funzione successiva nel file node_access_view_all_nodes(), utilizza questa:

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

La semplice risposta è che entrambi sono validi. Penso che l'uso di $GLOBALSsia tale che la variabile denominata $usernon sia attiva nell'ambito corrente e quindi non possa essere sovrascritta da una chiamata incurante, ad esempio, $user = NULLpiù avanti nella funzione. Non ci credo al 100%.


questo è quello che so e sono d'accordo nella tua ultima affermazione.
Saadlulu,

1
global $user;dovrebbe essere generalmente usato quando la variabile è riferita più di una volta e $GLOBALS['user']dovrebbe essere usata quando è usata una sola volta nel codice funzione; Il codice Drupal non è costante in questo. C'è un caso in cui global $user;è necessario: quando l'oggetto utente viene passato drupal_alter()per consentire ai moduli di terze parti di modificare l'utente attualmente attivo (che non è qualcosa di realmente implementato in Drupal).
kiamlaluno

1
global $usernon è la stessa cosa di user_uid_optional_load (). Il primo viene caricato dalla sessione e non è un oggetto utente completamente caricato (con campi e hook richiamati) mentre il secondo lo è. Quindi non vorrei elencarlo come un'opzione. Lo scopo di quella funzione deve essere utilizzato per argomenti di menu con nome che possono facoltativamente accettare un ID utente e altrimenti essere predefiniti per l'utente corrente. / user / uid è l'esempio principale.
Berdir,

@Berdir Grazie non sapevo che non global $userfosse completamente caricato di default (anche se ha senso e spiega un paio di cose che mi ero chiesto prima). L'ho tolto dalla risposta.
Clive

Grazie Clive, suppongo che utilizzare $ user globale e copiarlo in una variabile $ account sia probabilmente l'alternativa più sicura. In realtà stavo cercando user_uid_optional_load () però :)
Alex Weber,

3

È semplice come dichiarare l'oggetto $ user globale (esistente) nell'ambito della tua funzione:

global $user;

Tieni presente che le modifiche apportate a questo oggetto lo influenzano a livello globale, vale a dire

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

ho appena concesso all'utente 1 utente privilegi. Questo è il motivo per cui in genere $ user viene assegnato a $ account in modo che i dati possano essere armeggiati senza influenzare effettivamente l'utente attualmente connesso (a meno che, naturalmente, non lo si desideri).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.