Wie übergebe ich Daten zwischen Hooks, die nicht interagieren?

10

Wie übergebe ich Daten zwischen Hooks, die nicht zwischen ihnen interagieren, oder zwischen einem Menü-Rückruf und einem Hook?

In dem Fall, dass die beiden Hooks einen Parameter gemeinsam haben und dieser Parameter als Referenz übergeben wird, ist das einfach. Was mache ich, wenn die Hooks oder der Menü-Rückruf und der Hook keinen gemeinsamen Parameter erhalten?

Letharion
quelle

Antworten:

12

Verwenden Sie in Drupal 7 oder höher eine statische Variable, die mit drupal_static () behandelt wird .
drupal_static()ist eine Funktion, die einen zentralen Speicher für statische Variablen verwaltet. Anders als bei den mit dem staticSchlüsselwort deklarierten Variablen drupal_static()sind die statischen Variablen, mit denen umgegangen wird, von jeder Funktion aus zugänglich. Dies ist möglich, weil drupal_static()der Inhalt der Variablen als Referenz zurückgegeben wird, sodass jede Funktion ihn ändern kann.

Angenommen, Sie müssen einen Wert zwischen einem Menü-Handler und der Implementierung von hook_block_view () übergeben . Sie können den folgenden Code verwenden.

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.
}

Für den Fall, dass häufiger auf Daten zugegriffen werden muss, sollten Sie eine statische lokale Variable verwenden, die den von zurückgegebenen Wert enthält drupal_static(). Da statische Variablen nur aus dem Literalwert initialisiert werden können und statische Variablen keinen Referenzen zugewiesen werden können, ähnelt der einzige Arbeitscode dem folgenden. (Dieser Code stammt aus 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'];

Der von drupal_static()zurückgegebene Wert wird jedes Mal zurückgesetzt, wenn Drupal-Bootstraps ausgeführt werden. Wenn Sie einen Wert benötigen, der zwischen verschiedenen Seiten erhalten bleibt, müssen Sie eine Datenbanktabelle zum Speichern des Werts verwenden oder variable_get () / variable_set () verwenden .

Drupal 6 wird nicht implementiert drupal_static(), aber Sie können den Code in eine in Ihrem eigenen Modul definierte Funktion kopieren.

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;
}

Bevor Sie eine statische Variable mit drupal_static()(oder der in Ihrem Modul definierten rückportierten Funktion) verwenden, sollten Sie folgende Überlegungen berücksichtigen:

  • Der Code funktioniert nur, wenn der Code, der die statische Variable festlegt, vor dem Code ausgeführt wird, um seinen Wert zu erhalten. Wenn die Ausführungsreihenfolge nicht der Gedanke ist, funktioniert der Code nicht. Wenn die Ausführungsreihenfolge in der Drupal-Dokumentation nicht klar definiert ist, besteht das Risiko, dass sich die Reihenfolge in zukünftigen Versionen von Drupal ändert. Überprüfen Sie, ob sich die Ausführungsreihenfolge in der Drupal-Version, für die Sie Ihren Code implementieren, nicht ändert.
  • Drupal hätte einen Mechanismus implementieren können, um Daten zwischen verschiedenen Hooks auszutauschen. Beispielsweise kann bei verschiedenen Implementierungen von hook_form_alter () jede Implementierung Daten mit anderen hook_form_alter()Implementierungen unter Verwendung von teilen $form_state. Auf die gleiche Weise können Formularüberprüfungshandler und Formularübermittlungshandler Daten mithilfe des $form_stateParameters gemeinsam nutzen, der als Referenz übergeben wird. Stellen Sie vor der Implementierung Ihres eigenen Codes sicher, dass es möglich ist, Daten mithilfe eines anderen Mechanismus zu teilen, der bereits von Drupal für den jeweiligen Fall implementiert wurde.
kiamlaluno
quelle
Schätzen Sie wirklich die Antwort, die hier für das Originalplakat gegeben wird. Ich mache mir jedoch Sorgen, dass mir gesagt wird, dass die Verwendung von statischen Drupal-Variablen nicht sehr gut skaliert werden kann - für Websites, die viele Anforderungen bearbeiten, da der gesamte Variablensatz jedes Mal für jede Sitzung (oder so ähnlich) geladen wird das.) Dies wurde mir von einem Kollegen gesagt, der an einem diesbezüglichen Leistungsproblem gearbeitet hatte. Was denken Sie? Sie rieten, dass die Verwendung des Drupal-Cache eine bessere Möglichkeit wäre, Variablen weiterzugeben (vorausgesetzt, sie werden nicht benötigt, nachdem die Daten vom Zielcode empfangen wurden)
wissen, dass der
@therobyouknow „für Websites , viele Anfragen Handhabung, aufgrund der Tatsache , dass die ganzen Reihe von Variablen wird jedes Mal geladen“ , dass die Variablen der Tabelle , und nicht jede statische Variable, die eine ganz andere Sache ist. statische Variablen selbst haben vernachlässigbare Auswirkungen auf die Leistung. Selbst in der Variablentabelle müssten Sie das System häufig missbrauchen, um Probleme zu verursachen. Economist.com kann problemlos mehrere 100.000 Treffer in einer Stunde erzielen, die alle die Variablentabelle laden. Variablen sind kein Problem, aber wir speichern natürlich nur kleine Informationen in jeder Variablen.
Letharion