[php-src] Issue #8204: Nullsafe Operator doesn't work with uninitialized properties
| From: | iw-rylee | Date: | Wed, 16 Mar 2022 06:39:16 +0000 |
| Subject: | [php-src] Issue #8204: Nullsafe Operator doesn't work with uninitialized properties | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-240352@lists.php.net to get a copy of this message | ||
Issue: https://github.com/php/php-src/issues/8204
Author: iw-rylee
### Description
The following code:
```php
<?php
class SomeClass {
public DateTime $date_val;
}
$some = new SomeClass;
// Test 1
echo $some->date_val?->format("Y-m-d") ?? "default";
// Test 2
echo $some?->date_val?->format("Y-m-d") ?? "default";
// Test 3
echo ($some->date_val ?? null)?->format("Y-m-d") ?? "default";
// Test 4
echo ($some?->date_val ?? null)?->format("Y-m-d") ?? "default";
```
Resulted in this output:
```
// Test 1 - throws Fatal Error
// Test 2 - throws Fatal Error
// Test 3 - outputs "default" as expected
// Test 4 - outputs "default" as expected
```
But I expected this output instead:
```
All tests to output "default"
```
The alternative approach is:
```php
class SomeClass {
public ?DateTime $date_val = null;
}
```
However, doing this "marks"
SomeClass::$date_val as "possibly being
null".
The expected use case for the original class:
>A "valid" SomeClass should always have
>Ê&¡XÒŸWFèËFh$date typed as DateTime instead of
>being typed as null OR DateTime
We can potentially:
* set $date_val to be protected
* override the magic __get method to return $this->{$name} ?? null;
This works **outside** the class, but not within it:
```php
class SomeClass {
protected DateTime $date_val;
public function __get(string $name): mixed {
return $this->{$name} ?? null;
}
public function toArray(){
return [
"date_val" => $this->date_val?->format("Y-m-d") ??
"default",
];
}
}
$some = new SomeClass;
// Test 1 - this works and outputs "default"
echo $some->date_val?->format("Y-m-d") ?? "default";
// Test 2 - this throws a Fatal Error
var_dump($some->toArray());
```
The magic method __isset() is not called in any of the above cases where a Fatal
Exception is thrown.
### PHP Version
PHP 8.0.2
### Operating System
Windows 10