Come faccio a passare i dati tra hook che non interagiscono?


10

Come faccio a passare i dati tra hook che non interagiscono tra loro o tra un callback di menu e un hook?

Nel caso in cui i due hook abbiano un parametro in comune, e quel parametro viene passato per riferimento, è facile. Cosa devo fare quando gli hook, o il callback del menu e l'hook, non ottengono un parametro comune?

Risposte:


12

In Drupal 7 o versioni successive, utilizza una variabile statica gestita con drupal_static () .
drupal_static()è una funzione che gestisce una memoria centrale per variabili statiche. Diversamente dalle variabili dichiarate usando la staticparola chiave, le variabili statiche gestite drupal_static()sono accessibili da ogni funzione; questo è possibile perché drupal_static()restituisce il contenuto della variabile per riferimento, consentendo a ogni funzione di modificarlo.

Supponiamo che sia necessario passare un valore tra un gestore di menu e l'implementazione di hook_block_view () ; potresti usare il seguente codice.

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

Nel caso in cui sia necessario accedere ai dati più frequentemente, è necessario utilizzare una variabile locale statica che contenga il valore restituito drupal_static(). Poiché le variabili statiche possono essere inizializzate solo dal valore letterale e le variabili statiche non possono essere assegnate ai riferimenti , l'unico codice di lavoro è simile al seguente. (Questo codice è preso da 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'];

Il valore restituito da drupal_static()viene reimpostato ogni volta che Bootstrap Drupal; se è necessario un valore che viene conservato tra pagine diverse, è necessario utilizzare una tabella di database per archiviare il valore oppure utilizzare variabile_get () / variabile_set () .

Drupal 6 non implementa drupal_static(), ma potresti copiarne il codice in una funzione definita nel tuo modulo.

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

Prima di utilizzare una variabile statica con drupal_static()(o la funzione di back port definita nel modulo), è necessario tenere presente queste considerazioni:

  • Il codice funziona solo quando il codice che imposta la variabile statica viene eseguito prima del codice per ottenere il suo valore; se l'ordine di esecuzione non è quello pensato, il codice non funziona. Quando l'ordine di esecuzione non è chiaramente definito nella documentazione di Drupal, esiste il rischio che l'ordine cambi nelle versioni future di Drupal; controlla che l'ordine di esecuzione non cambi nella versione di Drupal per cui stai implementando il tuo codice.
  • Drupal avrebbe potuto implementare un meccanismo per condividere dati tra diversi hook. Ad esempio, nel caso di diverse implementazioni di hook_form_alter () , ogni implementazione può condividere dati con altre hook_form_alter()implementazioni usando $form_state; allo stesso modo, i gestori di convalida dei moduli e i gestori di invio dei moduli possono condividere i dati utilizzando il $form_stateparametro passato per riferimento. Prima di implementare il proprio codice, verificare che sia possibile condividere i dati utilizzando un meccanismo diverso già implementato da Drupal per il caso specifico.

Apprezzo molto la risposta fornita qui per il poster originale. Tuttavia la mia preoccupazione è che mi è stato detto che l'utilizzo di variabili statiche drupal non si adatta molto bene - per i siti che gestiscono molte richieste, a causa del fatto che l'intero set di variabili viene caricato ogni volta, per ogni sessione (o qualcosa del genere quello.) Mi è stato detto da un collega che aveva lavorato su un problema di performance correlato a questo. Cosa ne pensi? Hanno avvisato che usare la cache di Drupal sarebbe un modo migliore per passare le variabili (supponendo che non siano necessarie dopo che i dati sono stati ricevuti dal codice di destinazione)
therobyouknow

@therobyouknow "per i siti che gestiscono molte richieste, a causa del fatto che l'intero insieme di variabili viene caricato ogni volta" che è la tabella delle variabili , e non alcuna variabile statica, che è una cosa completamente diversa. le stesse variabili statiche hanno un impatto trascurabile sulle prestazioni. Anche nella tabella delle variabili, dovresti abusare molto del sistema per causare problemi. Economist.com può facilmente avere più di 100.000 hit in un'ora, ognuno dei quali carica la tabella delle variabili. Le variabili non sono un problema, ma ovviamente memorizziamo solo piccole informazioni in ogni variabile.
Letharion,
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.