I'm developing a WordPress plugin using the singleton pattern with the following requirements:
- There should ever exist one instance of the plugin
- Another instance of the object should never be instantiated, created, cloned, copied etc in any way.
- The singular plugin object and its public methods and vars should be easily accessible and usable in any scope, by anything including other plugins
The last one is a given with singleton pattern, but there is one concern I have:
- __construct()
should run only once, and should never run again. The code inside __construct()
should never be reparsed and reprocessed however the singleton is instantiated.
I already tested the code and it seems to work, however the code in __construct()
was being reprocessed every time i requested the instance of the object through get_instance()
outside the plugin until I added self::$instance = $this;
at the top.
I'm wondering whether I am violating the guidelines I listed above and also if it is possible for anyone to violate them through any kind of logic or method that they put into their plugins. Also whether this code will last at least a few PHP versions into the future.
class particular_plugin {
private static $instance = null;
protected function __construct()
{
self::$instance = $this;
// Numerous initialization variables and actions here
// including calls to functions inside the class
}
public static function get_instance()
{
if (null === static::$instance) {
static::$instance = new static();
}
return static::$instance;
}
private function __clone()
{
}
private function __wakeup()
{
}
}
// Initializing the plugin here
$particular_plugin = particular_plugin::get_instance();
function particular_plugin_get()
{
// This function allows any plugin to easily retrieve this plugin object and access its public methods and vars as they exist at any given point in time
return particular_plugin::get_instance();
}
1 Answer 1
Forget everything but the instatiator, constructor and property, you don't call new static;
you call new self()
, then it jumps into the constructor, the way I do singleton is:
class Foo
{
private static $init;
private function __construct() { }
public static function init()
{
return static::$init = (
null === static::$init ? new self() : static::$init
);
}
}
$foo = Foo::init();
This makes it so when new self()
is called, it jumps to the constructor and assigns self::$init
to really be an instance of the class
-
\$\begingroup\$ Just tested Sam. If i comment out self::$instance = $this; in __construct(), i enter recursion during plugin activation. There is an action initialize_vars that run inside the constructor, and one simple action that is hooked to it - which does nothing but the setup causes recursion. Leading me to think that construct is called multiple times if i leave out the self::$instance = $this; \$\endgroup\$unity100– unity1002016年01月27日 19:55:58 +00:00Commented Jan 27, 2016 at 19:55
-
\$\begingroup\$ @unity100, that's why you do your logic inside
__construct
and callnew self()
overnew static
\$\endgroup\$anon– anon2016年01月28日 18:59:11 +00:00Commented Jan 28, 2016 at 18:59 -
\$\begingroup\$ I have to call $this->initialize_vars() inside the construct. This allows the variable initialization to be hookable. \$\endgroup\$unity100– unity1002016年01月29日 15:58:31 +00:00Commented Jan 29, 2016 at 15:58
-
\$\begingroup\$ @unity, please read the manual, calling
new self()
is like calling$this->__construct()
inside the static member. basic OOP PHP. \$\endgroup\$anon– anon2016年01月29日 23:07:09 +00:00Commented Jan 29, 2016 at 23:07 -
\$\begingroup\$ Yeah but that's not my problem. I actually implemented your code and tested it. I still got the memory overflow problem without "self::$instance = $this;" at top of __construct(). \$\endgroup\$unity100– unity1002016年01月29日 23:17:55 +00:00Commented Jan 29, 2016 at 23:17
Explore related questions
See similar questions with these tags.
$this->initialize_vars();
function ? \$\endgroup\$