Лучший способ использовать переменные на всех страницах WordPress

Я создаю настраиваемую тему, в которой есть много переменных, которые я хочу использовать во всем.

Пример:

$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'];

Ответы

Ответ 1

Хорошо использовать глобальный, но он не поощряется (вы можете прочитать здесь Являются ли глобальные переменные в 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);

Надеюсь, это поможет вам.

Ответ 2

Лучшим способом для этого является определение всех переменных явно в functions.php или в основном файле плагина для плагина. Я подтвердил, что это самые популярные плагины, включая использование акисметров. В частности, вам нужно это сделать.

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

После этого вы можете просто использовать их везде, где хотите,

echo MYVAR_TV;

Надеюсь, это поможет.

Ответ 3

Как насчет создания функции в functions.php, которая возвращает массив ваших переменных?

Пример: $options = get_my_custom_vars();

Ответ 4

Я предполагаю, что вам нужны глобальные переменные, где он создает массив со всеми вашими переменными. Чтобы использовать его:

$GLOBALS['your-varriable']

Источник: Документация по PHP

Ответ 5

Мне лично нравится использовать Acf Options Addon. Также полезно изменить их и перевести их через плагин wpml.

Эти параметры будут добавляться/редактироваться на странице "Параметры" в Бэкэнд или как запрограммировано, как описано в ссылке.

После инициализации аддона через функции .php

if( function_exists('acf_add_options_page') ) {

acf_add_options_page();

}

просто назовите их в шаблоне через

<?php the_field('header_title', 'option'); ?>
  • Эти примеры были взяты из документации по файлам Acf.
  • Имейте в виду https://www.advancedcustomfields.com/ должен быть установлен для этого, чтобы это работало.

Ответ 6

Вы также можете реализовать пользовательскую поточную оболочку. Таким образом, вы можете получать и хранить данные с помощью таких функций, как 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 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.