Comment passer des données entre des hooks qui n'interagissent pas?


10

Comment passer des données entre des hooks qui n'interagissent pas entre eux, ou entre un rappel de menu et un hook?

Dans le cas où les deux crochets ont un paramètre en commun, et ce paramètre est passé par référence, c'est facile. Que dois-je faire lorsque les hooks, ou le rappel de menu et le hook, n'obtiennent pas de paramètre commun?

Réponses:


12

Dans Drupal 7 ou supérieur, utilisez une variable statique gérée avec drupal_static () .
drupal_static()est une fonction qui gère un stockage central pour les variables statiques. Différemment des variables déclarées à l'aide du staticmot - clé, les variables statiques gérées avec drupal_static()sont accessibles depuis toutes les fonctions; cela est possible car drupal_static()renvoie le contenu de la variable par référence, permettant à chaque fonction de le modifier.

Supposons que vous devez passer une valeur entre un gestionnaire de menus et l'implémentation de hook_block_view () ; vous pouvez utiliser le code suivant.

function mymodule_menu() {
  return array('path/%' => array(
    'page callback' => 'mymodule_callback_function',
    'page arguments' => array(1),
  ));
}

function mymodule_callback_function($data) {
  $data_passer = &drupal_static('mymodule_block_data');

  $data_passer = $data;

  // Other logic specific to this page callback.
}

function mymodule_block_view($delta = '') {
  // $data_passer will now contain the value of $data, from above.
  $data_passer = &drupal_static('mymodule_block_data');

  // Change the block content basing on the content of $data_passer.
}

Dans le cas où les données doivent être consultées plus fréquemment, vous devez utiliser une variable locale statique qui contiendrait la valeur renvoyée par drupal_static(). Comme les variables statiques ne peuvent être initialisées qu'à partir de la valeur littérale et que les variables statiques ne peuvent pas être affectées à des références , le seul code de travail est similaire au suivant. (Ce code est extrait de user_access () .)

  // Use the advanced drupal_static() pattern, since this is called very often.
  static $drupal_static_fast;
  if (!isset($drupal_static_fast)) {
    $drupal_static_fast['perm'] = &drupal_static(__FUNCTION__);
  }
  $perm = &$drupal_static_fast['perm'];

La valeur renvoyée par drupal_static()est réinitialisée à chaque démarrage de Drupal; si vous avez besoin d'une valeur qui est conservée entre différentes pages, vous devez utiliser une table de base de données pour stocker la valeur, ou utiliser variable_get () / variable_set () .

Drupal 6 n'est pas implémenté drupal_static(), mais vous pouvez copier son code dans une fonction définie dans votre propre module.

function &mymodule_static($name, $default_value = NULL, $reset = FALSE) {
  static $data = array(), $default = array();

  // First check if dealing with a previously defined static variable.
  if (isset($data[$name]) || array_key_exists($name, $data)) {
    // Non-NULL $name and both $data[$name] and $default[$name] statics exist.
    if ($reset) {
      // Reset pre-existing static variable to its default value.
      $data[$name] = $default[$name];
    }
    return $data[$name];
  }

  // Neither $data[$name] nor $default[$name] static variables exist.
  if (isset($name)) {
    if ($reset) {
      // Reset was called before a default is set and yet a variable must be
      // returned.
      return $data;
    }
    // First call with new non-NULL $name. Initialize a new static variable.
    $default[$name] = $data[$name] = $default_value;
    return $data[$name];
  }

  // Reset all: ($name == NULL). This needs to be done one at a time so that
  // references returned by earlier invocations of drupal_static() also get
  // reset.
  foreach ($default as $name => $value) {
    $data[$name] = $value;
  }

  // As the function returns a reference, the return should always be a
  // variable.
  return $data;
}

Avant d'utiliser une variable statique avec drupal_static()(ou la fonction de portage arrière définie dans votre module), vous devez garder ces considérations à l'esprit:

  • Le code ne fonctionne que lorsque le code qui définit la variable statique s'exécute avant le code pour obtenir sa valeur; si l'ordre d'exécution n'est pas celui de la pensée, le code ne fonctionne pas. Lorsque l'ordre d'exécution n'est pas clairement défini dans la documentation Drupal, il y a un risque que l'ordre change dans les futures versions de Drupal; vérifiez que l'ordre d'exécution ne change pas dans la version Drupal pour laquelle vous implémentez votre code.
  • Drupal aurait pu mettre en place un mécanisme pour partager des données entre différents hooks. Par exemple, dans le cas de différentes implémentations de hook_form_alter () , chaque implémentation peut partager des données avec d'autres hook_form_alter()implémentations en utilisant $form_state; de la même manière, les gestionnaires de validation de formulaire et les gestionnaires de soumission de formulaire peuvent partager des données à l'aide du $form_stateparamètre transmis par référence. Avant d'implémenter votre propre code, vérifiez qu'il est possible de partager des données en utilisant un mécanisme différent déjà implémenté par Drupal pour le cas spécifique.

J'apprécie vraiment la réponse donnée ici pour l'affiche originale. Cependant, ma préoccupation est que l'on me dit que l'utilisation de variables statiques drupal n'est pas très évolutive - pour les sites qui traitent un grand nombre de demandes, en raison du fait que l'ensemble des variables est chargé à chaque fois, pour chaque session (ou quelque chose comme cela.) Un collègue qui m'avait parlé d'un problème de performance lié à cela m'a dit cela. Qu'est-ce que tu penses? Ils ont indiqué que l'utilisation du cache Drupal serait un meilleur moyen de faire circuler les variables (en supposant qu'elles ne sont pas nécessaires après la réception des données par le code de destination)
therobyouknow

@therobyouknow "pour les sites qui traitent un grand nombre de requêtes, du fait que l'ensemble des variables est chargé à chaque fois" c'est la table des variables , et pas n'importe quelle variable statique, ce qui est complètement différent. les variables statiques elles-mêmes ont un impact négligeable sur les performances. Même dans le tableau des variables, il faudrait abuser du système pour causer des problèmes. Economist.com peut facilement avoir plusieurs hits de 100k en une heure, qui chargent tous le tableau des variables. Les variables ne sont pas un problème, mais bien sûr, nous ne stockons que de petites informations dans chaque variable.
Letharion
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.