We recently had a discussion if it was possible to build a trait Singleton
PHP Traits and we played around with it a possible Implementation but ran into issues with building one.
This is an academic exercise. I know that Singletons have very little - if not to say no - use in PHP
and that one should 'just create one'
but just for exploring the possibilities of traits:
<?php trait Singleton { protected static $instance; final public static function getInstance() { return isset(static::$instance) ? static::$instance : static::$instance = new static; } final private function __construct() { static::init(); } protected function init() {} final private function __wakeup() {} final private function __clone() {} } class A { use Singleton; public function __construct() { echo "Doesn't work out!"; } } $a = new A(); // Works fine
reproduce: http://codepad.viper-7.com/NmP0nZ
The question is: It is possible to create a Singleton Trait in PHP?
Unlike traits in Scala, traits in PHP can have a constructor but it must be declared public (an error will be thrown if is private or protected). Anyway, be cautious when using constructors in traits, though, because it may lead to unintended collisions in the composing classes.
Singleton is a creational design pattern, which ensures that only one object of its kind exists and provides a single point of access to it for any other code. Singleton has almost the same pros and cons as global variables. Although they're super-handy, they break the modularity of your code.
PHP does not allow you to create an instance of a Trait like an instance of a class. And there is no such concept of an instance of a trait.
PHP Traits are Bad On the surface, there is strong support for PHP traits because using them can help reduce code duplication throughout your application. In addition, they can help improve maintainability and the cleanliness of your code.
Quick solution we've found (thanks chat!):
If a trait and a class both define the same method, the one of class if used
So the Singleton trait only works if the class that uses it doesn't define a __construct()
<?php trait Singleton { protected static $instance; final public static function getInstance() { return isset(static::$instance) ? static::$instance : static::$instance = new static; } final private function __construct() { $this->init(); } protected function init() {} final private function __wakeup() {} final private function __clone() {} }
<?php class A { use Singleton; protected function init() { $this->foo = 1; echo "Hi!\n"; } } var_dump(A::getInstance()); new A();
Hi! object(A)#1 (1) { ["foo"]=> int(1) }
Fatal error: Call to private A::__construct() from invalid context in ...
Demo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With