DEV Community

Jesse Rushlow
Jesse Rushlow

Posted on • Originally published at rushlow.dev on

PHP 7.4 Typed Properties BC Problems

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

/ **@var int|null** /
public $id;

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

public ?int $id;

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:

//class.php

<?php
class MyClass {

    / **@var int|null** /
    public $id;
}

And then call the property without any problems like:

//test.php

<?php
require('class.php');

$object = new MyClass;
$var = $object->id;

var_dump($var);

$:> 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.

//test.php

<?php
class MyClass {

    public ?int $id;
}

$object = new MyClass;
$var = $object->int;

echo $var;

$:> 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.

class MyClass {

    public ?int $id = null;
}

class MyClass {

    public ?int $id;

    public function __construct() {
        $this->id = null;
    }
}

class MyClass {

    public ?int $id;

    public function setId(?int $id) {
        $this->id = $id;
    }
}

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

//class.php
<?php
class MyClass {

    public ?int $id = null;
}

$object = new MyClass;

$var = $object->id;

var_dump($var;)

$:> php -f class.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.

Top comments (0)