Description
Hey there!
I came across the following...
public string $path = '%s/foo/%s' {
get => sprintf($this->path, $this->name, str_replace('output', '%s', basename($this->stub)));
}
which works. PHPStorm offers a refactor to:
public string $path = '%s/foo/%s' {
get => $this->stub
|> basename(...)
|> (fn($x) => str_replace('output', '%s', $x))
|> (fn($x) => sprintf($this->path, $this->name, $x));
}
Which results in:
Fatal error: Cannot specify default value for virtual hooked property
The RFC explicitly shows such example, although without default value. There is, however, no word about that using pipes in hooks would turn a backed hooked property into a virtual property. Hence, I would have expected it to work. Then I tried:
public function __construct(
public string $path = '%s/foo/%s' {
get => sprintf($this->path, $this->name, str_replace('output', '%s', basename($this->stub)));
}
) {}
Which works, with and without passing $path to the constructor. Then I again apply the proposed refactor...
public function __construct(
public string $path = '%s/foo/%s' {
get => $this->stub
|> basename(...)
|> (fn($x) => str_replace('output', '%s', $x))
|> (fn($x) => sprintf($this->path, $this->name, $x));
}
) {}
which with and without passing $path to the constructor results in:
Fatal error: Uncaught Error: Property x::$path is read-only in
even though there is no readonly involved at all.
Nothing of this seems expected to me. Feels similar to what was added as errata regarding arrow functions, but wrapping the whole thing into parentheses does not help (and is not mentioned in the RFC), and get {} has the same issues.
PHP Version
PHP 8.5.7 (cli) (built: Jun 2 2026 20:59:56) (NTS)
Copyright (c) The PHP Group
Built by Homebrew
Zend Engine v4.5.7, Copyright (c) Zend Technologies
with Zend OPcache v8.5.7, Copyright (c), by Zend Technologies
Operating System
macOS latest
Description
Hey there!
I came across the following...
which works. PHPStorm offers a refactor to:
Which results in:
The RFC explicitly shows such example, although without default value. There is, however, no word about that using pipes in hooks would turn a backed hooked property into a virtual property. Hence, I would have expected it to work. Then I tried:
Which works, with and without passing
$pathto the constructor. Then I again apply the proposed refactor...which with and without passing
$pathto the constructor results in:even though there is no
readonlyinvolved at all.Nothing of this seems expected to me. Feels similar to what was added as errata regarding arrow functions, but wrapping the whole thing into parentheses does not help (and is not mentioned in the RFC), and
get {}has the same issues.PHP Version
Operating System
macOS latest