Table of contents

PHP 7.4+ Error: Typed property must not be accessed before initialization

PHP Jun 14, 2021 Viewed 7.3K Comments 0

Issue

In PHP 7.4.6, I use the newly introduced property type hints, like this:

<?php

class Test
{
    private string $foo;

    public function getFoo(): string
    {
        return $this->foo;
    }

    public function setFoo(string $foo): void
    {
        $this->foo = $foo;
    }
}

$test = new Test();
echo $test->getFoo() . PHP_EOL;

But I got an error saying:

Fatal error: Uncaught Error: Typed property Test::$foo must not be accessed before initialization in /develop/test.php on line 9

Error: Typed property Test::$foo must not be accessed before initialization in /develop/test.php on line 9

Call Stack:
    0.0210     395056   1. {main}() /develop/test.php:0
    0.0855     395320   2. Test->getFoo() /develop/test.php:19

Solution

Type declarations can be added to function arguments, return values, and, as of PHP 7.4.0, class properties. 

A property that has never been assigned doesn't have a null value, but it is on an undefined state, which will never match any declared typeundefined !== null.

1. Don't use type declarations

According to the previous versions of PHP 7.4, don't add type declarations.

class Test
{
    private $foo;
    public function getFoo()
    {
        return $this->foo;
    }
    public function setFoo($foo): void
    {
        $this->foo = $foo;
    }
}

2. Set a default value to property

Set a default value to the property. For string type, empty string or other string, but you cannot use null as the default value.

class Test
{
    private string $foo = "";
    ...
}

3. Nullable type

Since PHP 7.4 introduces type-hinting for properties, it is particularly important to provide valid values for all properties, so that all properties have values that match their declared types.

As of PHP 7.1.0, type declarations can be marked nullable by prefixing the type name with a question mark (?). This signifies that the value can be of the specified type or null.

<?php

class Test
{
    private ?string $foo = null;
    public function getFoo(): ?string
    {
        return $this->foo;
    }
    public function setFoo(?string $foo): void
    {
        $this->foo = $foo;
    }
}
Updated Jun 14, 2021