I'm using PHP 7.1.11
Consider below working code and its output :
<?php
class butto {
public static $instance;
private function __construct() {
echo 'Contruct of butto class called</br>';
}
public static function get_instance() {
if(!static::$instance instanceof static) {
static::$instance = new static();
}
return static::$instance;
}
public function test () {
echo 'test function called</br>';
}
}
class B extends butto {
public static $instance;
protected function __construct() {
echo 'Construct of Class B called</br>';
}
public static function get_class_name() {
return __CLASS__;
}
}
butto::get_instance()->test();
B::get_instance()->test();
B::get_instance()->test();
/*Output : Contruct of butto class called
test function called
Construct of Class B called
test function called
test function called*/
?>
If you look at the code closely you will come to know that constructors of both the classes are getting called even without creating an object of any of the classes.
The constructors are getting called even when I access any static method statically. Until now I knew that constructors can only be called upon object creation as the purpose of constructors is to set initial values into the object properties and make it usable as soon as it gets created.
Then how this is possible? What's the benefit of using constructors in this way i.e. accessing without creating an object?
Consider below code lines :
B::get_instance()->test();
B::get_instance()->test();
My question is why the constructor of class B is getting called for the first line only?
It is supposed to be called again for the second line as well.
Why it's behaving in such weird manner?
Because your
get_instance()
itself has the logic that way. You are assigning instance to your static variable. Static variable are "shared" between different instances of same class. So when you call your functionget_instance()
first time, you are creating object and storing it in your static variable$instance
. Next time when you are calling same function, your if condition turns out to be false and hence does not need to create a new object/instance. Look at the following code again:It is not behaving in weird manner, but it is behaving as your code asked it to behave.