我正在构建一个自定义主题,其中包含许多我希望在整个过程中使用的变量。
示例:
$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'];
答案 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)
答案 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_contents
,file_put_contents
,fread
,fwrite
等功能访问和存储数据。就像从文件读取或写入,或从中获取信息一样远程网址。
实际上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
对象。