Solve the Typed property X must not be accessed before initialization error
If you are new to using typed properties in PHP 7.4 and above, you have probably encountered the "Typed property X must not be accessed before initialization" error.
Why the error occures
To solve this problem, you need to know that PHP initializes the parameters of a class differently depending on whether they are type parameters or not. For example let's take the following legacy code:
class UserA {
public $id;
public $userName;
}
$userA = new UserA();
echo '<pre>';
var_dump($userA);
echo '</pre>';
echo 'The $userA->id is: >' . $userA->id . '<';
The output looks like this:
object(UserA)#1 (2) {
["id"]=>
NULL
["userName"]=>
NULL
}
The $userA->id is: ><
As you can see the class properties are automatically initialized with NULL
values.
And now use typed properties:
class UserB {
public ?int $id;
public string $userName;
}
$userB = new UserB();
echo '<pre>';
var_dump($userB);
echo '</pre>';
echo 'The $userB->id is: >' . $userB->id . '<';
Where the output is:
object(UserB)#1 (0) {
["id"]=>
uninitialized(?int)
["userName"]=>
uninitialized(string)
}
Fatal error: Uncaught Error: Typed property UserB::$id must not be accessed before initialization in ...
As you can see in this case the value of the class propertik has not been initialized. They were simply left uninitialized
.
And this brings us to the source of the problem. The id
variable is defined to be either int
or null
. But the uninitialized
value is neither int
nor null
.
Solution
The solution is simple. For typed properties, you always have to initialize the variable explicitly.
You can do this either by specifying a default value:
class UserB {
public ?int $id = null;
public string $userName;
}
or by using the constructor:
class UserB {
public ?int $id;
public string $userName;
/**
* UserB constructor.
* @param int|null $id
* @param string $userName
*/
public function __construct(?int $id, string $userName)
{
$this->id = $id;
$this->userName = $userName;
}
}
References