Drupal — Как я могу сделать массив доступным по всему миру?

#php #drupal #drupal-6 #drupal-views

#php #drupal #drupal-6 #drupal-просмотры

Вопрос:

Я использую этот код в шаблоне поля просмотра (в данном случае 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;    
}


?>
  

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

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

Ответ №1:

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

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

 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() в любом количестве мест, сколько захотите, и рабочий код под первым возвращаемым значением будет выполнен только при первом вызове.

Комментарии:

1. Я видел другой ваш пост о том, как вы это используете. На самом деле нет необходимости заново создавать этот массив пользовательских идентификаторов. Вы могли бы просто использовать эту функцию для установки $users_friends (вместо $ users_friends_ids), а затем вы можете проверить, существует ли конкретный идентификатор пользователя в этом массиве с помощью этого: key_exists($some_uid, $users_friends)

2. Как вы вызываете модуль, это с помощью module_invoke? Как вы можете видеть, здесь действительно трудно: (

3. Обычно у меня есть модуль для общей функциональности помощника сайта, но если вам пока неудобно работать с модулями, вы можете просто добавить эту функцию в свой template.php файл. Вероятно, вам следует изменить ‘mymodule’ в имени функции на название вашей темы. Затем в каждом шаблоне вам нужно получить доступ к этому массиву пользовательских идентификаторов, просто сделайте что-то вроде $users_friends_ids = mymodule_get_friend_ids();

4. Кажется, я просто не могу заставить это работать в функции. Я выполнил несколько простых тестов, чтобы проверить, распознается ли функция, и это так, плюс код работает нормально, если взять его из оболочки функции и поместить в шаблон. Я буду продолжать подключаться. (Я отмечу ваш ответ как «принятый», как только разберусь, что происходит!)

5. Я отредактировал, чтобы добавить возврат переменной в конце. Coder1 сделал то, что я часто делаю: забыл вернуть переменную в конце функции. Вам нужно добавить строку после // ADDED LINE …

Ответ №2:

Совет от 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 */
}
  

Комментарии:

1. ПРИМЕЧАНИЕ: вышесказанное может быть излишним, я увидел, что в элегантном решении Coder1 просто отсутствовала возвращаемая переменная в конце — и отредактировал ее — редактирование должно появиться «после экспертной оценки»

2. Приветствия. Возможно, в этом нет необходимости, но всегда полезно иметь немного дополнительных знаний, чтобы вникнуть в суть.