You can implement a custom stream wrapper, too. This way you could access and store data using functions like file_get_contents
, file_put_contents
, fread
, fwrite
, etc. Just like reading and writing from a file, or getting info from a remote URL.
Actually there is an example in the PHP manual, using global variables like you ask. But lets pull it from there in order of completeness and adapting it to your use case in WP and examples of use.
<?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;
}
}
Let's suppose you have a plugin to isolate your functions, being able to deactivate it for debugging and not losing it if you change the active theme. I'd recommend putting something like this in your plugin entrypoint:
<?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]);
Then, in your templates or other site plugins you can use the above mentioned functions, or use custom aliases. Let's expand on your request:
// 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 );
}
Finally, in the header.php or whatever template file you are going to consume your data, the call is just like this:
<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>
I know it may look like a lot of boilerplate at first, but because of separation of concerns, you are not limited only to scalar values like using constants, also your stream wrapper could be an adapter to whatever data store you like and not only in memory or stored in WordPress options table. And using a custom function eases you the hassle of writing such long calls to a singleton class, or calling global wherever you want to access your custom data.
Actually if you read the examples in the PHP manual, you'll find an example of using the wrapper to store an entire text, that you could call with include
. There is nothing stopping you from using even serialized data, in example with json_encode
/json_decode
, and stored with your wrapper, even directly in the database with little effort. There is another example to write/read data from a database with PDO, but is easily ported to use WordPress $wpdb
object.