在所有WordPress页面上使用变量的最佳方法

时间:2017-09-15 23:32:51

标签: php wordpress variables global-variables

我正在构建一个自定义主题,其中包含许多我希望在整个过程中使用的变量。

示例:

$tv     = $options['tv'];
$movies = $options['movies'];
$print  = $options['print'];
//....and about 50 more.

为此目的,我只是将它们全部放在一个名为vars.php的文件中,然后在主题的header.php中包含它...

require_once('vars.php');

虽然这确实有效,但它并不是最好的方式。我曾多次读过使用全局变量(大概是在functions.php中)并不是一个好主意,但这是真的吗?

但是如果在functions.php中使用全局变量(甚至很多都可以),这是正确的方法吗?:

global $tv;
$tv     = $options['tv'];

global $movies
$movies = $options['movies'];

global $print
$print  = $options['print'];

6 个答案:

答案 0 :(得分:8)

最好的方法是在functions.php或插件的主插件文件中明确定义所有变量。 我已经确认这是最流行的插件,包括akismet使用。具体来说,你需要这样做。

define( MYVAR_TV, $options['tv'] );
define( MYVAR_MOVIES, $options['movies'] );
define( MYVAR_PRINT, $options['print'] );

在这些之后你可以随心所欲地使用它们

echo MYVAR_TV;

希望它有所帮助。

答案 1 :(得分:8)

使用全球性很好,但不鼓励(你可以在这里阅读更多Are global variables in PHP considered bad practice? If so, why?)。您可以考虑使用Singleton:

<?php
class GlobalVariable {
    /**
     * @var array
     */
    public static $option = [];
}

// You can set the variable using this way
GlobalVariable::$option['movies'] = 1;

// And get the variables using that array
print_r(GlobalVariable::$option);

希望这可以帮到你。

答案 2 :(得分:2)

如何在functions.php中创建一个返回变量数组的函数?

示例:$options = get_my_custom_vars();

答案 3 :(得分:2)

我假设您想要全局变量,它会生成一个包含所有变量的数组。使用它:

$GLOBALS['your-varriable']

来源: PHP Documentation

答案 4 :(得分:2)

我个人喜欢使用Acf Options Addon。通过wpml插件改变这些并使它们可翻译也很有用。

这些选项可以在后端的“选项页面”中进行添加/编辑,也可以按照链接中的说明进行编程。

通过functions.php

初始化插件后
if( function_exists('acf_add_options_page') ) {

acf_add_options_page();

}

只需通过

在模板中调用这些内容即可
<?php the_field('header_title', 'option'); ?>

答案 5 :(得分:2)

您也可以实现自定义流包装器。这样您就可以使用file_get_contentsfile_put_contentsfreadfwrite等功能访问和存储数据。就像从文件读取或写入,或从中获取信息一样远程网址。

实际上PHP手册中有一个例子using global variables like you ask。但是我们可以按照完整性的顺序从中拉出它,并根据WP中的用例和使用示例进行调整。

<?php
// variable-stream-class.php just this is pulled from the PHP manual

class VariableStream {
    var $position;
    var $varname;

    function stream_open($path, $mode, $options, &$opened_path)
    {
        $url = parse_url($path);
        $this->varname = $url["host"];
        $this->position = 0;

        return true;
    }

    function stream_read($count)
    {
        $ret = substr($GLOBALS[$this->varname], $this->position, $count);
        $this->position += strlen($ret);
        return $ret;
    }

    function stream_write($data)
    {
        $left = substr($GLOBALS[$this->varname], 0, $this->position);
        $right = substr($GLOBALS[$this->varname], $this->position + strlen($data));
        $GLOBALS[$this->varname] = $left . $data . $right;
        $this->position += strlen($data);
        return strlen($data);
    }

    function stream_tell()
    {
        return $this->position;
    }

    function stream_eof()
    {
        return $this->position >= strlen($GLOBALS[$this->varname]);
    }

    function stream_seek($offset, $whence)
    {
        switch ($whence) {
            case SEEK_SET:
                if ($offset < strlen($GLOBALS[$this->varname]) && $offset >= 0) {
                     $this->position = $offset;
                     return true;
                } else {
                     return false;
                }
                break;

            case SEEK_CUR:
                if ($offset >= 0) {
                     $this->position += $offset;
                     return true;
                } else {
                     return false;
                }
                break;

            case SEEK_END:
                if (strlen($GLOBALS[$this->varname]) + $offset >= 0) {
                     $this->position = strlen($GLOBALS[$this->varname]) + $offset;
                     return true;
                } else {
                     return false;
                }
                break;

            default:
                return false;
        }
    }

    function stream_metadata($path, $option, $var) 
    {
        if($option == STREAM_META_TOUCH) {
            $url = parse_url($path);
            $varname = $url["host"];
            if(!isset($GLOBALS[$varname])) {
                $GLOBALS[$varname] = '';
            }
            return true;
        }
        return false;
    }
}

假设您有一个插件来隔离您的功能,能够将其停用以进行调试,并且如果您更改活动主题则不会丢失它。我建议在你的插件入口点放一些这样的东西:

<?php
/**
 * Plugin Name: Stream Wrapper for global variables
 * Plugin URI: https://stackoverflow.com/q/46248656/
 * Description: Utility class and functions to enable global data sharing in WordPress
 * Author: Jesús E. Franco Martínez and the PHP Documentation Group
 * Contributors: tzkmx
 * Version: 0.1
 * Author URI: https://tzkmx.wordpress.com
 */
require 'variable-stream-class.php';

stream_wrapper_register("var", "VariableStream")
    or wp_die("Failed to register protocol", null, ['back_link' => true]);

然后,在模板或其他站点插件中,您可以使用上述功能,或使用自定义别名。让我们扩展您的请求:

// functions.php in your theme or better, in the same plugin.php above

// Using a hook just for frontend in order to get populated
// our variables without require calls in the theme.

add_action('wp_head', 'populate_my_awesome_plugin_options');

function populate_my_awesome_plugin_options() {

// Let's say you get your data from a single get_option call
    $options = get_option( 'my_awesome_plugin_options' );

    foreach( $options as $key => $value ) {
        file_put_contents( 'var://' . $key, $value );
    }
}

function pop_get_var( $var_name ) {
    return file_get_contents( 'var://' . $var_name );
}

最后,在header.php或您要使用数据的任何模板文件中,调用如下:

<p>TV favorite show: <strong><?= pop_get_var( 'tv' ) ?></strong></p>

<p>Movies I like: <strong><?= pop_get_var( 'movies' ) ?></strong></p>

<p>Impressum: <em><?= pop_get_var( 'print' ) ?></em></p>

我知道它最初可能看起来像很多样板,但由于关注点的分离,你不仅仅局限于标量值,比如使用常量,你的流包装器也可以是你喜欢的任何数据存储的适配器。不仅在内存中或存储在WordPress选项表中。使用自定义函数可以轻松地将这些长调用写入单例类,或者在您想要访问自定义数据的任何地方调用全局。

实际上,如果您阅读PHP手册中的示例,您将找到使用包装器存储整个文本的示例,您可以使用include进行调用。没有什么能阻止您使用序列化数据,例如json_encode / json_decode,并与您的包装器一起存储,甚至可以直接在数据库中轻松完成。还有另一个使用PDO从数据库写入/读取数据的示例,但可以轻松移植到使用WordPress $wpdb对象。