¿Existe una función para obtener el objeto de usuario actual que evita acceder a la variable global?

29

Siempre he ido con esto global $user;. Sin embargo, parece recordar haber visto algo en un módulo contribuido que devolvió el objeto de usuario actual sin usar el global $user.

¿Existe tal función en el núcleo de Drupal 7, o está utilizando la variable global la forma recomendada de facto para obtener el objeto de usuario actual?

Alex Weber
fuente
¿por qué no usarías global $ user?
saadlulu
55
El uso de $ user global puede crear un posible comportamiento no deseado si se cambia descuidadamente más adelante en el código.
Alex Weber

Respuestas:

22

La función que podría usar es user_uid_optional_load () ; sin argumentos, devuelve el objeto de usuario para el usuario actualmente conectado. Todavía usa el global $usery carga el objeto completo de la base de datos, incluidos los campos asociados a los usuarios, pero evita que su código cambie accidentalmente el contenido de la variable global $user, ya que no se hace referencia a él desde su código.

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

Si no necesita el objeto completo, puede usar el código que ya se informó en las otras respuestas. Si desea asegurarse de no alterar el objeto global, puede copiar la variable global en una variable local, como en el siguiente fragmento.

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

En Drupal 8, simplemente usa el método estático \Drupal::currentUser()para obtener el equivalente de Drupal 7 $GLOBALS['user']y \Drupal\user\Entity\User::load(\Drupal::currentUser()->id())obtener un objeto completamente cargado con todos sus campos API de campo. Ya no existe el riesgo de anular una variable global con todas las consecuencias.
En el caso de que necesite cambiar el usuario actual con, por ejemplo, el usuario anónimo, el código que usa en Drupal 8 es el siguiente.

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

// Your code here.

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

El $userobjeto se declara como una variable global, por lo que si desea acceder a él, debe usar:

global $user;
$account = $user;

o

$account = $GLOBALS['user'];

En realidad, no parece haber una forma estándar de hacer esto en Drupal. Si observa el módulo de nodo, por ejemplo, la node_access_grants()función usa este código:

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

Mientras que la siguiente función en el archivo node_access_view_all_nodes(), usa esto:

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

La respuesta simple es que ambos son válidos. Creo que el uso de $GLOBALSes para que la variable nombrada $userno esté activa en el alcance actual y, por lo tanto, no se pueda sobrescribir con una llamada descuidada a, por ejemplo, $user = NULLmás adelante en la función. Aunque no estoy al 100% en eso.

Clive
fuente
eso es lo que sé y estoy de acuerdo en su última declaración.
saadlulu
1
global $user;debe usarse generalmente cuando la variable se refiere más de una vez, y $GLOBALS['user']debe usarse cuando se usa solo una vez en el código de función; El código Drupal no es constante en eso. Hay un caso en el que global $user;es necesario: cuando se pasa el objeto de usuario drupal_alter()para permitir que los módulos de terceros alteren al usuario actualmente activo (que no es algo realmente implementado en Drupal).
kiamlaluno
1
global $userno es lo mismo que user_uid_optional_load (). El primero se carga desde la sesión y no es un objeto de usuario completamente cargado (con campos y ganchos invocados) mientras que el segundo sí. Entonces no enumeraría esto como una opción. El propósito de esa función es usarse para argumentos de menú con nombre que opcionalmente pueden aceptar una identificación de usuario y, de lo contrario, ser el valor predeterminado para el usuario actual. / user / uid es el ejemplo principal.
Berdir
@ Berdir Gracias, no sabía que no global $userestaba completamente cargado por defecto (aunque tiene sentido y explica un par de cosas que me había preguntado antes). Lo he sacado de la respuesta.
Clive
Gracias Clive, supongo que usar $ user global y copiarlo en una variable $ account es probablemente la alternativa más segura. Aunque en realidad estaba buscando user_uid_optional_load () :)
Alex Weber
3

Es tan simple como declarar el objeto $ user global (existente) dentro del alcance de su función:

global $user;

Tenga en cuenta que los cambios realizados en este objeto lo afectan globalmente, es decir

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

acaba de dar al usuario actual uid 1 privilegios. Esta es la razón por la cual típicamente $ user se asigna a $ account para que los datos puedan ser manipulados sin afectar realmente al usuario actualmente conectado (a menos que, por supuesto, lo desee).

Charlie Schliesser
fuente