상호 작용하지 않는 후크간에 데이터를 전달하려면 어떻게합니까?


10

상호 작용하지 않는 후크 사이 또는 메뉴 콜백과 후크 사이에서 데이터를 전달하는 방법은 무엇입니까?

두 후크의 공통 매개 변수가 있고 해당 매개 변수가 참조로 전달되는 경우 쉽습니다. 후크 또는 메뉴 콜백 및 후크에 공통 매개 변수가없는 경우 어떻게해야합니까?

답변:


12

Drupal 7 이상에서는 drupal_static ()으로 처리되는 정적 변수를 사용하십시오 .
drupal_static()정적 변수에 대한 중앙 저장소를 처리하는 함수입니다. static키워드를 사용하여 선언 된 변수와 달리 처리 된 정적 변수 drupal_static()는 모든 함수에서 액세스 할 수 있습니다. 이것은 drupal_static()변수의 내용을 참조로 반환하여 모든 함수가 변수를 변경할 수 있기 때문에 가능 합니다.

메뉴 핸들러와 hook_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이 부트 스트랩 할 때마다 재설정됩니다. 다른 페이지간에 유지되는 값이 필요한 경우 데이터베이스 테이블을 사용하여 값을 저장하거나 variable_get () / variable_set ()을 사용해야 합니다 .

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은 서로 다른 후크간에 데이터를 공유하는 메커니즘을 구현했을 수 있습니다. 예를 들어, hook_form_alter () 의 다른 구현의 경우 각 구현은 ;을 hook_form_alter()사용하여 다른 구현 과 데이터를 공유 할 수 있습니다 $form_state. 동일한 방식으로 양식 유효성 검증 핸들러 및 양식 제출 핸들러 $form_state는 참조로 전달되는 매개 변수를 사용하여 데이터를 공유 할 수 있습니다 . 자체 코드를 구현하기 전에 Drupal이 특정 사례에 대해 이미 구현 한 다른 메커니즘을 사용하여 데이터를 공유 할 수 있는지 확인하십시오.

원래 포스터에 대한 여기에 주어진 대답을 정말로 고맙게 생각합니다. 그러나 내 우려는 drupal 정적 변수를 사용하는 것이 확장 성이 좋지 않다는 말입니다. 모든 변수 세트가 매번로드 될 때마다 많은 요청을 처리하는 사이트의 경우 (또는 이와 유사한 것) 나는 이것과 관련된 성능 문제를 해결해 온 동료로부터 이것을 들었습니다. 어떻게 생각해? 그들은 Drupal 캐시를 사용하는 것이 변수를 전달하는 더 좋은 방법이라고 조언했습니다 (대상 코드가 데이터를 수신 한 후 필요하지 않다고 가정)
therobyouknow

@therobyouknow는 변수 테이블 인 정적 변수가 아니라 변수 테이블 인 "모든 변수 세트가 매번로드되기 때문에 많은 요청을 처리하는 사이트에 대해" 완전히 다른 것입니다. 정적 변수 자체는 성능에 거의 영향을 미치지 않습니다. 변수 테이블에서도 문제를 일으키려면 시스템을 많이 남용해야합니다. Economist.com은 한 시간에 몇 번의 조회수 10 만 회를 쉽게 달성 할 수 있으며, 모두 변수 테이블을로드합니다. 변수는 문제가되지 않지만 물론 각 변수에 작은 정보 조각 만 저장합니다.
Letharion
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.