php 实现IOC
PHP 实现 IOC(控制反转)容器
控制反转(IoC)是一种设计模式,通过将对象的创建和管理交给外部容器来实现解耦。在 PHP 中,可以通过以下方式实现一个简单的 IoC 容器。
基本容器类实现
创建一个基础的 IoC 容器类,用于注册和解析依赖:
class Container
{
protected $bindings = [];
public function bind($abstract, $concrete = null, $shared = false)
{
if (is_null($concrete)) {
$concrete = $abstract;
}
$this->bindings[$abstract] = compact('concrete', 'shared');
}
public function singleton($abstract, $concrete = null)
{
$this->bind($abstract, $concrete, true);
}
public function make($abstract)
{
if (!isset($this->bindings[$abstract])) {
return $this->build($abstract);
}
$binding = $this->bindings[$abstract];
if ($binding['shared'] && isset($binding['instance'])) {
return $binding['instance'];
}
$instance = $this->build($binding['concrete']);
if ($binding['shared']) {
$this->bindings[$abstract]['instance'] = $instance;
}
return $instance;
}
protected function build($concrete)
{
if ($concrete instanceof Closure) {
return $concrete($this);
}
$reflector = new ReflectionClass($concrete);
if (!$reflector->isInstantiable()) {
throw new Exception("Target [$concrete] is not instantiable.");
}
$constructor = $reflector->getConstructor();
if (is_null($constructor)) {
return new $concrete;
}
$dependencies = $this->resolveDependencies($constructor->getParameters());
return $reflector->newInstanceArgs($dependencies);
}
protected function resolveDependencies($parameters)
{
$dependencies = [];
foreach ($parameters as $parameter) {
$dependency = $parameter->getClass();
if (is_null($dependency)) {
if ($parameter->isDefaultValueAvailable()) {
$dependencies[] = $parameter->getDefaultValue();
} else {
throw new Exception("Cannot resolve dependency [$parameter].");
}
} else {
$dependencies[] = $this->make($dependency->name);
}
}
return $dependencies;
}
}
使用示例
定义接口和实现类:
interface LoggerInterface
{
public function log($message);
}
class FileLogger implements LoggerInterface
{
public function log($message)
{
echo "Logging to file: $message\n";
}
}
class DatabaseLogger implements LoggerInterface
{
public function log($message)
{
echo "Logging to database: $message\n";
}
}
注册依赖并解析:
$container = new Container();
// 绑定接口到具体实现
$container->bind(LoggerInterface::class, FileLogger::class);
// 获取实例
$logger = $container->make(LoggerInterface::class);
$logger->log("Hello World"); // 输出: Logging to file: Hello World
// 单例绑定
$container->singleton(LoggerInterface::class, DatabaseLogger::class);
$logger1 = $container->make(LoggerInterface::class);
$logger2 = $container->make(LoggerInterface::class);
var_dump($logger1 === $logger2); // 输出: bool(true)
自动依赖注入
通过反射自动解析构造函数依赖:
class UserController
{
protected $logger;
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}
public function action()
{
$this->logger->log("User action performed");
}
}
$controller = $container->make(UserController::class);
$controller->action(); // 输出取决于绑定的 LoggerInterface 实现
闭包绑定
可以使用闭包来定义更复杂的实例化逻辑:
$container->bind('complex.service', function($container) {
$logger = $container->make(LoggerInterface::class);
return new ComplexService($logger, 'some_config');
});
实际应用建议
对于生产环境,建议使用成熟的 IoC 容器库如:
- Laravel 的服务容器
- PHP-DI
- Pimple
这些库提供了更完善的功能,包括:
- 自动装配
- 注解支持
- 配置管理
- 生命周期管理







