了解PHP容器(Container)的实现
Dependency Injection Containers 的基本功能:
- Container 管理对象实例化到配置的过程
- 对象本身不知道自己是由 Container 管理的,对 Container 一无所知。
这就是为什么 Container 能够管理任何 PHP 对象。 对象使用 DI 来管理依赖关系非常好,但不是必须的。
i
<?php function info($msg){ echo $msg; } class LogToFile { public function execute($message) { info('log the message to a 美羊羊 :'.$message); } } class UseLogger { protected $logger; public function __construct(LogToFile $logger) { $this->logger = $logger; } public function show() { $user = '小灰灰'; $this->logger->execute($user); } } $useLogger = new UseLogger(new LogToFile()); $useLogger->show();
ii
A
<?php function info($msg){ echo $msg; } class LogToFile { public function execute($message) { info('log the message to a 美羊羊 :'.$message); } } class LogToDD { public function execute($message) { info('log the message to 喜羊羊 :'.$message); } } class UseLogger { protected $logger; public function __construct(LogToFile $logger) { $this->logger = $logger; } public function show() { $user = '小灰灰'; $this->logger->execute($user); } } $useLogger = new UseLogger(new LogToFile()); $useLogger->show();
B
<?php function info($msg){ echo $msg; } class LogToFile { public function execute($message) { info('log the message to a 美羊羊 :'.$message); } } class LogToDD { public function execute($message) { info('log the message to 喜羊羊 :'.$message); } } class UseLogger { protected $logger; public function __construct(LogToDD $logger) { $this->logger = $logger; } public function show() { $user = '小灰灰'; $this->logger->execute($user); } } $useLogger = new UseLogger(new LogToDD()); $useLogger->show();
iii
<?php function info($msg){ echo $msg; } interface Logger { public function execute($message); } class LogToFile implements Logger { public function execute($message) { info('log the message to a 美羊羊 :'.$message); } } class LogToDD implements Logger { public function execute($message) { info('log the message to 喜羊羊 :'.$message); } } class UseLogger { protected $logger; public function __construct(Logger $logger) { $this->logger = $logger; } public function show() { $user = '小灰灰'; $this->logger->execute($user); } } $useLogger = new UseLogger(new LogToFile()); $useLogger->show(); echo '<br>'; $useLogger = new UseLogger(new LogToDD()); $useLogger->show();
终极版
<?php function info($msg){ echo $msg; } interface Logger { public function execute($message); } class LogToFile implements Logger { public function execute($message) { info('log the message to a 美羊羊 :'.$message); } } class LogToDD implements Logger { public function execute($message) { info('log the message to 喜羊羊 :'.$message); } } class UseLogger { protected $logger; public function __construct(Logger $logger) { $this->logger = $logger; } public function show() { $user = '小灰灰'; $this->logger->execute($user); } } class SimpleContainer { // 用于存储所有绑定 key-value protected static $container = []; public static function bind($name, Callable $resolver) { static::$container[$name] = $resolver; } public static function make($name) { if(isset(static::$container[$name])){ $resolver = static::$container[$name] ; return $resolver(); } throw new Exception("Binding does not exist in container"); } } SimpleContainer::bind(Logger::class, function () { return new LogToDD(); }); $useLogger3 = new UseLogger(SimpleContainer::make(Logger::class)); $useLogger3->show();
示例
<?php interface SuperModuleInterface{ public function activate(array $target); } class Superman { protected $module; /** * Superman constructor. * @param SuperModuleInterface $module * 通过构造器 注入依赖 */ public function __construct(SuperModuleInterface $module) { $this->module = $module; } public function show(array $target){ $this->module->activate($target); } } class PowerA implements SuperModuleInterface { public function activate(array $target) { echo '<pre>'. __METHOD__; print_r(func_get_args()); } } class PowerB implements SuperModuleInterface { public function activate(array $target) { echo '<pre>'. __METHOD__; print_r(func_get_args()); } } class Container { protected $binds; protected $instances; /** * @param $abstract * @param $concrete * 把代词 绑定到容器里,为后续make */ public function bind($abstract, $concrete) { if ($concrete instanceof Closure) { $this->binds[$abstract] = $concrete; } else { $this->instances[$abstract] = $concrete; } } /** * @param $abstract * @param array $parameters * @return mixed * 创建对象 */ public function make($abstract, $parameters = []) { if (isset($this->instances[$abstract])) { return $this->instances[$abstract]; } // 把容器对象$this,放到参数数组第一个元素。为call_user_func_array使用 array_unshift($parameters, $this); // 这里$this->binds[$abstract] 绑定的闭包函数, 执行函数参数是$parameters return call_user_func_array($this->binds[$abstract], $parameters); } } // 创建一个容器(后面称作超级工厂) $container = new Container; // 向该 超级工厂添加超能力模组的生产脚本 $container->bind('powerA', function($container) { return new PowerA; }); // 同上 $container->bind('powerB', function($container) { return new PowerB; }); // 向该 超级工厂添加超人的生产脚本 $container->bind('superman', function($container, $moduleName) { return new Superman($container->make($moduleName)); }); echo "<pre>"; // 开始启动生产 $superman_1 = $container->make('superman', ['powerA']); $superman_1->show(['a' => 1]); $superman_2 = $container->make('superman', ['powerB']); $superman_2->show(['b' => 1]);
原文地址:https://segmentfault.com/a/1190000019472257
相关推荐
-
windows下 用nginx部署php项目 php基础
2019-9-9
-
Windows下用xmapp配置PHP开发环境 php基础
2019-9-9
-
小时到分钟 – 一步步优化巨量关键词的匹配 php基础
2019-5-13
-
一份腾讯 PHP 程序员面试笔试题的解答(GitChat分享) php基础
2020-6-26
-
PHP算法基础-算法复杂度 php基础
2019-8-26
-
swoole_process实现多进程 php基础
2019-9-15
-
PHP实现支付宝小程序用户授权的工具类 php基础
2018-12-25
-
OAuth2.0 知多少 php基础
2019-1-30
-
图解Go的channel底层原理 php基础
2019-9-9
-
RabbitMQ二三事 php基础
2019-3-31