references & arrays + hooks
| From: | Rob Landers | Date: | Thu, 31 Jul 2025 08:46:50 +0000 |
| Subject: | references & arrays + hooks | ||
| Groups: | php.internals | ||
| Request: | Send a blank email to internals+get-128334@lists.php.net to get a copy of this message | ||
Hello internals:
Currently, this is not allowed by PHP:
class Foo {
public function __construct(
public string &$ref { get => $this->ref ?? 'null'; set => $this->ref
= $value; }
) {}
}
$var = 'hello';
$foo = new Foo($var);
$var = "world";
echo $foo->ref;
https://3v4l.org/JRArK
Currently, you have to emulate it like so:
class Foo {
public string $ref {
get => $this->_ref;
set => $this->_ref = $value;
}
public function __construct(
private string &$_ref,
) {}
}
$var = 'hello';
$foo = new Foo($var);
$foo->ref = 'world';
echo $var;
https://3v4l.org/0cC0S
After the release, I'd like to propose an RFC that allows using references with hooks:
A hooked reference variable is a callable/closure under the hood (technically, a reference to the
actual hook methods) that can be used like a value. Reading from it calls the ::get() method, and
setting to it calls the ::set($value) method. If the callable were to be written in PHP, it might
look something like the following psuedo code:
function hookRef(...$args) use (&$backedValue) {
if(empty($args)) return $backedValue::get();
$backedValue = $backedValue::set(array_first($args));
}
In simplified terms, the engine, upon detecting a read/write to a hooked reference (eg, a standalone
variable pointing to a hooked property), instead of doing typical variable access, it will call the
bound closure with the appropriate arguments. This will effectively allow hooks to be references.
This would also handle the case for arrays, which appears to require the same plumbing to exist.
Downsides:
1. this will probably necessitate a new zval type, determined at runtime (it will not be exposed to
users).
2. there are a lot of ways to access/write to a variable (especially once you consider arrays) thus
it will touch a lot of the engine.
Thoughts? Concerns? Suggestions?
— Rob