Straight to the point:
I've got two singleton classes, both inheriting their singleton nature from a super-class. I initialize some properties on the first singleton, and then have the second singleton retrieve the instance of the first one. That instance, however, does not seem to be the one I initialized in the first place. Some example code might help to explain this:
First, the super-class, providing singleton nature (requires PHP 5.3 or greater):
class Singleton {
protected static $instance;
protected function __construct() { }
final private function __clone() { }
public static function getInstance() {
if (!(static::$instance instanceof static)) {
static::$instance = new static();
}
return static::$instance;
}
}
Then we've got the the first singleton carrying a value:
require_once('Singleton.php');
class SingletonA extends Singleton {
protected $value;
public function SingletonA() {
$this->value = false;
}
public function getValue() {
return $this->value;
}
public function setValue($value) {
$this->value = $value;
}
}
Then the second singleton that references the first singleton:
require_once('Singleton.php');
require_once('SingletonA.php');
class SingletonB extends Singleton {
public function getValue() {
return SingletonA::getInstance()->getValue();
}
}
Now for the test that shows how this fails:
require_once('SingletonA.php');
require_once('SingletonB.php');
SingletonA::getInstance()->setValue(true);
echo (SingletonA::getInstance()->getValue()) ? "true\n" : "false\n";
echo (SingletonB::getInstance()->getValue()) ? "true\n" : "false\n";
The test yields the following output:
true
false
Clearly, the SingletonA instance that the test code references is not the same instance that the SingletonB instance references. In short, SingletonA is not as single as I need it to be. How is this possible? And what magic can I wield to remedy this behaviour, giving me a true singleton?
Try using isset rather than instanceof:
class Singleton {
protected static $instances;
protected function __construct() { }
final private function __clone() { }
public static function getInstance() {
$class = get_called_class();
if (!isset(self::$instances[$class])) {
self::$instances[$class] = new $class;
}
return self::$instances[$class];
}
}
SingletonA and SingletonB are different classes. Although they inherit from the same class, they are separate classes and so they have different static instances.
If you change your code to get 2 instances of SingletonA or 2 instances of SingletonB, you will see the behavior you expect. But because they are different classes, they are not the same singleton.
I'm pretty sure it's because you are using static methods, which are not instanced.
Let's talk OO. :)
SingletonA and SingletonB are of type Singleton
thus it can be said:
SingletonA is Singleton
and
SingletonB is Singleton
i.e. they're both Singleton
The expected meaning of Singleton means there can be only one. Many people from an OO background using your code will be confused.
Usually, implementation of Singleton would be on a per class basis because most OO languages will not be bent to allow the intent of what you are proposing.
That PHP might do (via get_called_class() magic) doesn't mean it should.
I can absolutely accept that from a utilitarian point of view, the accepted answer looks good. Given the niftyness of the accepted answer, I'd propose a name change that doesn't conflict with "standard" Singleton implementation. From a strict OO point of view, one could never inherit from a Singleton, so it really needs a different name.
Related
I've seen this code in multiple projects(usually laravel) that i support now and i can not determine which pattern is this. It looks somewhat alike Factory Method, but it is obviously not and has a stable implementation that pops up here and there.
Personally i like it(nice instatiating method) but i want to know more about it(name, purposes and other information).
Can you help me?
So basically it is like this
class Foo implements Fooable
{
public readonly $bar;
private function make($bar)
{
$instance = new self();
$instance->bar = $bar;
return $instance;
}
public function process($bar) //or execute, that is a cqrs app but i saw that in non-cqrs too
{
$instance = $this->make($bar);
//continue code
}
}
Sometimes there is an protected/private constructor and make is static method that sets up the instance. But there is always a make() method that returns set up self/static instance of class.
I want to define a Singleton base type from which the user will derive his classes, so this is what I thought:
interface SingletonInterface {
public static function getInstance();
}
abstract class SingletonAbstract implements SingletonInterface {
abstract protected function __construct();
final private function __clone() {}
}
But using this aproach the user may implement this singleton...
class BadImpl implements SingletonInterface {
public static function getInstance() {
return new self;
}
}
What would be your aproach?
Remember PHP doesn't allow multiple inheritance so you must carefully choose what you base your classes on. Singleton is so easy to implement it's probably better to let each class define it.
Beware also that private fields are not ported to descendant classes and therefore you can have two different fields with the same name.
I am using this code for creating a Singleton:
abstract class Singleton {
private static $_aInstance = array();
private function __construct() {}
public static function getInstance() {
$sClassName = get_called_class();
if( !isset( self::$_aInstance[ $sClassName ] ) ) {
self::$_aInstance[ $sClassName ] = new $sClassName();
}
$oInstance = self::$_aInstance[ $sClassName ];
return $oInstance;
}
final private function __clone() {}
}
This is using of this pattern:
class Example extends Singleton {
...
}
$oExample1 = Example::getInstance();
$oExample2 = Example::getInstance();
if(is_a( $oExample1, 'Example' ) && $oExample1 === $oExample2){
echo 'Same';
} else {
echo 'Different';
}
First of all: if you have so much Singletons over the project then you probably mess up something on projection level
Second of all: Singleton should be used there, and only there, where more that one instance of a class makes totally no sense or might cause some errors
Finally: the inheritance ain't designed to reduce the amount of code
You can now use traits, but do you need so much singletons ?
I have always used a Singleton class for a registry object in PHP. As all Singleton classes I think the main method looks like this:
class registry
{
public static function singleton()
{
if( !isset( self::$instance ) )
{
self::$instance = new registry();
}
return self::$instance;
}
public function doSomething()
{
echo 'something';
}
}
So whenever I need something of the registry class I use a function like this:
registry::singleton()->doSomethine();
Now I do not understand what the difference is between creating just a normal static function. Will it create a new object if I just use a normal static class.
class registry
{
public static function doSomething()
{
echo 'something';
}
}
Now I can just use:
registry::doSomethine();
Can someone explain to me what the function is of the singleton class. I really do not understand this.
A static function is a function that can be called without creating an object of a class.
registry::doSomething()
A Singleton is a design pattern, that should prevent the users of the class from creating more than one instance of a class. So, there is usually only one instance of a singleton class. A Singleton's constructor should be declared private and have a static method providing a single instance-object:
class Singleton
{
private Singleton()
{
}
private static var $instance = null;
public static getInstance()
{
if(self::$instance == null)
self::$instance = new Singleton();
return self::$instance;
}
}
For more information see http://en.wikipedia.org/wiki/Singleton_pattern
P.S: Sorry for my bad PHP, the syntax may not be 100% correct, but you should roughly understand what I mean in terms of OOP.
The fact that the Singleton is a design-pattern that restricts instantiation of a class to one single object, it is possible to do some stuff that is slightly more difficult with a static class:
Lazy initialization
Replace implementation internally by sub-classing the Factory
Manage via configuration
However, there are several drawbacks to singletons, so it is better in general to use patterns such as Factory as you get additional benefits such as decoupling.
I am working on a PHP library in which we will be supplying our clients with encrypted code. The code will include a main classes which they can instantiate that will handle license verification and expose methods for their use. The main class will instantiate several sub classes each contained in their own file. How can I prevent our clients from including the subclass files and instantiating the sub classes themselves for use? Is there a way to prevent a sub class from being instantiated except from our main class?
Wild guess, but use a Singleton for the main class, and factory/Singleton with dependency injection (of the main class) for all the subclasses. That way the subclasses won't even load without a valid reference to an instance of your primary class.
EDIT: Since this answer was accepted I've decided to provide an example, for the benefit of future readers. Also, don't forget to mark all of your classes as final.
Primary Class:
final class myPrimaryClass {
private static $instance = null;
private function __construct() {
// do something or not
return $this;
}
public static function getInstance() {
if (is_null(self::$instance) || !(self::$instance instanceof myPrimaryClass))
self::$instance = new myPrimaryClass;
return self::$instance;
}
}
Singleton Subclass:
final class mySingletonSubClass {
private static $instance = null;
private function __construct(myPrimaryClass $primaryClassInstanceRef) {
return $this;
}
public static function getInstance(myPrimaryClass $primaryClassInstanceRef) {
if (is_null(self::$instance) || !(self::$instance instanceof mySingletonSubClass))
self::$instance = new mySingletonSubClass($primaryClassInstanceRef);
return self::$instance;
}
}
Factory Subclass:
final class myFactorySubClass {
private function __construct(myPrimaryClass $primaryClassInstanceRef) {
return $this;
}
public static function getNewInstance(myPrimaryClass $primaryClassInstanceRef) {
return new myFactorySubClass($primaryClassInstanceRef);
}
}
Two notes about this example; first, of course I'm grossly oversimplifying the matter. Second, one neat trick you could employ is to modify the subclasses slightly so that the getInstance() methods do not always need to have an instance of the primary class passed as an argument after the first time. I'll provide an example here with the singleton class:
final class mySingletonSubClass {
private static $instance = null;
private static $classInstanceRef = null;
private function __construct(myPrimaryClass $primaryClassInstanceRef) {
return $this;
}
public static function getInstance(myPrimaryClass $primaryClassInstanceRef = null) {
if (!is_null($primaryClassInstanceRef))
self::$classInstanceRef = $primaryClassInstanceRef;
if (is_null(self::$instance) || !(self::$instance instanceof mySingletonSubClass))
self::$instance = new mySingletonSubClass(self::$classInstanceRef);
return self::$instance;
}
}
Please note, this relies heavily on PHP's type-hinting mechanism. As such, you should read the manual entry on it so you understand the nuances (e.g. default null).
I don't think there's a language-supported way, so it'll be down to tricks.
What you could do is add a secret argument to your private class's constructors, which is only known by your main class. If that's not present, throw a NotAllowed exception.
I know it's ugly, and not very safe (yes no-one likes security-through-obscurity), but it might work enough for your specific case...
I know this topic is a little old by now, but I was just thinking that how I'd do this in Java is with Caller Stack Inspection, and doesn't PHP have something similar? In fact it does, though it's a PECL module:
http://www.php.net/manual/en/function.apd-callstack.php
Get the call stack, check it against your code points, throw an exception if it doesn't match. You could even create a common superclass that does this checking for you.
UPDATE: Rephrasing the question to ask, 'are there too many' static methods (I realize that right now there are only 4 but I originally started with 2) in this class structure? If so, any suggestions on how to refactor these classes to use some sort of Finder class so that I can remove the static functions from the Model classes?
I have the following abstract class:
abstract class LP_Model_Abstract
{
protected static $_collectionClass = 'LP_Model_Collection';
protected $_row = null;
protected $_data = array();
public function __construct($row = null)
{
$this->_row = $row;
}
public function __get($key)
{
if(method_exists($this, '_get' . ucfirst($key)))
{
$method = '_get' . ucfirst($key);
return $this->$method();
}
elseif(isset($this->_row->$key))
{
return $this->_row->$key;
}
else
{
foreach($this->_data as $gateway)
{
if(isset($gateway->$key))
{
return $gateway->$key;
}
}
}
}
public function __set($key, $val)
{
if(method_exists($this, '_set' . ucfirst($key)))
{
$method = '_set' . ucfirst($key);
return $this->$method($val);
}
elseif(isset($this->_row->$key))
{
$this->_row->$key = $val;
return $this->_row->$key;
}
else
{
foreach($this->_data as $gateway)
{
if(isset($this->_data[$gateway]->$key))
{
$this->_data[$gateway]->$key = $val;
return $this->_data[$gateway]->$key;
}
}
}
}
public function __isset($key)
{
return isset($this->_row->$key);
}
public function save()
{
$this->_row->save();
}
abstract public static function get($params);
abstract public static function getCollection($params = null);
abstract public static function create($params);
}
And then this class which provides additional functionality for class table inheritance schemes (where type is important in determining additional functionality in a factory fashion):
abstract class LP_Model_Factory_Abstract extends LP_Model_Abstract
{
protected static $_collectionClass = 'LP_Model_Collection_Factory';
abstract public static function factory($row);
}
These ultimately result in the following type of class declaration:
class Model_Artifact extends LP_Model_Factory_Abstract
{
protected static $_artifactGateway = 'Model_Table_Artifact';
public static function create($params)
{
}
public static function get($params)
{
$gateway = new self::$_artifactGateway();
$row = $gateway->fetchArtifact($params);
return self::factory($row);
}
public static function getCollection($params = null)
{
$gateway = new self::$_artifactGateway();
$rowset = $gateway->fetchArtifacts($params);
$data = array(
'data' => $rowset,
'modelClass' => __CLASS__
);
return new self::$_collectionClass($data);
}
public static function factory($row)
{
$class = 'Model_Artifact_' . $row->fileType;
}
}
When do you know that you have too many static methods in a class? And how would you refactor the existing design so that the static methods are perhaps encapsulated in some sort of Finder class?
I'd have to agree with Brubaker and add that to my thinking it isn't the number of methods so much as the functionality of said methods. If you start thinking that your class has to many methods (static or otherwise) then you might find they can be re-grouped and refactored into a more intuitive architecture.
The first indicator I use when determining if I have to many static methods is if the methods functionality is not stateless. If the static methods change the state of the object they reside in, they probably shouldn't be static.
I agree with BaileyP and I'll add my couple of pennies:
I always work with the idea that a class should have a single reason for existing; it should have one job that it does, and it should do it well. After deciding that, and figuring out what the interface to that class should be, I go through and mark any functions that don't change the state of an instance of the class as static.
If you want to build reusable and testable code, you should avoid static methods altogether. Code which calls static methods (or constructors of non-data-like classes) cannot be tested in isolation.
Yes, you will have to pass around alot more objects if you eliminate static methods. This is not necessarily a bad thing. It forces you to think about the boundaries and cooperation between your components in a disciplined way.
Personally I find that any number of static methods are a sign of trouble. If your class has instance methods and static methods, then most likely you could split the class into two separate entities and change the static methods to instance methods.
Think of a class as a special kind of object, with the distinctive property that it is global by nature. Since it's a global variable, it implies a very strong level of coupling, so you would want to reduce any references to it. Static members will need to be referred, meaning that your code will get a strong level of coupling to the class.
I'll throw in my 2 cents.
First of all, I'll agree that setting some sort of arbitrary limit is not helpful, such as "Once I have more than 10 statics in a class that's too many!". Refactor when it makes sense but don't start doing it just because you've hit some imaginary boundary.
I wouldn't 100% agree with Brubaker's comment about stateful vs. stateless - I think the issue is more about classes vs instances. Because a static method can change the value of another static property which is a stateful change.
So, think of it like this - if the method/property is of or pertaining to the class, then it should probably be static. If the method/property is of or pertaining to an instance of the class, it should not be static.