Drupal - Как я могу сделать массив глобально доступным? - PullRequest
6 голосов
/ 18 апреля 2011

Я использую этот код в шаблоне поля представлений (в данном случае views-view-field - all-members - uid.tpl.php):

<?php

$users_friends = flag_friend_get_friends($user->uid);

$users_friends_ids = array();

foreach ($users_friends as $id => $value) {     
 $users_friends_ids[] = $id;    
}


?>

Он в основном получаетидентификаторы друзей друзей и помещают их в массив, чтобы я мог проверить, совпадает ли поле с любым идентификатором пользователя.

Так что моя проблема в том, что я не хочу, чтобы это было в этом шаблоне (для некоторыхпричины), но если я не могу, я не могу получить доступ к массиву.Как я могу сделать этот массив глобально доступным?

Ответы [ 2 ]

5 голосов
/ 18 апреля 2011

Не зная ваших «нескольких причин», я не могу сказать, является ли это ответом наверняка. Мои собственные причины, вероятно, состоят в том, что я не хочу, чтобы один и тот же код выполнялся несколько раз, и я бы предпочел, чтобы в нескольких местах не было одного и того же точного кода.

Я бы тогда создал функцию со статической переменной для хранения массива друзей.

function mymodule_get_friends_ids() {
  // pull in the current global user variable
  global $user;

  // call up the static variable
  static $users_friends_ids;
  // return if this static var has already been set
  if (is_array($users_friends_ids)) {
    return $users_friends_ids;
  }

  // if we hit here, then this function has not been
  // run yet for this page load.

  // init array
  $users_friends_ids = array();

  // if user is anon, no need to go on
  if (user_is_anonymous()) {
    return $users_friends_ids;
  }

  // get friends array
  $users_friends = flag_friend_get_friends($user->uid);

  // build ids array
  foreach ($users_friends as $id => $value) {     
    $users_friends_ids[] = $id;    
  }

  return $users_friends_ids;
}

Теперь в ваших шаблонах вы можете вызывать mymodule_get_friends_ids () в любом количестве мест, и рабочий код под первым возвратом будет выполняться только при первом вызове.

2 голосов
/ 19 апреля 2011

Coder1 очень хороший совет - он не дает вам заполнить пространство имен вашей глобальной переменной большим количеством мусора. Это, наверное, самый «элегантный». Это может быть не самым простым в использовании, если вы новичок в PHP (что, я полагаю, может быть в случае, если вам трудно разобраться с возвратом массивов, но это нормально).

Однако, если это действительно приоритет, вам, вероятно, не нужно иметь одну дополнительную глобальную переменную.

Полагаю, здесь я могу заявить об очевидном - но вы можете, практически в любой момент выполнения (при условии, что нужная вам информация уже сгенерирована - например, переменная $ user заполнена), сделать это:

$GLOBALS['users_friends_ids'] = /* your code goes here */

Затем в вашем шаблоне вы получаете доступ к этому ...

$friendsArray = $GLOBALS['users_friends_ids'];

Или вы можете просто использовать конструкцию

global $user_friends_ids;

когда вы хотите инициализировать переменную или получить доступ к ней внутри функции или класса (как в случае с файлами шаблонов - они вызываются внутри функций, поэтому вам нужно глобализировать или использовать массив $GLOBALS, который "автоматически" все переменные, активные в глобальном пространстве имен).

Самое «логичное» место для этого было бы в модуле, использующем один из множества доступных хуков, чтобы выполнить этот код только один раз. hook_init() может сделать это за вас, если пользовательский объект уже загружен в этот момент (не уверен, вам придется тестировать). Но вы можете не захотеть создавать модули Drupal (это не так сложно).

Если вы делаете это внутри шаблона (и хотя это не очень хорошая практика, многие владельцы сайтов Drupal с начальным знанием PHP помещают все в шаблоны), вы захотите узнать, какой код шаблона выполняется когда. Код шаблона узла обычно выполняется перед кодом шаблона страницы, что логично, поскольку в противном случае переменные для содержимого узла в шаблоне страницы не будут заполнены.

Если у вас есть списки узлов, они будут вызывать этот код несколько раз, так что в итоге вы сделаете что-то похожее на то, что описывает Coder1 . Если вы не хотите создавать свой собственный небольшой модуль, вы можете поместить объявление функции, которое он написал, в файл template.php вашей темы, поскольку он вызывается только один раз. Вы не хотите помещать объявления функций в файлы tpl.php, поскольку они иногда вызываются более одного раза (и вам не разрешено объявлять функции более одного раза).

Если вам трудно понять функцию и результат, вы всегда можете сделать что-то подобное в своем коде (что очень, очень не элегантно - но лучше иметь не сложный код, который вы понимаете, чем элегантный код, который Вы не).

if(!isset($GLOBALS['users_friends_ids'])) {
   $GLOBALS['users_friends_ids'] = /* your code here */
}
...