rushlow.dev

PHP 7.4 Typed Properties BC Problems

Updated: April 25, 2024 20:52

Published: December 27, 2019 02:13

If you’re not aware, PHP 7.4 has introduced Typed Properties. But buyer beware, there‘s a hitch...

Prior to PHP 7.4, declaring property scalar types was done with DocBlocks as follows:

1
/** @var int|null **/
2
public $id;
3

With typed properties introduced in PHP 7.4, the scalar type can now be set like this:

1
public ?int $id;
2

This is awesome, it cuts down on excessive boilerplate and the PHP interpreter will not allow an invalid value to be set on the property.

But, there are a couple caveats to be aware of...

Without setting a property type, one would be able to have a class property such as:

1
// MyClass.php
2
3
<?php
4
class MyClass {
5
6
/** @var int|null **/
7
public $id;
8
}
9

And then call the property without any problems like:

1
// test.php
2
3
<?php
4
require('MyClass.php');
5
6
$object = new MyClass;
7
$var = $object->id;
8
9
var_dump($var);
10
    
$:> php -f test.php
NULL
                

However, if you declare the property type and then attempt to access that type as above, you'll get a FatalError. I.e.

1
// test.php
2
3
<?php
4
class MyClass {
5
6
public ?int $id;
7
}
8
9
$object = new MyClass;
10
$var = $object->int;
11
12
echo $var;
13
    
$:> php -f test.php
Fatal error: Uncaught Error: Typed property MyClass::$id must not be accessed before initialization...
                

To overcome this, you must set the value of $id before attempting to access it. This can be accomplished in a number of ways.

1
class MyClass
2
{
3
public ?int $id = null;
4
}
5
1
class MyClass
2
{
3
public ?int $id;
4
5
public function __construct() {
6
$this->id = null;
7
}
8
}
9
1
class MyClass {
2
3
public ?int $id;
4
5
public function setId(?int $id) {
6
$this->id = $id;
7
}
8
}
9

Using any of the above means of setting $id before accessing the value of $id would result in the following:

1
// MyClass.php
2
<?php
3
class MyClass {
4
5
public ?int $id = null;
6
}
7
8
$object = new MyClass;
9
10
$var = $object->id;
11
12
var_dump($var;)
13
    
$:> php -f  MyClass.php
NULL
                

Of course if you are using setter's to set the value of $id , you must call the setter method before accessing the property.

- Jesse Rushlow [email protected]