refactor(di): remove debug logging from dependency analyzers
- Eliminate debug logging clutter in `CyclicDependencyException` and `InitializerDependencyAnalyzer` for cleaner production code. - Simplify and streamline logic by removing unnecessary logs and redundant error tracing.
This commit is contained in:
@@ -262,40 +262,22 @@ final class CyclicDependencyException extends ContainerException
|
|||||||
// Verwende Analyzer aus Exception (wenn verfügbar)
|
// Verwende Analyzer aus Exception (wenn verfügbar)
|
||||||
$analyzer = $this->dependencyAnalyzer ?? new InitializerDependencyAnalyzer();
|
$analyzer = $this->dependencyAnalyzer ?? new InitializerDependencyAnalyzer();
|
||||||
|
|
||||||
// DEBUG: Logge welche Dependencies geprüft werden
|
|
||||||
error_log(sprintf(
|
|
||||||
"[CYCLIC_DEBUG] Suche problematische Dependency für Interface '%s' in %d Dependencies: [%s]",
|
|
||||||
$interface,
|
|
||||||
count($initializerDependencies),
|
|
||||||
implode(', ', $initializerDependencies)
|
|
||||||
));
|
|
||||||
|
|
||||||
// Methode 1: Rekursive Suche - Finde vollständigen Pfad für jede Dependency
|
// Methode 1: Rekursive Suche - Finde vollständigen Pfad für jede Dependency
|
||||||
foreach ($initializerDependencies as $dependency) {
|
foreach ($initializerDependencies as $dependency) {
|
||||||
// Überspringe Container selbst
|
// Überspringe Container selbst
|
||||||
if ($dependency === Container::class || $dependency === 'App\Framework\DI\Container') {
|
if ($dependency === Container::class || $dependency === 'App\Framework\DI\Container') {
|
||||||
error_log(sprintf("[CYCLIC_DEBUG] Überspringe Container '%s'", $dependency));
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_log(sprintf("[CYCLIC_DEBUG] Prüfe Dependency '%s' auf Pfad zu '%s'", $dependency, $interface));
|
|
||||||
|
|
||||||
$path = $analyzer->findDependencyPathToInterface($dependency, $interface);
|
$path = $analyzer->findDependencyPathToInterface($dependency, $interface);
|
||||||
|
|
||||||
if ($path !== null && !empty($path)) {
|
if ($path !== null && !empty($path)) {
|
||||||
error_log(sprintf(
|
|
||||||
"[CYCLIC_DEBUG] ✅ Pfad gefunden für '%s': [%s]",
|
|
||||||
$dependency,
|
|
||||||
implode(' → ', $path)
|
|
||||||
));
|
|
||||||
// Der erste Eintrag im Pfad ist die Dependency, die das Interface benötigt
|
// Der erste Eintrag im Pfad ist die Dependency, die das Interface benötigt
|
||||||
return [
|
return [
|
||||||
'problematicDependency' => $dependency,
|
'problematicDependency' => $dependency,
|
||||||
'confirmationMethod' => 'recursive_analysis',
|
'confirmationMethod' => 'recursive_analysis',
|
||||||
'fullPath' => $path,
|
'fullPath' => $path,
|
||||||
];
|
];
|
||||||
} else {
|
|
||||||
error_log(sprintf("[CYCLIC_DEBUG] ❌ Kein Pfad gefunden für '%s'", $dependency));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -247,46 +247,25 @@ final readonly class InitializerDependencyAnalyzer
|
|||||||
array $currentPath = [],
|
array $currentPath = [],
|
||||||
int $depth = 0
|
int $depth = 0
|
||||||
): ?array {
|
): ?array {
|
||||||
// DEBUG: Temporäres Logging
|
|
||||||
error_log(sprintf(
|
|
||||||
"[DEPENDENCY_DEBUG] Tiefe %d: Suche Pfad von '%s' zu '%s' (aktueller Pfad: [%s])",
|
|
||||||
$depth,
|
|
||||||
$dependencyClass,
|
|
||||||
$targetInterface,
|
|
||||||
implode(' → ', $currentPath)
|
|
||||||
));
|
|
||||||
|
|
||||||
// Max. Rekursionstiefe erreicht
|
// Max. Rekursionstiefe erreicht
|
||||||
if ($depth >= self::MAX_RECURSION_DEPTH) {
|
if ($depth >= self::MAX_RECURSION_DEPTH) {
|
||||||
error_log(sprintf("[DEPENDENCY_DEBUG] Max. Tiefe erreicht für '%s'", $dependencyClass));
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cycle-Detection: Vermeide Endlosschleifen
|
// Cycle-Detection: Vermeide Endlosschleifen
|
||||||
if (in_array($dependencyClass, $visited, true)) {
|
if (in_array($dependencyClass, $visited, true)) {
|
||||||
error_log(sprintf("[DEPENDENCY_DEBUG] Cycle erkannt für '%s' (bereits besucht)", $dependencyClass));
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prüfe ob diese Klasse direkt das Interface benötigt
|
// Prüfe ob diese Klasse direkt das Interface benötigt
|
||||||
if ($this->dependencyNeedsInterface($dependencyClass, $targetInterface)) {
|
if ($this->dependencyNeedsInterface($dependencyClass, $targetInterface)) {
|
||||||
$path = array_merge($currentPath, [$dependencyClass, $targetInterface]);
|
return array_merge($currentPath, [$dependencyClass, $targetInterface]);
|
||||||
error_log(sprintf("[DEPENDENCY_DEBUG] ✅ Pfad gefunden: [%s]", implode(' → ', $path)));
|
|
||||||
return $path;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rekursiv: Analysiere Dependencies dieser Klasse
|
// Rekursiv: Analysiere Dependencies dieser Klasse
|
||||||
$dependencies = $this->getClassDependencies($dependencyClass);
|
$dependencies = $this->getClassDependencies($dependencyClass);
|
||||||
|
|
||||||
error_log(sprintf(
|
|
||||||
"[DEPENDENCY_DEBUG] '%s' hat %d Dependencies: [%s]",
|
|
||||||
$dependencyClass,
|
|
||||||
count($dependencies),
|
|
||||||
implode(', ', $dependencies)
|
|
||||||
));
|
|
||||||
|
|
||||||
if (empty($dependencies)) {
|
if (empty($dependencies)) {
|
||||||
error_log(sprintf("[DEPENDENCY_DEBUG] Keine Dependencies für '%s'", $dependencyClass));
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,16 +275,9 @@ final readonly class InitializerDependencyAnalyzer
|
|||||||
foreach ($dependencies as $subDependency) {
|
foreach ($dependencies as $subDependency) {
|
||||||
// Überspringe Container selbst (würde alle Dependencies auflisten)
|
// Überspringe Container selbst (würde alle Dependencies auflisten)
|
||||||
if ($subDependency === Container::class || $subDependency === 'App\Framework\DI\Container') {
|
if ($subDependency === Container::class || $subDependency === 'App\Framework\DI\Container') {
|
||||||
error_log(sprintf("[DEPENDENCY_DEBUG] Überspringe Container '%s'", $subDependency));
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_log(sprintf(
|
|
||||||
"[DEPENDENCY_DEBUG] Prüfe Sub-Dependency '%s' (Tiefe %d)",
|
|
||||||
$subDependency,
|
|
||||||
$depth + 1
|
|
||||||
));
|
|
||||||
|
|
||||||
$path = $this->findDependencyPathToInterface(
|
$path = $this->findDependencyPathToInterface(
|
||||||
$subDependency,
|
$subDependency,
|
||||||
$targetInterface,
|
$targetInterface,
|
||||||
@@ -315,12 +287,10 @@ final readonly class InitializerDependencyAnalyzer
|
|||||||
);
|
);
|
||||||
|
|
||||||
if ($path !== null) {
|
if ($path !== null) {
|
||||||
error_log(sprintf("[DEPENDENCY_DEBUG] ✅ Pfad über '%s' gefunden!", $subDependency));
|
|
||||||
return $path;
|
return $path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
error_log(sprintf("[DEPENDENCY_DEBUG] ❌ Kein Pfad gefunden für '%s'", $dependencyClass));
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -394,7 +364,6 @@ final readonly class InitializerDependencyAnalyzer
|
|||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
if (!class_exists($className) && !interface_exists($className)) {
|
if (!class_exists($className) && !interface_exists($className)) {
|
||||||
error_log(sprintf("[DEPENDENCY_DEBUG] Klasse/Interface existiert nicht: '%s'", $className));
|
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -402,14 +371,11 @@ final readonly class InitializerDependencyAnalyzer
|
|||||||
|
|
||||||
// Wenn es ein Interface ist, versuche die Implementierung zu finden
|
// Wenn es ein Interface ist, versuche die Implementierung zu finden
|
||||||
if ($reflection->isInterface()) {
|
if ($reflection->isInterface()) {
|
||||||
error_log(sprintf("[DEPENDENCY_DEBUG] '%s' ist Interface, suche Implementierung...", $className));
|
|
||||||
// Suche nach bekannten Implementierungen (basierend auf Namenskonvention)
|
// Suche nach bekannten Implementierungen (basierend auf Namenskonvention)
|
||||||
$implClass = $this->findInterfaceImplementation($className);
|
$implClass = $this->findInterfaceImplementation($className);
|
||||||
if ($implClass !== null && class_exists($implClass)) {
|
if ($implClass !== null && class_exists($implClass)) {
|
||||||
error_log(sprintf("[DEPENDENCY_DEBUG] ✅ Implementierung gefunden: '%s' → '%s'", $className, $implClass));
|
|
||||||
$reflection = new \ReflectionClass($implClass);
|
$reflection = new \ReflectionClass($implClass);
|
||||||
} else {
|
} else {
|
||||||
error_log(sprintf("[DEPENDENCY_DEBUG] ❌ Keine Implementierung für Interface '%s' gefunden", $className));
|
|
||||||
// Kann keine Dependencies für Interfaces ohne Implementierung finden
|
// Kann keine Dependencies für Interfaces ohne Implementierung finden
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
@@ -564,50 +530,36 @@ final readonly class InitializerDependencyAnalyzer
|
|||||||
*/
|
*/
|
||||||
private function findInterfaceImplementation(string $interface): ?string
|
private function findInterfaceImplementation(string $interface): ?string
|
||||||
{
|
{
|
||||||
error_log(sprintf("[DEPENDENCY_DEBUG] findInterfaceImplementation: Suche Implementierung für '%s'", $interface));
|
|
||||||
|
|
||||||
// 1. Versuche über Container-Bindings (falls Container verfügbar)
|
// 1. Versuche über Container-Bindings (falls Container verfügbar)
|
||||||
if ($this->container !== null) {
|
if ($this->container !== null) {
|
||||||
try {
|
try {
|
||||||
error_log(sprintf("[DEPENDENCY_DEBUG] Container verfügbar, prüfe has('%s')", $interface));
|
|
||||||
// Prüfe ob Interface gebunden ist
|
// Prüfe ob Interface gebunden ist
|
||||||
if ($this->container->has($interface)) {
|
if ($this->container->has($interface)) {
|
||||||
error_log(sprintf("[DEPENDENCY_DEBUG] Interface '%s' hat Binding, hole Binding...", $interface));
|
|
||||||
$binding = $this->getBindingForInterface($interface);
|
$binding = $this->getBindingForInterface($interface);
|
||||||
if ($binding !== null) {
|
if ($binding !== null) {
|
||||||
error_log(sprintf("[DEPENDENCY_DEBUG] Binding gefunden: %s (Typ: %s)",
|
|
||||||
is_string($binding) ? $binding : (is_object($binding) ? $binding::class : 'callable'),
|
|
||||||
gettype($binding)
|
|
||||||
));
|
|
||||||
|
|
||||||
// Wenn Binding ein String ist (Klassenname), verwende diesen
|
// Wenn Binding ein String ist (Klassenname), verwende diesen
|
||||||
if (is_string($binding) && class_exists($binding)) {
|
if (is_string($binding) && class_exists($binding)) {
|
||||||
error_log(sprintf("[DEPENDENCY_DEBUG] ✅ Verwende String-Binding: '%s'", $binding));
|
|
||||||
return $binding;
|
return $binding;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wenn Binding ein Objekt ist, verwende dessen Klasse
|
// Wenn Binding ein Objekt ist, verwende dessen Klasse
|
||||||
if (is_object($binding)) {
|
// ABER: Überspringe Closure, da wir den Return-Type analysieren müssen
|
||||||
error_log(sprintf("[DEPENDENCY_DEBUG] ✅ Verwende Objekt-Binding: '%s'", $binding::class));
|
if (is_object($binding) && !($binding instanceof \Closure)) {
|
||||||
return $binding::class;
|
return $binding::class;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wenn Binding ein Callable ist, können wir es nicht direkt auflösen
|
// Wenn Binding ein Closure ist, versuche Return-Type zu analysieren
|
||||||
// aber wir können versuchen, es zu instanziieren (wenn kein Zyklus)
|
if ($binding instanceof \Closure) {
|
||||||
// Das ist riskant, also überspringen wir es für jetzt
|
$returnType = $this->getClosureReturnType($binding);
|
||||||
error_log(sprintf("[DEPENDENCY_DEBUG] ⚠️ Binding ist Callable, kann nicht direkt verwendet werden"));
|
if ($returnType !== null && class_exists($returnType)) {
|
||||||
} else {
|
return $returnType;
|
||||||
error_log(sprintf("[DEPENDENCY_DEBUG] ❌ Kein Binding gefunden für '%s'", $interface));
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
error_log(sprintf("[DEPENDENCY_DEBUG] Container->has('%s') = false", $interface));
|
|
||||||
}
|
}
|
||||||
} catch (\Throwable $e) {
|
}
|
||||||
error_log(sprintf("[DEPENDENCY_DEBUG] ❌ Container-Zugriff fehlgeschlagen: %s", $e->getMessage()));
|
}
|
||||||
|
} catch (\Throwable) {
|
||||||
// Container-Zugriff fehlgeschlagen - ignoriere und versuche Fallback
|
// Container-Zugriff fehlgeschlagen - ignoriere und versuche Fallback
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
error_log(sprintf("[DEPENDENCY_DEBUG] ❌ Container nicht verfügbar"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Versuche Namenskonvention: Interface -> DefaultInterfaceName
|
// 2. Versuche Namenskonvention: Interface -> DefaultInterfaceName
|
||||||
@@ -654,5 +606,24 @@ final readonly class InitializerDependencyAnalyzer
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Versuche Return-Type eines Closures zu extrahieren
|
||||||
|
*/
|
||||||
|
private function getClosureReturnType(\Closure $closure): ?string
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$reflection = new \ReflectionFunction($closure);
|
||||||
|
$returnType = $reflection->getReturnType();
|
||||||
|
|
||||||
|
if ($returnType instanceof \ReflectionNamedType && !$returnType->isBuiltin()) {
|
||||||
|
return $returnType->getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
} catch (\Throwable) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user