Array von Instanzen oder Klassennamen */ public function locate(string $directory, string $interfaceName, bool $instantiate = true): array { $implementations = []; $rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory)); foreach ($rii as $file) { if (! $file->isFile() || $file->getExtension() !== 'php') { continue; } try { $className = $this->getClassNameFromFile($file->getPathname()); if (! $className || ! ClassName::create($className)->exists()) { continue; } $refClass = new ReflectionClass($className); // Überprüfen, ob die Klasse das gewünschte Interface implementiert if ($refClass->implementsInterface($interfaceName) && ! $refClass->isAbstract() && ! $refClass->isInterface()) { if ($instantiate) { // Prüfen, ob der Konstruktor Parameter hat $constructor = $refClass->getConstructor(); if ($constructor === null || $constructor->getNumberOfRequiredParameters() === 0) { $implementations[] = $refClass->newInstance(); } else { // Bei Konstruktoren mit Pflichtparametern nur den Klassennamen zurückgeben $implementations[] = $className; } } else { $implementations[] = $className; } } } catch (Throwable $e) { #error_log("InterfaceImplementationLocator Warnung: Fehler in Datei {$file->getPathname()}: " . $e->getMessage()); } } return $implementations; } private function getClassNameFromFile(string $file): ?string { $contents = file_get_contents($file); if ( preg_match('#namespace\s+([^;]+);#', $contents, $nsMatch) && preg_match('/class\s+(\w+)/', $contents, $classMatch) ) { return trim($nsMatch[1]) . '\\' . trim($classMatch[1]); } return null; } }