Skip to content

Fatal errors for property hooks in combination with pipes #22587

Description

@NickSdot

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

Metadata

Metadata

Assignees

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions