it-swarm.com.de

Was ist die beabsichtigte Verwendung von drupal_static?

Ich verstehe Drupal statischer Cache wird verwendet, um statische Werte im Speicher für die Länge der Anforderung zu speichern, um schneller darauf zugreifen zu können. Jedoch während Drupal und beigetragene Module I. neigen dazu, zwei verschiedene Versionen zu sehen:

Beispiel aus drupal_is_front_page :

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

  if (!isset($is_front_page)) {
    // As drupal_path_initialize updates $_GET['q'] with the 'site_frontpage' path,
    // we can check it against the 'site_frontpage' variable.
    $is_front_page = ($_GET['q'] == variable_get('site_frontpage', 'node'));
  }

  return $is_front_page;
}

So wie ich es aus einem Tutorial gelesen (und verwendet) habe, das ich einmal gefunden habe:

$static_cache = &drupal_static(__FUNCTION__);
if (!isset($static_cache[$key])) {
  // Obtain value
  $static_cache[$key] = $obtained_value;
}

return $static_cache[$key];

Also habe ich die statische Deklaration der lokalen Variablen übersprungen, und um ehrlich zu sein, verstehe ich nicht, warum ich sie hinzufügen sollte, sie steht in der ersten Zeile von drupal_static :

function &drupal_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];
  }
  ...
}

Ist es noch schneller, wenn ich eine andere statische Variable in meinem Modul deklariere, die eine Funktion enthält, die eine statische Variable verwaltet? (Der Name drupal_static_fast impliziert dies.) Ist dies eine alte Drupal 6-Konvention, bei der es keine drupal_static gab und die lokal deklariert werden musste? Oder fehlt mir etwas anderes?

4
Neograph734

Der Code in drupal_is_front_page() beschleunigt das Rendern der Seite, da drupal_static() für jede Seitenanforderung einmal aufgerufen wird. Wie viel schneller es macht, hängt davon ab, wie oft drupal_is_front_page() aufgerufen wird. Die Tatsache, dass dieser Code verwendet wird, bedeutet, dass die Hauptbetreuer wissen, dass die Funktion oft genug aufgerufen wird, um diesen Code zu benötigen.
Die drupal_static() Dokumentation erklärt dies mit dem folgenden Absatz:

In einigen Fällen benötigt eine Funktion eine zurücksetzbare statische Variable, aber die Funktion wird während einer einzelnen Seitenanforderung mehrmals (100+) aufgerufen, sodass jede Mikrosekunde Ausführungszeit zählt, die aus der Funktion entfernt werden kann. Diese Funktionen können eine umständlichere, aber schnellere Variante des Aufrufs von drupal_static() verwenden. Es funktioniert, indem die von drupal_static() zurückgegebene Referenz in der eigenen statischen Variablen der aufrufenden Funktion gespeichert wird, wodurch das Aufrufen von drupal_static() für jede Iteration der Funktion entfällt. Konzeptionell ersetzt es:

$foo = &drupal_static(__FUNCTION__);

mit:

// Unfortunately, this does not work.
static $foo = &drupal_static(__FUNCTION__);

Die obige Codezeile funktioniert jedoch nicht, da PHP erlaubt nur die Initialisierung statischer Variablen durch Literalwerte und die Zuweisung statischer Variablen zu Referenzen nicht.

Das folgende Beispiel zeigt die Syntax, die erforderlich ist, um beide Einschränkungen zu umgehen. Benchmarks und weitere Informationen finden Sie unter http://drupal.org/node/619666 .

function user_access($string, $account = NULL) {
  // 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'];
  // ...
}

Ihr Code ruft jedes Mal drupal_static() auf und ist im Wesentlichen derselbe Code wie der folgende, der in der Dokumentation Drupal Dokumentation) nicht als schnelle Version betrachtet wird.

  $added = &drupal_static(__FUNCTION__);

  // User-uploaded files cannot set any response headers, so a custom header is
  // used to indicate to ajax.js that this response is safe. Note that most
  // Ajax requests bound using the Form API will be protected by having the URL
  // flagged as trusted in Drupal.settings, so this header is used only for
  // things like custom markup that gets Ajax behaviors attached.
  if (empty($added)) {
    drupal_add_http_header('X-Drupal-Ajax-Token', '1');
    // Avoid sending the header twice.
    $added = TRUE;
  }

@ Clive erklärt der Grund, warum drupal_static() zu Drupal hinzugefügt wurde: Die Idee hinter seiner Implementierung war, eine statische Variable zu verwenden, die gleichzeitig von anderen Funktionen zurückgesetzt (oder geändert) werden konnte auch. Tatsächlich sagt die drupal_static() Dokumentation :

Alle Funktionen, für die eine statische Variable erforderlich ist, um Daten innerhalb einer einzelnen Seitenanforderung beizubehalten oder zwischenzuspeichern, sollten diese Funktion verwenden, es sei denn, es ist absolut sicher, dass die statische Variable während der Seitenanforderung nicht zurückgesetzt werden muss. Durch die Zentralisierung der Speicherung statischer Variablen über diese Funktion können sich andere Funktionen auf eine konsistente API verlassen, um die statischen Variablen anderer Funktionen zurückzusetzen.

7
kiamlaluno