【问题标题】:Drupal - How can I make an array globally accessible?Drupal - 如何使数组全局可访问?
【发布时间】:2011-04-17 22:32:53
【问题描述】:

我在视图字段模板中使用此代码(在本例中为 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;    
}


?>

它基本上获取朋友的用户 ID 并将它们放入一个数组中,这样我就可以检查该字段是否与任何用户 ID 匹配。

所以我的问题是我不想在这个模板中包含它(出于几个原因),但如果我不这样做,我将无法访问该数组。如何使该数组可全局访问?

【问题讨论】:

    标签: php drupal drupal-6 drupal-views


    【解决方案1】:

    在不知道您的“几个原因”的情况下,我无法确定这是否是答案。我自己的原因可能是我不希望相同的代码执行很多次,并且我宁愿在多个地方没有相同的确切代码。

    然后我会创建一个带有静态变量的函数来保存朋友数组。

    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(),并且第一次返回下方的工作代码只会在第一次调用时执行。

    【讨论】:

    • 我看到了你的另一篇关于你如何使用它的帖子。实际上不需要重新创建该用户 ID 数组。您可以使用此函数设置 $users_friends(而不是 $users_friends_ids),然后您可以使用以下命令检查该数组中是否存在特定的用户 ID:key_exists($some_uid, $users_friends)
    • 如何调用模块,是使用module_invoke吗?如您所见,在这里真的很挣扎:(
    • 我通常有一个用于通用站点助手功能的模块,但如果您还不习惯使用模块,您可以将该功能添加到您的 template.php 文件中。您可能应该将函数名称中的“mymodule”更改为您的主题名称。然后,在您需要访问该用户 ID 数组的每个模板中,只需执行类似 $users_friends_ids = mymodule_get_friend_ids();
    • 我似乎无法让它在函数中工作。我已经运行了一些简单的测试来查看函数是否正在被拾取,而且如果从函数包装器中取出代码并放在模板中,代码也可以正常工作。我会继续插电。 (一旦我完成了工作,我会将您的回答标记为“已接受”!)
    • 我编辑在最后添加了变量的返回。 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 模块(这并不难)。

    如果您在模板中执行此操作(尽管这不是一个好的做法,许多对 PHP 有初步了解的 Drupal 站点所有者将所有内容都放在模板中),您会想知道何时执行哪个模板代码。节点模板代码往往在页面模板代码之前执行 - 这是合乎逻辑的,否则页面模板中节点内容的变量将不会被填充。

    如果您有节点列表,它们会多次调用此代码,因此您最终会执行类似于 Coder1 所描述的操作。如果你不想创建自己的小模块,你可以把他写的函数声明放在你主题的 template.php 文件中,因为它只被调用一次。您不想将函数声明放在 tpl.php 文件中,因为它们有时会被多次调用(并且您不能多次声明函数)。

    如果你很难理解函数和返回,你总是可以在你的代码中做这样的事情(这非常、非常不优雅——但最好有你理解的不优雅的代码,而不是优雅的代码你没有)。

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

    【讨论】:

    • 注意:以上可能是不必要的,我看到 Coder1 的优雅解决方案只是在最后缺少一个返回变量 - 并且已经对其进行了编辑 - 编辑应该出现在“同行评审之后”
    • 干杯。这可能不是必需的,但有一点额外的知识来深入了解总是好的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-04
    • 2020-10-25
    • 1970-01-01
    • 1970-01-01
    • 2011-12-22
    • 1970-01-01
    相关资源
    最近更新 更多