Як передавати дані між гачками, які не взаємодіють?


10

Як передавати дані між гачками, які не взаємодіють між ними, або між зворотним викликом меню та гачком?

У випадку, якщо два гака мають спільний параметр, і цей параметр передається посиланням, це просто. Що робити, коли гачки або зворотний виклик меню та гачок не отримують загального параметра?

Відповіді:


12

У Drupal 7 або вище використовуйте статичну змінну, оброблювану з drupal_static () .
drupal_static()це функція, яка обробляє центральне сховище для статичних змінних. Відмінні від змінних, оголошених за допомогою staticключового слова, статичні змінні, з якими обробляються drupal_static(), доступні з кожної функції; це можливо, тому що drupal_static()повертає вміст змінної за посиланням, дозволяючи кожній функції змінювати її.

Припустимо, що вам потрібно передати значення між оброблювачем меню та реалізацією mock_block_view () ; ви можете використовувати наступний код.

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

У випадку, коли до даних потрібно частіше звертатися, слід використовувати статичну локальну змінну, яка містила б повернене значення drupal_static(). Оскільки статичні змінні можуть бути ініціалізовані лише з буквального значення , а статичні змінні не можуть бути призначені для посилань , єдиний робочий код аналогічний наступному. (Цей код взято з 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'];

Значення, що повертається з drupal_static(), скидається щоразу, коли завантажуються Drupal; якщо вам потрібне значення, яке зберігається між різними сторінками, вам потрібно використовувати таблицю бази даних для зберігання значення або використовувати змінний_get () / змінний_сет () .

Drupal 6 не реалізує drupal_static(), але ви можете скопіювати його код у функції, визначені у вашому власному модулі.

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

Перш ніж використовувати статичну змінну з drupal_static()(або функцією, що переноситься на задній панелі, визначеною у вашому модулі), слід пам’ятати про ці міркування:

  • Код працює лише тоді, коли код, який встановлює статичну змінну, працює перед кодом, щоб отримати його значення; якщо наказ на виконання не є продуманим, код не працює. Коли порядок виконання не чітко визначений в документації щодо Drupal, існує ризик зміни порядку в наступних версіях Drupal; перевірте, чи не змінюється порядок виконання у версії Drupal, для якої ви реалізуєте свій код.
  • Drupal міг реалізувати механізм обміну даними між різними гачками. Наприклад, у випадку різних реалізацій klju_form_alter () , кожна реалізація може обмінюватися даними з іншими hook_form_alter()реалізаціями, використовуючи $form_state; таким же чином, обробники валідації форми та обробники подачі форми можуть обмінюватися даними, використовуючи $form_stateпараметр, переданий посиланням. Перш ніж реалізувати власний код, переконайтесь, що можна обмінюватися даними, використовуючи інший механізм, який вже реалізував Drupal для конкретного випадку.

Дійсно оцініть відповідь, поданий тут за оригінальний плакат. Однак мене турбує те, що мені кажуть, що використання статичних змінних drupal не дуже масштабне - для сайтів, що обробляють багато запитів, завдяки тому, що весь набір змінних завантажується щоразу, для кожного сеансу (або щось подібне це.) Мені це сказав колега, який працював над проблемою вистави, пов'язаною з цим. Як ти гадаєш? Вони порадили, що використання кешу Drupal стане кращим способом передачі змінних (припускаючи, що вони не потрібні після отримання даних за кодом призначення)
therobyouknow

@therobyouknow "для сайтів, що обробляють безліч запитів, завдяки тому, що весь набір змінних щоразу завантажується", це таблиця змінних , а не будь-яка статична змінна, що зовсім інша річ. самі статичні змінні мають незначний вплив на продуктивність. Навіть у таблиці змінних вам доведеться багато зловживати системою, щоб викликати проблеми. Economist.com може легко отримати декілька 100-кілометрових звернень за годину, всі вони завантажують таблицю змінних. Змінні не є проблемою, але, звичайно, ми зберігаємо лише невеликі фрагменти інформації у кожній змінній.
Летаріон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.