Etkileşim yapmayan kancalar arasında verileri nasıl iletirim?


10

Verileri, aralarında etkileşimde bulunmayan kancalar arasında veya bir menü geri arama ve bir kanca arasında nasıl iletirim?

İki kancanın ortak bir parametresi varsa ve bu parametre referans olarak iletilir, bu kolaydır. Kancalar veya menü geri araması ve kanca, ortak bir parametre almazsa ne yapmalıyım?

Yanıtlar:


12

Drupal 7 veya daha yüksek sürümlerde, drupal_static () ile işlenen statik bir değişken kullanın .
drupal_static()statik değişkenler için merkezi depolamayı işleyen bir işlevdir. staticAnahtar sözcük kullanılarak bildirilen değişkenlerden farklı olarak, ele alınan statik değişkenlere drupal_static()her işlevden erişilebilir; bu mümkündür, çünkü drupal_static()değişkenin içeriğini referans olarak döndürür ve her fonksiyonun değiştirmesine izin verir.

Bir menü işleyicisi ile hook_block_view () uygulaması arasında bir değer geçirmeniz gerektiğini varsayalım ; aşağıdaki kodu kullanabilirsiniz.

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

Verilere daha sık erişilmesi gerekiyorsa, döndürülen değeri içeren statik bir yerel değişken kullanmalısınız drupal_static(). Gibi statik değişkenleri yalnızca edebi değerinden başlatıldı edilebilir ve statik değişkenler referanslarına atanamaz , sadece çalışma kod aşağıdaki birine benzer. (Bu kod user_access () öğesinden alınmıştır .)

  // 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'];

Döndürülen değer drupal_static(), Drupal önyüklemelerinin her defasında sıfırlanır; farklı sayfalar arasında korunan bir değere ihtiyacınız varsa, değeri depolamak için bir veritabanı tablosu kullanmanız veya variable_get () / variable_set () kullanmanız gerekir .

Drupal 6 uygulanmaz drupal_static(), ancak kodunu kendi modülünüzde tanımlanan bir fonksiyona kopyalayabilirsiniz.

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

Statik bir değişkeni drupal_static()(veya modülünüzde tanımlanan arkadan taşınan işlevle) kullanmadan önce, aşağıdaki noktaları göz önünde bulundurmalısınız:

  • Kod, yalnızca statik değişkeni ayarlayan kod değerini almak için koddan önce çalıştığında çalışır; yürütme sırası düşünülen sipariş değilse, kod çalışmaz. Yürütme sırası Drupal belgelerinde açıkça tanımlanmadığında, siparişin Drupal'ın gelecek sürümlerinde değişme riski vardır; kodunu uyguladığınız Drupal sürümünde yürütme sırasının değişip değişmediğini kontrol edin.
  • Drupal, farklı kancalar arasında veri paylaşımı için bir mekanizma uygulayabilirdi. Örneğin, hook_form_alter () ' in farklı uygulamaları durumunda , her uygulama aşağıdakileri hook_form_alter()kullanarak diğer uygulamalarla veri paylaşabilir $form_state; aynı şekilde, form doğrulama işleyicileri ve form gönderme işleyicileri, $form_statebaşvuru tarafından iletilen parametreyi kullanarak veri paylaşabilir . Kendi kodunuzu uygulamadan önce, özel durum için Drupal tarafından halihazırda uygulanmış farklı bir mekanizma kullanarak veri paylaşmanın mümkün olduğunu doğrulayın.

Orijinal poster için burada verilen cevabı gerçekten takdir ediyorum. Bununla birlikte endişem, drupal statik değişkenleri kullanmanın çok iyi ölçeklenmediği söyleniyor - çok sayıda istek işleyen siteler için, her bir değişkenin her seferinde, her oturumda (veya benzer bir şeyde) yüklü olması nedeniyle ) Bunu, bununla ilgili bir performans sorunu üzerinde çalışan bir meslektaşım tarafından söylendi. Ne düşünüyorsun? Drupal önbelleğini kullanmanın değişkenleri aktarmanın daha iyi bir yolu olacağını tavsiye ettiler (veriler hedef kod tarafından alındıktan sonra gerekli olmadığı varsayılarak)
therobyouknow

değişkenler var "değişkenlerin tüm set her zaman yüklenir getirilmesinden ötürü, birçok istek işleme siteler için" @therobyouknow masa ve değil tamamen farklı bir şeydir statik değişkeni. statik değişkenlerin kendilerinin ihmal edilebilir performans etkisi vardır. Değişkenler tablosunda bile, sorunlara neden olması için sistemi çok fazla kötüye kullanmanız gerekir. Economist.com, bir saat içinde kolayca 100 bin isabete sahip olabilir. Değişkenler bir sorun değildir, ancak elbette, her bir değişkende sadece küçük bilgiler depolarız.
Letharion
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.