Bug #79373 [Nab]: uninitialized typed property cannot accessed in __get magic method
| From: | requinix@php.net | Date: | Mon, 13 Apr 2020 15:08:05 +0000 |
| Subject: | Bug #79373 [Nab]: uninitialized typed property cannot accessed in __get magic method | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-226559@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=79373&edit=1
ID: 79373
Updated by: requinix@php.net
Reported by: consatan at gmail dot com
Summary: uninitialized typed property cannot accessed in
__get magic method
Status: Not a bug
Type: Bug
Package: Class/Object related
Operating System: Linux
PHP Version: 7.4.3
Block user comment: N
Private report: N
New Comment:
> Note: while this may or may not be interpreted as a bug, it is still a major BC break. In
> practice, a
> PHP 7.4.0 -> 7.4.1 upgrade requires changes in how type properties (public or private) are
> being
> shadowed for lazy-loading purposes.
And in an ideal world the behavior seen in 7.4.0 would not have made it to the release. But it did.
And it was incorrect: initialized and accessible are two different and separate concepts. And
__get/etc. are about accessibility.
Better to fix the bug immediately and break the early adopters than to let it live until 7.5/8.0
where it would create even larger problems.
Previous Comments:
------------------------------------------------------------------------
[2020-04-13 14:47:00] ocramius@php.net
Note: while this may or may not be interpreted as a bug, it is still a major BC break. In practice,
a PHP 7.4.0 -> 7.4.1 upgrade requires changes in how type properties (public or private) are
being shadowed for lazy-loading purposes.
------------------------------------------------------------------------
[2020-03-12 17:12:04] beberlei@php.net
Your example seems to be wrong, you are not accessing Foo::$bar through __get, because its public. I
assume its an error while making the example small and contained.
However the behavior here is correct regardless of __get or public access. You cannot access an
uninitialized typed variable anywhere, before initializing it and this error represents that.
------------------------------------------------------------------------
[2020-03-12 16:56:29] consatan at gmail dot com
Description:
------------
A uninitialized typed property cannot accessed in __get method until unset() it. Test on
7.4.0~7.4.3, 7.4.0 is works.
Test script:
---------------
<?php
class Foo {
public int $bar;
public function __get($name) {
if ('bar' === $name) {
return $this->bar = 1;
}
}
}
$foo1 = new Foo();
var_dump($foo1);
var_dump($foo1->bar);
$foo2 = new Foo();
var_dump($foo2);
unset($foo2->bar);
var_dump($foo2);
var_dump($foo2->bar);
Expected result:
----------------
object(Foo)#1 (0) {
["bar"]=>
uninitialized(int)
}
int(1)
object(Foo)#2 (0) {
["bar"]=>
uninitialized(int)
}
object(Foo)#2 (0) {
["bar"]=>
uninitialized(int)
}
int(1)
Actual result:
--------------
object(Foo)#1 (0) {
["bar"]=>
uninitialized(int)
}
Warning: Uncaught Error: Typed property Foo::$bar must not be accessed before initialization in php
shell code:1
Stack trace:
#0 {main}
thrown in php shell code on line 1
object(Foo)#2 (0) {
["bar"]=>
uninitialized(int)
}
object(Foo)#2 (0) {
["bar"]=>
uninitialized(int)
}
int(1)
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=79373&edit=1