Como passo dados entre ganchos que não interagem?

10

Como transmito dados entre ganchos que não interagem entre eles ou entre um retorno de chamada de menu e um gancho?

No caso de os dois ganchos terem um parâmetro em comum, e esse parâmetro é passado por referência, isso é fácil. O que faço quando os ganchos, ou o retorno de chamada do menu e o gancho, não obtêm um parâmetro comum?

Letharion
fonte

Respostas:

12

No Drupal 7, ou superior, use uma variável estática manipulada com drupal_static () .
drupal_static()é uma função que lida com um armazenamento central para variáveis ​​estáticas. Diferentemente das variáveis ​​declaradas usando a staticpalavra - chave, as variáveis ​​estáticas manipuladas drupal_static()são acessíveis a partir de todas as funções; isso é possível porque drupal_static()retorna o conteúdo da variável por referência, permitindo que cada função a altere.

Suponha que você precise passar um valor entre um manipulador de menus e a implementação de hook_block_view () ; você pode usar o seguinte código.

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

Caso os dados precisem ser acessados ​​com mais frequência, você deve usar uma variável local estática que contenha o valor retornado drupal_static(). Como variáveis ​​estáticas só podem ser inicializadas a partir do valor literal e variáveis ​​estáticas não podem ser atribuídas a referências , o único código de trabalho é semelhante ao seguinte. (Este código é retirado de 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'];

O valor retornado drupal_static()é redefinido toda vez que o Drupal inicia; se você precisar de um valor preservado entre páginas diferentes, precisará usar uma tabela de banco de dados para armazenar o valor ou usar variable_get () / variable_set () .

O Drupal 6 não implementa drupal_static(), mas você pode copiar seu código em uma função definida em seu próprio módulo.

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

Antes de usar uma variável estática com drupal_static()(ou a função de porta traseira definida em seu módulo), lembre-se destas considerações:

  • O código funciona apenas quando o código que define a variável estática é executado antes do código para obter seu valor; se a ordem de execução não for a ideal, o código não funcionará. Quando a ordem de execução não está claramente definida na documentação do Drupal, existe o risco de a ordem mudar nas versões futuras do Drupal; verifique se a ordem de execução não muda na versão do Drupal para a qual você está implementando seu código.
  • Drupal poderia ter implementado um mecanismo para compartilhar dados entre diferentes ganchos. Por exemplo, no caso de diferentes implementações de hook_form_alter () , cada implementação pode compartilhar dados com outras hook_form_alter()implementações usando $form_state; da mesma maneira, os manipuladores de validação de formulários e os manipuladores de envio de formulários podem compartilhar dados usando o $form_stateparâmetro que é passado por referência. Antes de implementar seu próprio código, verifique se é possível compartilhar dados usando um mecanismo diferente já implementado pelo Drupal para o caso específico.
kiamlaluno
fonte
Realmente aprecio a resposta dada aqui para o pôster original. No entanto, minha preocupação é que me digam que o uso de variáveis ​​estáticas drupal não se ajusta muito bem - para sites que lidam com muitas solicitações, devido ao fato de que todo o conjunto de variáveis ​​é carregado a cada vez, para cada sessão (ou algo como Isso foi dito por um colega que estava trabalhando em um problema de desempenho relacionado a isso. O que você acha? Eles aconselhável que usando o cache Drupal seria a melhor maneira de passar variáveis ao redor (assumindo que eles não são necessários após os dados foram recebidos pelo código de destino)
therobyouknow
@therobyouknow "para sites que lidam com muitas solicitações, devido ao fato de que todo o conjunto de variáveis ​​é carregado a cada vez", que é a tabela de variáveis , e não qualquer variável estática, que é uma coisa completamente diferente. as próprias variáveis ​​estáticas têm um impacto insignificante no desempenho. Mesmo na tabela de variáveis, você teria que abusar muito do sistema para causar problemas. Economist.com pode facilmente ter vários hits de 100k em uma hora, todos os quais carregam a tabela de variáveis. Variáveis ​​não são um problema, mas é claro, armazenamos apenas pequenas informações em cada variável.
Letharion