Use
$this
to refer to the current object. Useself
to refer to the current class. In other words, use$this->member
for non-static members, useself::$member
for static members.
In the example below, sayHello()
and sayGoodbye()
are using self
and $this
difference can be observed here.
class Person {
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
public function getTitle() {
return $this->getName()." the person";
}
public function sayHello() {
echo "Hello, I'm ".$this->getTitle()."<br/>";
}
public function sayGoodbye() {
echo "Goodbye from ".self::getTitle()."<br/>";
}
}
class Geek extends Person {
public function __construct($name) {
parent::__construct($name);
}
public function getTitle() {
return $this->getName()." the geek";
}
}
$geekObj = new Geek("Ludwig");
$geekObj->sayHello();
$geekObj->sayGoodbye();
static
refers to whatever class in the hierarchy you called the method on. It allows for better reuse of static class properties when classes are inherited.
Consider the following code:
class Car {
protected static $brand = 'unknown';
public static function brand() {
return self::$brand."\n";
}
}
class Mercedes extends Car {
protected static $brand = 'Mercedes';
}
class BMW extends Car {
protected static $brand = 'BMW';
}
echo (new Car)->brand();
echo (new BMW)->brand();
echo (new Mercedes)->brand();
This doesn't produce the result you want:
unknown
unknown
unknown
That's because self
refers to the Car
class whenever method brand()
is called.
To refer to the correct class, you need to use static
instead:
class Car {
protected static $brand = 'unknown';
public static function brand() {
return static::$brand."\n";
}
}
class Mercedes extends Car {
protected static $brand = 'Mercedes';
}
class BMW extends Car {
protected static $brand = 'BMW';
}
echo (new Car)->brand();
echo (new BMW)->brand();
echo (new Mercedes)->brand();
This does produce the desired output:
unknown
BMW
Mercedes
See also Late static binding
If you have an object that's expensive to create or represents a connection to some external resource you want to reuse, i.e. a database connection where there is no connection pooling or a socket to some other system, you can use the static
and self
keywords in a class to make it a singleton. There are strong opinions about whether the singleton pattern should or should not be used, but it does have its uses.
class Singleton {
private static $instance = null;
public static function getInstance(){
if(!isset(self::$instance)){
self::$instance = new self();
}
return self::$instance;
}
private function __construct() {
// Do constructor stuff
}
}
As you can see in the example code we are defining a private static property $instance
to hold the object reference. Since this is static this reference is shared across ALL objects of this type.
The getInstance()
method uses a method know as lazy instantiation to delay creating the object to the last possible moment as you do not want to have unused objects lying around in memory never intended to be used. It also saves time and CPU on page load not having to load more objects than necessary. The method is checking if the object is set, creating it if not, and returning it. This ensures that only one object of this kind is ever created.
We are also setting the constructor to be private to ensure that no one creates it with the new
keyword from the outside. If you need to inherit from this class just change the private
keywords to protected
.
To use this object you just write the following:
$singleton = Singleton::getInstance();
Now I DO implore you to use dependency injection where you can and aim for loosely coupled objects, but sometimes that is just not reasonable and the singleton pattern can be of use.