Troubleshooting
Common issues when using wpzylos-container.
Resolution Issues
EntryNotFoundException
Problem: EntryNotFoundException: No entry found for "MyService"
Cause: Service not registered in container.
Fix: Bind the service before resolving:
// Register first
$container->bind(MyService::class);
// Then resolve
$service = $container->get(MyService::class);
BindingResolutionException
Problem: BindingResolutionException: Unable to resolve dependency
Cause: Auto-wiring failed due to unresolvable dependency.
Fix: Check constructor parameters:
class MyService
{
// Bad: Can't auto-wire primitive without binding
public function __construct(string $apiKey) {}
// Good: Can auto-wire class dependencies
public function __construct(Logger $logger) {}
}
// For primitives, bind explicitly:
$container->bind(MyService::class, fn() => new MyService('my-key'));
Circular Dependency
Problem: Container hangs or stack overflow.
Cause: Class A needs B, class B needs A.
Fix: Break cycle with setter injection:
// Bad: Circular
class A { public function __construct(B $b) {} }
class B { public function __construct(A $a) {} }
// Good: Break with setter
class B {
private ?A $a = null;
public function setA(A $a): void { $this->a = $a; }
}
$container->singleton(A::class);
$container->singleton(B::class, function ($c) {
$b = new B();
$b->setA($c->get(A::class));
return $b;
});
Binding Issues
Singleton returns different instances
Problem: singleton() binding returns new instance each call.
Cause: Binding overwritten or wrong method used.
Fix: Verify you're using singleton() not bind():
// Bad: Creates new instance each time
$container->bind(Database::class);
// Good: Same instance every time
$container->singleton(Database::class);
Interface binding not resolving
Problem: get(Interface::class) fails even after binding.
Cause: Binding uses wrong interface name or namespace.
Fix: Use fully qualified class names:
// Bad: Missing namespace
$container->bind('LoggerInterface', FileLogger::class);
// Good: Full namespace
$container->bind(
\Psr\Log\LoggerInterface::class,
\App\Logging\FileLogger::class
);
Auto-wiring Issues
Optional parameters not working
Problem: Optional constructor parameter causes resolution failure.
Cause: Parameter type can't be resolved and has no default.
Fix: Ensure optional parameters have defaults:
class Service
{
// Bad: No default, will fail if Cache not bound
public function __construct(?CacheInterface $cache) {}
// Good: Has default, will use null if not bound
public function __construct(?CacheInterface $cache = null) {}
}
Union types failing
Problem: A|B union type parameter fails to resolve.
Cause: Container doesn't know which type to use.
Fix: Bind explicitly or use first resolvable type:
// Bind the specific type you want
$container->bind(LoggerInterface::class, FileLogger::class);
PSR-11 Compatibility
Third-party library rejects container
Problem: Library throws Container must implement ContainerInterface.
Cause: Import mismatch or interface not implemented.
Fix: Verify container implements PSR-11:
use Psr\Container\ContainerInterface;
$container = new Container();
assert($container instanceof ContainerInterface); // Should pass