我正在构建一个自定义主题,该主题有很多我希望在整个过程中使用的变量。
示例:
$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'];
可以使用全局,但不鼓励它(您可以在这里阅读更多的PHP中的全局变量被认为是不良实践?如果是这样,为什么?)。您可以考虑实施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);
希望这可以帮助您。
最好的方法是在functions.php或用于插件的主插件文件中明确定义所有变量。我已经验证了这是最受欢迎的插件(包括Akismet使用)的方式。特别需要执行此操作。
define( MYVAR_TV, $options['tv'] );
define( MYVAR_MOVIES, $options['movies'] );
define( MYVAR_PRINT, $options['print'] );
之后,您可以在任何想要的地方使用它们,例如
echo MYVAR_TV;
希望它有帮助。
在返回变量数组的function.php中创建一个函数呢?
示例:$options = get_my_custom_vars();
我假设您想要全局变量,其中它具有所有变量的数组。使用它:
$GLOBALS['your-varriable']
来源:PHP文档
我个人喜欢使用ACF选项插件。更改它们并通过WPML插件可以翻译它们也很有用。
这些选项将在后端的"选项页面"中添加/可编辑,或按照链接中所述的编程。
通过functions.php
初始化插件后if( function_exists('acf_add_options_page') ) {
acf_add_options_page();
}
只需通过
在模板中调用它们<?php the_field('header_title', 'option'); ?>
- 这些示例是从ACF选项页面文档中获取的。
- 请记住https://www.advancedcustomfields.com/必须安装才能工作。
您也可以实现自定义流包装器。这样,您可以使用file_get_contents
,file_put_contents
,fread
,fwrite
等函数访问和存储数据。就像从文件中读取和写作或从远程URL获取信息一样。
实际上,PHP手册中有一个示例,使用您提出的全局变量。但是,让我们按完整的顺序从那里拉出并将其调整为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
对象。