Using constructor property promotion
Aside from the Just-In-Time (JIT) compiler, one of the greatest new features introduced in PHP 8 is constructor property promotion. This new feature combines property declarations and argument lists in the __construct()
method signature, as well as assigning defaults. In this section, you will learn how to substantially reduce the amount of coding required in property declarations as well as in the __construct()
method signature and body.
Property promotion syntax
The syntax needed to invoke constructor property promotion is identical to that used in PHP 7 and earlier, with the following differences:
- You need to define a visibility level
- You do not have to explicitly declare the properties in advance
- You do not need to make assignments in the body of the
__construct()
method
Here is a bare-bones example of code that uses constructor property promotion:
// /repo/ch01/php8_prop_promo.php declare(strict_types=1); class Test { public function __construct( public int $id, public int $token = 0, public string $name = '') { } } $test = new Test(999); var_dump($test);
When the preceding code block is executed, this is the output:
object(Test)#1 (3) { ["id"]=> int(999) ["token"]=> int(0) ["name"]=> string(0) "" }
This shows that an instance of Test
type has been created using default values. Now, let's have a look at how this feature might save a substantial amount of coding.
Using property promotion for code reduction
In a conventional OOP PHP class, the following three things need to be done:
- Declare the properties, as follows:
/repo/src/Php8/Image/SingleChar.php namespace Php7\Image; class SingleChar { public $text = ''; public $fontFile = ''; public $width = 100; public $height = 100; public $size = 0; public $angle = 0.00; public $textX = 0; public $textY = 0;
- Identify the properties and their data type in the
__construct()
method signature, as follows:const DEFAULT_TX_X = 25; const DEFAULT_TX_Y = 75; const DEFAULT_TX_SIZE = 60; const DEFAULT_TX_ANGLE = 0; public function __construct( string $text, string $fontFile, int $width = 100, int $height = 100, int $size = self::DEFAULT_TX_SIZE, float $angle = self::DEFAULT_TX_ANGLE, int $textX = self::DEFAULT_TX_X, int $textY = self::DEFAULT_TX_Y)
- In the body of the
__construct()
method, assign values to properties, like this:{ $this->text = $text; $this->fontFile = $fontFile; $this->width = $width; $this->height = $height; $this->size = $size; $this->angle = $angle; $this->textX = $textX; $this->textY = $textY; // other code not shown }
As the number of constructor arguments increases, the amount of work you need to do also increases significantly. When constructor property promotion is applied, the amount of code required to do the same as previously shown is reduced to one-third of the original.
Let's now have a look at the same block of code as shown previously, but rewritten using this powerful new PHP 8 feature:
// /repo/src/Php8/Image/SingleChar.php // not all code shown public function __construct( public string $text, public string $fontFile, public int $width = 100, public int $height = 100, public int $size = self::DEFAULT_TX_SIZE, public float $angle = self::DEFAULT_TX_ANGLE, public int $textX = self::DEFAULT_TX_X, public int $textY = self::DEFAULT_TX_Y) { // other code not shown }
Amazingly, what took 24 lines of code in PHP 7 and earlier can be collapsed into eight lines of code using this new PHP 8 feature!
You are completely free to include other code in the constructor. In many cases, however, constructor property promotion takes care of everything normally done in the __construct()
method, which means you can literally leave it empty ({ }
).
Now, in the next section, you learn about a new feature called attributes.
Tip
Have a look at the full SingleChar class for PHP 7 here:
https://github.com/PacktPublishing/PHP-8-Programming-Tips-Tricks-and-Best-Practices/tree/main/src/Php7/Image
Also, the equivalent PHP 8 class is found here:
https://github.com/PacktPublishing/PHP-8-Programming-Tips-Tricks-and-Best-Practices/tree/main/src/Php8/Image
For more information on this new feature, have a look at the following:
https://wiki.php.net/rfc/constructor_promotion