getConstructor(); if (!$constructor) { throw new \RuntimeException('DTO must have a constructor'); } $properties = []; foreach ($constructor->getParameters() as $parameter) { $properties[$parameter->getName()] = $data[$parameter->getName()] ?? ($parameter->isOptional() ? $parameter->getDefaultValue() : null); } return new static(...$properties); } /** * Convert the DTO to an array. */ public function toArray(): array { return get_object_vars($this); } /** * Convert the DTO to JSON. */ public function jsonSerialize(): array { return $this->toArray(); } }