Skip to content

Nested lazy ghost fails with clone #18766

Closed as not planned
Closed as not planned
@mkroeders

Description

@mkroeders

Description

In a library I do reflection of objects and want to support nested references. So use lazy ghost/proxies for creating nested objects to prevent endless loop and with a combination of caching to prevent redoing the same objects multiple times. However it breaks when using clone inside the factory method. Tested it with the newLazyGhost and newLazyProxy.

Not sure if it is supported behavior, but looking at the rfc it only mentions nesting in combination with throwing exceptions.

The following code:

<?php
class Bar {
    public function __construct(
        public Bar $bar,
        public int $x,
    ) {}

    public function with(): self
    {
        return clone $this;
    }
}

class Fiz {
    public mixed $cache = null;

    public function foo(int $i)
    {
        if (!$this->cache) {
            $this->cache = $this->factor($i);
        }

        if ($i <= 1) {
            return $this->cache->with();
        }

        return $this->cache;
    }

    public function factor(int $i): object
    {
        $reflector = new ReflectionClass(Bar::class);

        return $reflector->newLazyGhost(
            function (Bar $bar) use ($i) {
                $bar->__construct($this->foo($i + 1), 2);
            },
        );
    }
}

$fiz = new Fiz();

$f = $fiz->foo(0);
var_dump($f->bar->bar->x);

https://3v4l.org/lYpu1

Resulted in this output:

PHP Fatal error:  Uncaught Error: Typed property Bar::$bar must not be accessed before initialization

But I expected this output instead:

int(2)

PHP Version

PHP 8.4.3 (cli) (built: Jan 15 2025 01:03:17) (NTS)
Copyright (c) The PHP Group
Built by Homebrew
Zend Engine v4.4.3, Copyright (c) Zend Technologies
    with Xdebug v3.4.0, Copyright (c) 2002-2024, by Derick Rethans
    with Zend OPcache v8.4.3, Copyright (c), by Zend Technologies

Operating System

Mac OS

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions