Related to #1589
Analysis
The RFC had 2 proposals:
- Non-readonly classes can extend readonly classes in PHP 8.3: ❌ did not pass
- Readonly properties can be reinitialized during cloning in PHP 8.3: ✅ passed
Summary of existing PHP 8.2 behavior based on the RFC:
class Foo {
public function __construct(
public readonly string $bar,
public readonly string $baz
) {}
public function __clone()
{
unset($this->baz); // Fatal error
$this->bar = 'new value'; // Fatal error
}
}
$foo = new Foo('bar', 'baz');
clone $foo;
Updated behavior in PHP 8.3:
class Foo {
public function __construct(
public readonly string $bar,
public readonly string $baz
) {}
public function __clone()
{
unset($this->baz); // Uninitializing is allowed
unset($this->baz); // Uninitializing a second time is allowed
$this->bar = 'new value'; // Reinitializing to a new value is allowed
$this->bar = 'new value'; // Fatal error: cannot reinitialize a second time, even if it's the same value
}
}
$foo = new Foo('bar', 'baz');
clone $foo;
Top 2000 Packages
Detection in PHP 8.2
Assuming the property is readonly:
function __clone() { unset($this->bar); } Unset in __clone: error
function __clone() { $this->bar = 'new value'; } Assign in __clone: error
Detection in PHP 8.3
Assuming the property is readonly:
function __clone() { unset($this->bar); } Unset in __clone: valid
function __clone() { unset($this->bar); unset($this->bar); } Repeated unset in __clone: valid
function __clone() { $this->bar = 'new value'; } Assign in __clone: valid
function __clone() { $this->bar = 'new value'; $this->bar = 'new value'; } Repeated assign in __clone: error
Syntax Variations
Detectability
- Find readonly properties ✅ Already done in the original sniff
- Find assignment in __clone ✅❌ Partially doable, as __clone can call other methods in other files
- Find unsetting in __clone ✅❌ Partially doable, as __clone can call other methods in other files
References
Related to #1589
Analysis
The RFC had 2 proposals:
Summary of existing PHP 8.2 behavior based on the RFC:
Updated behavior in PHP 8.3:
Top 2000 Packages
Detection in PHP 8.2
Assuming the property is readonly:
function __clone() { unset($this->bar); }Unset in __clone: errorfunction __clone() { $this->bar = 'new value'; }Assign in __clone: errorDetection in PHP 8.3
Assuming the property is readonly:
function __clone() { unset($this->bar); }Unset in __clone: validfunction __clone() { unset($this->bar); unset($this->bar); }Repeated unset in __clone: validfunction __clone() { $this->bar = 'new value'; }Assign in __clone: validfunction __clone() { $this->bar = 'new value'; $this->bar = 'new value'; }Repeated assign in __clone: errorSyntax Variations
Detectability
References