|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2019-12-03 22:24 UTC] public at grik dot net
Description:
------------
Unitialized properties make unpredictabe side effects.
In fact, unitialized property is a Schrödinger property - it both exists and does not exist at the same time.
All popular frameworks use magic getters in base classes.
Having __get() called for uninitialized properties makes initialization in declaration to be obligatory, or face unpredictable side effects, as it was in Pascal 30 years ago.
Scripting languages were inteneded to help avoid obligatory initialization in declaration.
Test script:
---------------
<?php
abstract class Base{
public function __get($name){echo 'magic';}
}
class A extends Base{
public string $x;
public ?string $y;
public $z;
}
$A = new A;
var_dump(get_object_vars($A)); //array(0) {}
var_dump(property_exists($A,'x'));//true
$A->z; // __get is not executed
$A->y; // magic - __get() is executed
$A->x; //Fatal error
Expected result:
----------------
array(3) {
["x"]=>
NULL
["y"]=>
NULL
["z"]=>
NULL
}
bool(true)
Actual result:
--------------
array(1) {
["z"]=>
NULL
}
bool(true)
magicmagic
Fatal error: Uncaught TypeError: Typed property A::$x must be string, null used
PatchesPull Requests
Pull requests:
HistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sun Oct 26 22:00:01 2025 UTC |
Thank you for reply. By doing unset first I have to explicitly put all the unset thing in constructor. In my opinion, this comes with time and resource penalty and makes code less readable. Before fix (7.4.0): class A { use GetMagicTrait; private Foo $a; private Bar $b; private Baz $z; } After fix (7.4.1+): class A { use GetMagicTrait; private Foo $a; private Bar $b; private Baz $z; function __construct() { unset($this->$a, $this->b, $this->z); } } Anyway I have read the rfc for typed properties briefly and if I understand it correctly, this fix breaks it starting with section https://wiki.php.net/rfc/typed_properties_v2#uninitialized_and_unset_properties. I would like to explain, what I want to achieve. As of php7.4 not nullable typed properties can have 3 different states: 1. Not Initialized 2. Not Set (Initialized) 3. Set (Initialized) So whenever I use unset I'm making its state unset (2) and __get is working. Problem is, we cannot define typed property as unset, only "Not Initialized" or "Initialized" I would like to be able to define unset state at the property instead of "Not Initialized". This would avoid using explicit unset in constructors. I like typescript ! operator so final property definition could use one of: class A { use GetMagicTrait; private Foo $a!; private Bar! $b; private ! Baz $z; private unset Bay $f; } where "private unset Foo $a" could be equivalent to shorter use with !. Can I write RFC for this? Are there any guidelines for RFCs? What timeline could be expected for implementation?