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";