wrappedClassCache[$className] ??= new WrappedReflectionClass( $this->getClass($className) ); } public function getWrappedMethod(string $className, string $methodName): WrappedReflectionMethod { $key = "{$className}::{$methodName}"; return $this->wrappedMethodCache[$key] ??= new WrappedReflectionMethod( $this->getMethod($className, $methodName) ); } public function getClass(string $className): ReflectionClass { return $this->classCache[$className] ??= new ReflectionClass($className); } public function getMethod(string $className, string $methodName): ReflectionMethod { $key = "{$className}::{$methodName}"; return $this->methodCache[$key] ??= $this->getClass($className)->getMethod($methodName); } public function getMethodParameters(string $className, string $methodName): array { $key = "{$className}::{$methodName}::params"; return $this->parameterCache[$key] ??= $this->getMethod($className, $methodName)->getParameters(); } public function getProperties(string $className): array { $key = "{$className}::properties"; return $this->propertyCache[$key] ??= $this->getClass($className)->getProperties(); } public function getAttributes(string $className, ?string $attributeClass = null): array { $key = "{$className}::attributes::" . ($attributeClass ?? 'all'); return $this->attributeCache[$key] ??= $attributeClass ? $this->getClass($className)->getAttributes($attributeClass) : $this->getClass($className)->getAttributes(); } public function getMethodAttributes(string $className, string $methodName, ?string $attributeClass = null): array { $key = "{$className}::{$methodName}::attributes::" . ($attributeClass ?? 'all'); return $this->attributeCache[$key] ??= $attributeClass ? $this->getMethod($className, $methodName)->getAttributes($attributeClass) : $this->getMethod($className, $methodName)->getAttributes(); } public function hasAttribute(string $className, string $attributeClass): bool { return !empty($this->getAttributes($className, $attributeClass)); } public function getParameterInfo(string $className, string $methodName): array { $key = "{$className}::{$methodName}::paramInfo"; return $this->parameterInfoCache[$key] ??= $this->buildParameterInfo($className, $methodName); } public function isInstantiable(string $className): bool { return $this->instantiableCache[$className] ??= $this->getClass($className)->isInstantiable(); } public function implementsInterface(string $className, string $interfaceName): bool { $key = "{$className}::implements::{$interfaceName}"; return $this->interfaceCache[$key] ??= $this->getClass($className)->implementsInterface($interfaceName); } private function buildParameterInfo(string $className, string $methodName): array { $parameters = $this->getMethodParameters($className, $methodName); $paramInfo = []; foreach ($parameters as $param) { $type = $param->getType(); $paramInfo[] = [ 'name' => $param->getName(), 'type' => $type ? $type->getName() : null, 'isBuiltin' => $type ? $type->isBuiltin() : true, 'allowsNull' => $param->allowsNull(), 'isOptional' => $param->isOptional(), 'hasDefaultValue' => $param->isDefaultValueAvailable(), 'default' => $param->isDefaultValueAvailable() ? $param->getDefaultValue() : null, 'position' => $param->getPosition(), ]; } return $paramInfo; } public function forget(string $className): void { unset($this->classCache[$className]); unset($this->instantiableCache[$className]); unset($this->wrappedClassCache[$className]); // Alle zugehörigen Caches leeren $this->clearRelatedCaches($className); } public function flush(): void { $this->classCache = []; $this->methodCache = []; $this->parameterCache = []; $this->propertyCache = []; $this->attributeCache = []; $this->parameterInfoCache = []; $this->instantiableCache = []; $this->interfaceCache = []; $this->wrappedClassCache = []; $this->wrappedMethodCache = []; } private function clearRelatedCaches(string $className): void { $prefix = $className . '::'; $caches = [ &$this->methodCache, &$this->parameterCache, &$this->propertyCache, &$this->attributeCache, &$this->parameterInfoCache, &$this->interfaceCache, &$this->wrappedMethodCache ]; foreach ($caches as &$cache) { $cache = array_filter( $cache, fn($key) => !str_starts_with($key, $prefix), ARRAY_FILTER_USE_KEY ); } } }