Globals的替代品

时间:2014-09-17 20:13:54

标签: php wordpress

我有一组需要在我的网站上访问的变量。虽然我可以在我的header.php文件中声明它们,但我更愿意在functions.php中定义它们,或者不在模板文件(视图)中定义它们。我读到的一切都说不要使用GLOBAL的......好吧。但那么定义这些变量的最佳方法是什么?

以下是我要定义的内容:

 global $favorites_array;
 global $user;
 global $user_id;
 global $user_name;
 global $uri;

 $user = wp_get_current_user();
 $user_name = $user->user_login;
 $user_id = $user->ID;
 $user_id = get_current_user_id();
 $uri = $_SERVER['REQUEST_URI'];

3 个答案:

答案 0 :(得分:4)

您发现使用全局变量(或尽可能避免使用它们)的常见建议通常是很好的建议,而您首先要寻找替代方案而不是使用它们是正确的。最常见的替代方法是将值作为参数传递给函数。

WordPress的许多功能已经依赖于全局变量,而looking into the source code似乎函数wp_get_current_user()实际上正在设置一个名为$current_user的全局变量。

多次调用wp_get_current_user() will immediately return if the global $current_user is already populated:

if ( isset( $current_user ) && ( $current_user instanceof WP_User ) && ( $id == $current_user->ID ) )
    return $current_user;

因此,查看您要设置的变量列表,我发现任何容器变量都没有迫切需要。我的建议是尽可能选择代码中的显式可读性。由于WordPress提供的功能wp_get_current_user()的目的是获取该用户,而不是创建global $user并传递它,调用可用功能。例如,你不能在字符串插值中使用函数调用:

// Can't do this:
echo "The user is {wp_get_current_user()->user_login}";

...所以如果您打算为用户的登录创建一个全局变量,请在函数中设置一个本地变量。

function your_func() {
  $login = wp_get_current_user()->user_login;
  echo "The user is $login";
}

至于设置像$user_id这样的变量作为用户对象的ID属性的容器,因为ID确实是用户对象的属性,所以它很好逻辑意义上维护代码中的关系。虽然输入速度可能更快:

echo $user_id;

这明确了变量的来源:

echo wp_get_current_user()->ID;
// or even better, using the API function
echo wp_get_current_user_id();

最后,关于$_SERVER数组,它已经是a PHP superglobal array,可在所有范围中使用,无需任何额外的工作。因此,不是以下列形式从中抽象出一个键:

$uri = $_SERVER['REQUEST_URI'];

我会选择直接在您自己的函数中使用$_SERVER['REQUEST_URI'] 。例如,如果您发现需要在一个函数中多次使用它,那么可以随意在函数中创建 local 变量:

function uses_uri() {
  $uri = $_SERVER['REQUEST_URI'];
  echo "I like to say $uri over and over $uri $uri $uri";
}

但是,如果您使用的是超全局值,如果直接使用代码或者在使用它的位置附近定义局部变量,则代码将更具可读性(而不是在单独的包含中定义的全局变量)必须追溯其值的文件)。

因为我对WordPress的API并不十分熟悉,所以我不能肯定它是否提供了一个API函数来检索请求URI。但是,如果这样的函数已经存在并且通常在WP代码中使用,我不会感到惊讶。

答案 1 :(得分:2)

你是对的,你不应该使用全局变量。 解决这个问题的一种方法是将主题代码放在一个类中并实例化它。

下面的示例使用单例样式类定义以及主题模板文件可能需要的变量,我认为它可以实现您的尝试。

的functions.php:

class My_Theme {
    public $favorites_array;
    public $user;
    public $user_id;
    public $user_name;
    public $uri;

    protected function __construct(){
        // TODO: put all your add_filter and add_action calls here  

        $this->favorites_array = array();
        $this->user = wp_get_current_user();
        $this->user_name = $this->user->user_login;
        $this->user_id = get_current_user_id();
        $this->uri = $_SERVER['REQUEST_URI']; 
    }

    function get_instance() {
        static $instance;
        if( ! isset( $instance ) )
            $instance = new self();

        return $instance;
    }
}

My_Theme::get_instance();

然后在header.php中你可以:

<?php
    $my_theme = My_Theme::get_instance();
?>
<html>
    ...
    ...
    <title>Hello <?php echo( esc_html( $my_theme->user_name ) ); ?></title>

我还应该指出,通过你拥有的变量的外观,你可能只需要$favorites_array,因为其他的都可以使用WordPress函数进行检索,而且只是多余的。

答案 2 :(得分:1)

嗯,有很多博客说'#34;不要使用全球&#34;但实际上没有解释原因。在所有语言中,我们都有&#34;全球&#34;。它似乎不是一个问题。 唯一的问题&#34;我们可以发现,在一个大型代码中,很难找到问题wuth全局,因为它们(在许多情况下)在不同的文件中(一个巨大的C dev可以有超过100个文件)。 在PHP中,代码通常很短。

实际上,您必须考虑使用命名约定,以便能够快速检测var是否为全局变量。 例如,用'&#34; gl&#34;命名他们。或者&#34; glb&#34;,如你所愿。 这样可以避免忘记放置&#34; global&#34;在功能开始时。 使用session,fucntion参数全局等。每个都作为正面和负面点。无需避免使用其中一个。

另请注意,如果值在整个代码中保持不变,则使用常量(DEFINE)可能是另一个不错的选择。

此致 彼得