<?php
class Placeholders {
    /**
     * @var \Closure(): (self)|null
     */
    private ?\Closure $value = null;

    public function __construct(private array $collection = [], private array $scopedCollection = [])
    {
    }
    public function withCallbackScope(string $scope, \Closure $callback): Placeholders
    {
        $clone = clone $this;
        $clone->scopedCollection[$scope] = new self();
        $clone->scopedCollection[$scope]->value = $callback;
        return $clone;
    }

    public function getScope(string $scope): Placeholders
    {
        if (!isset($this->scopedCollection[$scope])) {
            throw new \InvalidArgumentException('Cannot find key ' . $scope);
        }

        return $this->scopedCollection[$scope];
    }

    public function get(string $key): string
    {
        if ($this->value !== null) {
            $value = \call_user_func($this->value);
            $this->collection = $value->collection;
            $this->value = null;
        }

        if (!isset($this->collection[$key])) {
//            return '';  // <- solves the crash
            throw new \InvalidArgumentException('Cannot find key ' . $key); // <- here is the crash
        }

        return $this->collection[$key];
    }
}

$placeholders = (new Placeholders())
    ->withCallbackScope('x', fn () => new Placeholders([
        'letterhead' => 'letterhead',
        'street' => 'street',
        'postalcode' => 'postalcode',
        'city' => 'city',
    ]));

class Resolver {
    public function resolve(Placeholders $placeholders)
    {
        $result = '';
        try {
            $result .= $placeholders->getScope('x')->get('letterhead');
            $result .= $placeholders->getScope('x')->get('street');
            $result .= $placeholders->getScope('x')->get('postalcode');
            $result .= $placeholders->getScope('x')->get('city');
            $result .= $placeholders->getScope('x')->get('country');
        } catch (\InvalidArgumentException) {
        }

        return $result;
    }
}

$resolver = new Resolver();
echo $resolver->resolve($placeholders);

echo "end";
