|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #78480 The typed properties miss an important "function"
Submitted: 2019-08-30 21:27 UTC Modified: 2021-05-27 14:45 UTC
Avg. Score:4.5 ± 0.8
Reproduced:5 of 5 (100.0%)
Same Version:5 (100.0%)
Same OS:4 (80.0%)
From: manchokapitancho at gmail dot com Assigned:
Status: Wont fix Package: Scripting Engine problem
PHP Version: 7.4.0beta4 OS:
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
Block user comment
Status: Assign to:
Bug Type:
From: manchokapitancho at gmail dot com
New email:
PHP Version: OS:


 [2019-08-30 21:27 UTC] manchokapitancho at gmail dot com
The new PHP 7.4 feature - typed properties is a great addition to the language.
As a side effect it adds a brand new state of the class/object properties - initialized=yes/no.
If one tries to access an uninitialized property, a TypeError is being thrown.
isset($object->prop) does not trigger TypeError but it returns false if $object->prop is NULL.
The suggested check is only indirectly possible via the long construct
(new ReflectionProperty(<name>::class, '<prop>'))->isInitialized($obj)

On the other side, unset works perfectly well and returns a property back into the uninitialized state.

This write-only asymmetry is not consistent and I would expect a language construct similar to isset [e.g. is_initialized($obj->prop)] that handles this case.

Test script:
class test {
	public ?int $prop;
$obj = new test;


$obj->prop = null;


Expected result:

Actual result:


Add a Patch

Pull Requests

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2019-08-31 11:42 UTC]
What's your use-case?

A language construct for this is very unlikely, but if this is a common and performance-critical operation, a plain function could be provided in lieu of going through reflection.
 [2019-08-31 14:05 UTC] manchokapitancho at gmail dot com
A simplified use case would be:

//orm with lazy loading from DB
class something {
 public ?<class|self> $parent;
function getParent() {
 if (! is_initialized($this->parent)) {
 $this->parent = //fetch from DB; value could be NULL
 return $this->parent;

A plain function is indeed possible but the call parameters should be ($obj, 'prop) since ($obj->prop) would throw TypeError.
 [2019-09-08 18:10 UTC]
You can use `__get` to check if it's initialized. 

see the Overloaded Properties section of the RFC( as an example.
 [2019-09-09 18:10 UTC] manchokapitancho at gmail dot com
I know that I can use __get but:
1. this is a workaround (which is also not simpler than a ReflectionProperty call).
2. this is only possible if the developer has control over the class. A counterexample would be a typed property in a class exposed by a third party library.

Once again: the target is "if (!is_initialized($obj->prop)) { ... }" similar to 
"if (!isset($obj->prop)) { ... }". Isset would not generate a notice if the property is not defined and similarly is_initialized should not trigger a TypeError if $obj->prop has not been yet initialized.
 [2019-11-07 11:03 UTC]
-Type: Bug +Type: Feature/Change Request
 [2020-12-04 10:15 UTC] a dot haan at iwink dot nl
[2019-09-08 18:10 UTC] writes:

You can use `__get` to check if it's initialized. 

That's not completely true - in PHP 7.4.11.

In the first example on

if you do not include `unset($this->typed);`, then that example still throws:

Fatal error: Uncaught Error: Typed property Test::$typed must not be accessed before initialization in test.php on line 24

That line is the first `var_dump($test->typed);`.

Apparently this little edge case was not covered when implementing the RFC.

Regarding this mentioned issue there is another option to test for initialized state: `array_key_exists('prop', get_object_vars($obj));`
Not very neat either.
 [2020-12-04 10:50 UTC] a dot haan at iwink dot nl
Ah. With that behavior of `__get` changed. There's now a difference between uninitialized and unset properties.

That makes this request more apparent.

We used to mix types for micro cache properties; start as `false`, ending up with `null`, or an object instance. By strict checking for `false` retrieval is only done once.

Since mixing types is a bad practice, and not an option with typed properties anyway, it would be ideal if one could detect whether a property was actually uninitialized.

Sure, we can. Two ways are mentioned here. But both are verbose and require representing the property as a string.
 [2020-12-07 04:34 UTC] marrtins at dqdp dot net
I completely agree such is_initialized() would be useful for typed properties. Another use case would be for passing data to database.

Distinction would be useful:
If property hasn't been initialized - ignore it.
If property has been set to null - set database field to null.
 [2021-02-26 09:58 UTC] heiko at jerichen dot de
Working with graphql provides an other use case.
When you have a ?float field with null, it means delete this value. When not provided with graphql (would resolve to uninitialized) than ignore it.
 [2021-05-27 14:45 UTC]
-Status: Open +Status: Wont fix
 [2021-05-27 14:45 UTC]
After discussion as a result of

It has transpired that we collectively do not want to go in this direction at this time, and it's highly unlikely this will change, in my opinion.

Closing as won't fix.

Anyone is free to pursue an RFC, which would be required - but ill advised given the overwhelming negative feedback.
PHP Copyright © 2001-2022 The PHP Group
All rights reserved.
Last updated: Fri Jul 01 08:05:45 2022 UTC