MAGIC METHODS
The easiest way to create a global variable without polluting the global space is to utilize the Singleton
pattern. Essential a class that is only instantiated once and accessed via a single static function.
In this case you could make getters
and setters
to store and retrieve values but we can utilize PHP's magic methods. Now you have an ability to access this class from anywhere (as long as it's loaded) and save any property with any value.
The basic syntax is
<class>::<singleton>()-><property>
Just load this class once before accessing it.
if ( ! class_exists( 'CustomSettingClass' ) ) {
class CustomSettingClass {
private $s = array ();
private static $_instance;
public static function instance() {
if ( ! static::$_instance ) {
static::$_instance = new self();
}
return static::$_instance;
}
// setter
function __set( $k, $c ) {
$this->s[ $k ] = $c;
}
// getter
function __get( $k ) {
return isset( $this->s[ $k ] ) ? $this->s[ $k ] : null;
}
// callable
function __call( $method, $args ) {
if ( isset( $this->s[ $method ] ) && is_callable( $this->s[ $method ] ) ) {
return call_user_func_array( $this->s[ $method ], $args );
} else {
echo "unknown method " . $method;
return false;
}
}
}
}
Then just access the properties of the singleton
from a static
accessor.
CustomSettingClass::instance()->foo = 'bar';
echo CustomSettingClass::instance()->foo; // bar
CustomSettingClass::instance()->complex = array(1,2,3);
print_r( CustomSettingClass::instance()->complex ); // 1,2,3
As for security, you could utilize the same approach but rather than magic methods
use private methods for secure functions. Basic OOP really.
It's also worth noting that, by adding the __call
magic method, we can resolve anonymous functions.
// create handler
CustomSettingClass::instance()->callback = function($value){ echo $value; };
// add listener
add_action( 'test', array(CustomSettingClass::instance(), 'callback'));
// do action
do_action ('test', 'some value'); // some value
Now you have a completely dynamic and customizable object that acts like a $global
, can be adjusted on the fly, and can handle actions
and filters
.
SIMPLIFIED STATIC CLASS FUNCTIONS
Ok, so magic methods are over kill and not private. So how about a static class with private internals and an external facing settings getter. You only need to expose as much as you need in the public StaticSettings::settings()
function.
if ( ! class_exists( 'StaticSettings' ) ) {
class StaticSettings {
private static $_location = 'here';
public static function settings() {
return array (
'some' => 'settings',
'go' => static::$_location,
);
}
}
}
$settings = StaticSettings::settings();
LOCALLY SCOPED STATIC VARIABLE
I almost want to say your best bet is to go the static variable in a function route. This instantiated the $settings
object as null
which lets you trigger an initialization. At that point they are basically cached. So every other call to the function returns an already constructed object. All the inner workings are private to the function itself.
function my_settings() {
static $settings = null;
if ( null === $settings ) {
// initialize settings object once
$settings = array (
'some' => 'setting',
'go' => 'here',
);
}
// return cached value
return $settings;
}