What does new self(); mean in PHP?

This seems to be an implementation of the Singleton pattern. The function is called statically and checks whether the static class has the variable $_instance set.

If it isn't, it initializes an instance of itself (new self()) and stores it in $_instance.

If you call className::getInstance() you will get one and the same class instance on every call, which is the point of the singleton pattern.

I've never seen it this done this way, though, and honestly didn't know it was possible. What is $_instance declared as in the class?


This is most likely used in singleton design pattern, wherein the constructor is defined as private so as to avoid being instantiated, the double colon (::) operator can access members that are declared static inside the class, so if there are static members, the pseudo variable $this cannot be used, hence the code used self instead, Singletons are good programming practices that will only allow 1 instance of an object like database connector handlers. From client code, accessing that instance would be done by creating a single access point, in this case he named it getInstance(), The getInstance in itself was the function that created the the object basically using the new keyword to create an object meaning the constructor method was also called.

the line if(!isset(self::instance)) checks if an object has already been created, you could not understand this becuase the code is just a fragment, somewhere in the top, there should be static members like probably

private static $_instance = NULL; 

in normal classes we would have accessed this member by simply

$this->_instance = 'something';

but its declared static and so we could not use the $this code we use instead

self::$_instance

by checking if there is an object stored on this static class variable, the class can then decide to create or not to create a single instance, so if its not set, !isset, meaning no object exists on the static member $_instance, then it generates a new object, stored it in the static member $_instance by the command

self::$_instance = new self();

and returned it to client code. The client code can then happily use the single instance of the object with its public methods, but in the client code, calling the single access point, that is, the getInstance() method is also tricky, it has to be called like this

$thisObject = className::getInstance();

the reason, the function in itself is declared static.


self points to the class in which it is written.

So, if your getInstance method is in a class name MyClass, the following line :

self::$_instance = new self();

Will do the same as :

self::$_instance = new MyClass();


Edit : a bit more information, after the comments.

If you have two classes that extend each other, you have two situations :

  • getInstance is defined in the child class
  • getInstance is defined in the parent class

The first situation would look like this (I've removed all non-necessary code, for this example -- you'll have to add it back to get the singleton behavior)* :

class MyParentClass {
    
}
class MyChildClass extends MyParentClass {
    public static function getInstance() {
        return new self();
    }
}

$a = MyChildClass::getInstance();
var_dump($a);

Here, you'll get :

object(MyChildClass)#1 (0) { } 

Which means self means MyChildClass -- i.e. the class in which it is written.


For the second situation, the code would look like this :
class MyParentClass {
    public static function getInstance() {
        return new self();
    }
}
class MyChildClass extends MyParentClass {
    
}

$a = MyChildClass::getInstance();
var_dump($a);

And you'd get this kind of output :

object(MyParentClass)#1 (0) { }

Which means self means MyParentClass -- i.e. here too, the class in which it is written.




With PHP That's why PHP 5.3 introduces a new usage for the static keyword : it can now be used exactly where we used self in those examples :
class MyParentClass {
    public static function getInstance() {
        return new static();
    }
}
class MyChildClass extends MyParentClass {
    
}

$a = MyChildClass::getInstance();
var_dump($a);

But, with static instead of self, you'll now get :

object(MyChildClass)#1 (0) { } 

Which means that static sort of points to the class that is used (we used MyChildClass::getInstance()), and not the one in which it is written.

Of course, the behavior of self has not been changed, to not break existing applications -- PHP 5.3 just added a new behavior, recycling the static keyword.


And, speaking about PHP 5.3, you might want to take a look at the [Late Static Bindings][1] page of the PHP manual.

Tags:

Php

Class

Self