Làm cách nào để truyền dữ liệu giữa các hook không tương tác?


10

Làm cách nào để tôi chuyển dữ liệu giữa các hook không tương tác giữa chúng hoặc giữa một cuộc gọi lại menu và hook?

Trong trường hợp hai hook có một tham số chung và tham số đó được truyền bằng tham chiếu, điều đó thật dễ dàng. Tôi phải làm gì khi các hook, hoặc menu callback và hook, không nhận được một tham số chung?

Câu trả lời:


12

Trong Drupal 7 hoặc cao hơn, sử dụng biến tĩnh được xử lý với drupal_static () .
drupal_static()là một hàm xử lý một bộ lưu trữ trung tâm cho các biến tĩnh. Khác với các biến được khai báo bằng statictừ khóa, các biến tĩnh được xử lý có drupal_static()thể truy cập được từ mọi hàm; điều này là có thể bởi vì drupal_static()trả về nội dung của biến bằng tham chiếu, cho phép mọi hàm thay đổi nó.

Giả sử rằng bạn cần chuyển một giá trị giữa trình xử lý trình đơn và việc triển khai hook_block_view () ; bạn có thể sử dụng mã sau đây.

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

Trong trường hợp dữ liệu cần được truy cập thường xuyên hơn, bạn nên sử dụng biến cục bộ tĩnh có chứa giá trị được trả về drupal_static(). Vì các biến tĩnh chỉ có thể được khởi tạo từ giá trị bằng chữcác biến tĩnh không thể được gán cho các tham chiếu , mã làm việc duy nhất tương tự như sau. (Mã này được lấy từ 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'];

Giá trị được trả về từ drupal_static()được đặt lại mỗi lần bootstraps Drupal; nếu bạn cần một giá trị được bảo tồn giữa các trang khác nhau, thì bạn cần sử dụng bảng cơ sở dữ liệu để lưu trữ giá trị hoặc sử dụng biến_get () / biến_set () .

Drupal 6 không triển khai drupal_static(), nhưng bạn có thể sao chép mã của nó trong một hàm được xác định trong mô-đun của riêng bạn.

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

Trước khi sử dụng biến tĩnh với drupal_static()(hoặc hàm được chuyển ngược được xác định trong mô-đun của bạn), bạn nên ghi nhớ những lưu ý sau:

  • Mã chỉ hoạt động khi mã đặt biến tĩnh chạy trước mã để nhận giá trị của nó; nếu thứ tự thực hiện không phải là thứ được nghĩ, mã không hoạt động. Khi thứ tự thực hiện không được xác định rõ ràng trong tài liệu Drupal, có nguy cơ trật tự thay đổi trong các phiên bản tương lai của Drupal; kiểm tra thứ tự thực hiện không thay đổi trong phiên bản Drupal mà bạn đang triển khai mã của mình.
  • Drupal có thể đã thực hiện một cơ chế chia sẻ dữ liệu giữa các hook khác nhau. Ví dụ, trong trường hợp triển khai hook_form_alter () khác nhau, mỗi triển khai có thể chia sẻ dữ liệu với các hook_form_alter()triển khai khác bằng cách sử dụng $form_state; theo cùng một cách, trình xử lý biểu mẫu và trình xử lý biểu mẫu, có thể chia sẻ dữ liệu bằng cách sử dụng $form_statetham số được truyền bằng tham chiếu. Trước khi triển khai mã của riêng bạn, hãy xác minh có thể chia sẻ dữ liệu bằng cơ chế khác đã được Drupal triển khai cho trường hợp cụ thể.

Thực sự đánh giá cao câu trả lời được đưa ra ở đây cho các poster ban đầu. Tuy nhiên, mối quan tâm của tôi là tôi được thông báo rằng việc sử dụng các biến tĩnh drupal không có quy mô rất tốt - đối với các trang web xử lý rất nhiều yêu cầu, do thực tế là toàn bộ các biến được tải mỗi lần, cho mỗi phiên (hoặc đại loại như đó.) Tôi đã nói với một đồng nghiệp, người đã làm việc về một vấn đề hiệu suất liên quan đến vấn đề này. Bạn nghĩ sao? Họ khuyên rằng sử dụng bộ đệm Drupal sẽ là cách tốt hơn để truyền các biến xung quanh (giả sử rằng chúng không cần thiết sau khi dữ liệu đã được nhận bởi mã đích)
Therobyoukn

@therobyouledge "đối với các trang web xử lý rất nhiều yêu cầu, do thực tế là toàn bộ bộ biến được tải mỗi lần" đó là bảng biến và không phải bất kỳ biến tĩnh nào, đây là một điều hoàn toàn khác. Các biến tĩnh có tác động hiệu suất không đáng kể. Ngay cả trong bảng biến, bạn sẽ phải lạm dụng hệ thống rất nhiều để gây ra sự cố. Economist.com có ​​thể dễ dàng có vài lượt truy cập 100 nghìn trong một giờ, tất cả đều tải bảng biến. Các biến không phải là một vấn đề, nhưng tất nhiên, chúng tôi chỉ lưu trữ các mẩu thông tin nhỏ trong mỗi biến.
Letharion
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.