How to use class constructors in PHP

In this simple tutorial you will learn about PHP class constructors.
You are going to see how class constructors work in PHP, what happens with class inheritance, and a new PHP 8 feature called “argument promotion”.
Contents
What are PHP class constructors?
In object-oriented programming, objects are variables of a specific class.
For example:
class Circle
{
public $radius;
public $color;
public $thickness;
}
$myCircle = new Circle();
Here, $myCircle is a variable of the Circle class type.
When you create a class object, PHP looks into the class definition searching for the class constructor.
The class constructor is a special class method named __construct(). This method is executed immediately after creating an object of that class.
So, let’s add a constructor to our Circle class:
class Circle
{
public $radius;
public $color;
public $thickness;
public function __construct() {
$this->radius = 5;
$this->color = 'black';
$this->thickness = 1;
}
}
Our constructor assigns some values to the class properties.
Since the constructor is executed as soon as a new object is created, these values are going to be the default values for every new object.
You can try and see for yourself:
$myCircle = new Circle();
echo $myCircle->radius . '<br>';
echo $myCircle->color . '<br>';
echo $myCircle->thickness . '<br>';
Output:
5
black
1
Constructors are not limited to setting the class properties. They can also call other class methods, execute commands such as echo, connect to databases, and more.
Usually, you want to use constructors to:
- Initialize the class properties to their default values.
- Perform validation checks on input arguments or global variables.
- Initialize class resources, such as database connections and log files.
For example, here is how you can create a custom database wrapper class that automatically connects to the database as soon as you create a new object:
class MyDatabase()
{
private $mysqli;
public function __construct($user, $passwd) {
$this->mysqli = mysqli_connect('localhost', $user, $passwd);
}
}
The constructors’ argument list.
Class constructors support arguments like any normal method.
The constructor’s argument list can include typed arguments, variable-length arguments and default values.
For example:
class Circle
{
public $radius;
public $color;
public $thickness;
public function __construct(int $radius, string $color = 'black', int $thk = 1) {
$this->radius = $radius;
$this->color = $color;
$this->thickness = $thk;
}
}
When you create a new object, you must follow the class constructor’s argument list requirements.
For example, you cannot create an object of our Circle class without arguments (because the $radius argument is required and doesn’t have a default value), or with a string as the first argument (because it must be an int):
$myCircle = new Circle();
/* Fatal error: Too few arguments to function Circle::__construct() */
$myCircle = new Circle('hey');
/* Fatal error: Argument 1 passed to Circle::__construct() must be of the type integer */
$myCircle = new Circle(7);
/* OK! */
Note that class constructors cannot return any value.
The reason is that constructors are meant to return the new object, so it would not make sense to return anything else.
Constructors and class inheritance.
Now let’s see how class constructors work with class inheritance.
Let’s say that you have a parent class and a child class:
class Bird
{
public $wingspan;
public function __construct(int $wingspan = 1) {
$this->wingspan = $wingspan;
}
}
class Parrot extends Bird
{
public $species;
public function __construct() {
$this->species = 'Parrot';
}
}
When you create an object of the child class, PHP executes the child’s constructor. However, the parent class’ constructor is not automatically executed:
$parrot = new Parrot();
echo $parrot->species; /* Outputs "Parrot". */
echo '<br>';
echo $parrot->wingspan; /* Outputs nothing, because $wingspan is not set. */
As explained in this PHP inheritance tutorial, if you want the parent class’ constructor to be executed, then you need to call it explicitly from the child class constructor.
Like this:
class Parrot extends Bird
{
public $species;
public function __construct() {
$this->species = 'Parrot';
parent::__construct();
}
}
$parrot = new Parrot();
echo $parrot->species; /* Outputs "Parrot". */
echo '<br>';
echo $parrot->wingspan; /* Outputs "1". */
The child class’ constructor does not need to have an arguments list compatible with the parent class’ constructor.
In other words, you can set any argument list for the child class’ constructor, no matter which arguments the parent class constructor takes.
Forbidden constructors: private and abstract.
There are two cases when you cannot call a class constructor.
First case: you cannot call an abstract constructor of an abstract class, just like you cannot call any abstract method.
For example:
abstract class Bird
{
abstract public function __construct();
}
class Parrot extends Bird
{
public $species;
public function __construct() {
$this->species = 'Parrot';
parent::__construct();
}
}
$parrot = new Parrot();
Fatal error: Cannot call abstract method Bird::__construct()
But you can call a non-abstract constructor from the parent class, even if the class itself is abstract:
abstract class Bird
{
public function __construct() {}
}
class Parrot extends Bird
{
public $species;
public function __construct() {
$this->species = 'Parrot';
parent::__construct();
}
}
$parrot = new Parrot(); /* OK */
Second case: if you set the constructor visibility to protected or private, then you cannot create an object of that class:
class Parrot
{
protected function __construct() {}
}
$parrot = new Parrot();
Fatal error: Call to protected Parrot::__construct() from invalid context
Now, you may wonder: why would you want to prevent objects from being created?
Well, in some cases you want to be able to create class objects only from the class itself, by using static methods.
One of such cases is when you want to simulate multiple constructors. If you want to know more, you can find more details here (under the Static creation methods section).
PHP 8 argument promotion.
PHP 8 introduced a new way to automatically define class properties directly from the constructor.
Here’s the idea:
For each constructor argument, you can automatically turn that argument into a class property by adding a visibility modifier.
This feature is called constructor promotion.
For example:
class Circle
{
public $thickness;
public function __construct(public int $radius, public string $color = 'black', int $thickness = 1)
{
$this->thickness = $thickness;
}
}
The $radius and $color arguments have the public visibility modifier, therefore they are automatically turned into public class properties by the constructor.
You can also define protected and private arguments, and they will be turned into protected and private properties respectively.
When you use this syntax, you do not need to create the properties explicitly in the class.
The $thickness argument, on the other hand, does not have the visibility modifier in the argument list. Therefore, you need to define it explicitly in the class.
Conclusion
In this tutorial you learned how PHP class constructors work.
We looked at the constructors’ arguments list, the class inheritance rules, and the two cases when you cannot call class constructors directly.
Finally, we looked at PHP 8 argument promotion and saw some examples.
There will be more tutorials about OOP.
If there are specific topics you would like me to write about, let me know in the comments.
Be sure to subscribe to my free newsletter to get my weekly tips.
Alex
Image copyright: Building maintenance vector created by macrovector – www.freepik.com
Nice article!
Did you explain constructors and destructors in another part of the site?
Thanks
Thank you John.
I haven’t written about destructors yet, but that’s a good suggestion for my next article 🙂