服务容器Ioc的示例分析
发表于:2025-01-26 作者:千家信息网编辑
千家信息网最后更新 2025年01月26日,小编给大家分享一下服务容器Ioc的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!服务容器是一个用于管理类依赖和执行
千家信息网最后更新 2025年01月26日服务容器Ioc的示例分析
小编给大家分享一下服务容器Ioc的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!
服务容器是一个用于管理类依赖和执行依赖注入的强大工具。
一个类要被容器所能够提取,必须要先注册至这个容器。既然称这个容器叫做服务容器,那么我们需要某个服务,就得先注册、绑定这个服务到容器,那么提供服务并绑定服务至容器的东西就是服务提供器(ServiceProvider)。
依赖注入和控制反转是对同一件事情的不同描述,它们描述的角度不同。依赖注入是从应用程序的角度在描述,应用程序依赖容器创建并注入它所需要的外部资源。而控制反转是从容器的角度在描述,容器控制应用程序,由容器反向的向应用程序注入应用程序所需要的外部资源。
'value']; }}/** * User类依赖Log接口的实现 */class User{ private $log; private $extra; public function __construct(Log $log, $a, $b, $c = '默认参数') { $this->log = $log; $this->extra = compact('a', 'b', 'c'); } /** * 模拟用户登录写入登录日志 */ public function login(Request $request) { echo '接收登录请求的参数json:' . json_encode($request->toArray()) . PHP_EOL; echo 'user log success...' . PHP_EOL; $this->log->write(); } public function getExtra() { var_dump($this->extra); }}/** * Class Ioc * 模拟IoC容器 * 类从注册到实例化,最终被我们所使用,都是服务容器负责 */class Ioc{ protected $bindings = []; protected $instances = []; protected static $ioc; protected function __construct() { } public static function getInstance() { if (is_null(self::$ioc)) { self::$ioc = new self(); } return self::$ioc; } /** * 注册绑定 (绑定自身、闭包、接口) * 也就是服务 * @param $abstract * @param null $concrete * @param bool $share */ public function bind($abstract, $concrete = null, $share = true) { if (is_null($concrete)) { $concrete = $abstract; } $this->bindings[$abstract]['share'] = $share; if ($concrete instanceof Closure) { $this->bindings[$abstract]['concrete'] = $concrete; } else { $this->bindings[$abstract]['concrete'] = function (Ioc $ioc, $vars = []) use ($concrete) { return $ioc->build($concrete, $vars); }; } } /** * 返回对象 * @param $abstract * @param array $vars * @return mixed * @throws ReflectionException */ public function make($abstract, $vars = []) { if (isset($this->instances[$abstract])) { return $this->instances[$abstract]; } if (isset($this->bindings[$abstract]['concrete'])) { $concrete = $this->bindings[$abstract]['concrete']; $instance = $concrete($this, $vars); if ($this->bindings[$abstract]['share']) { $this->instances[$abstract] = $instance; } return $instance; } throw new RuntimeException($abstract . ' is not bound yet'); } /** * 创建对象 * @param $concrete * @return object * @throws ReflectionException */ public function build($concrete, $vars = []) { $reflectionClass = new ReflectionClass($concrete); $constructor = $reflectionClass->getConstructor(); if (is_null($constructor)) { return $reflectionClass->newInstance(); } $isInstantiable = $reflectionClass->isInstantiable(); if (!$isInstantiable) { throw new ReflectionException("{$concrete} cant construct"); } $parameters = $constructor->getParameters(); $dependencies = $this->getDependencies($parameters, $vars); return $reflectionClass->newInstanceArgs($dependencies); } /** * 获取参数的依赖 * @param array $parameters * @return array * @throws ReflectionException */ public function getDependencies(array $parameters, $vars = []) { $dependencies = []; reset($vars); $type = key($vars) === 0 ? 'figure' : 'letter'; /** * @var ReflectionParameter $parameter */ foreach ($parameters as $parameter) { $dependency = $parameter->getClass(); $name = $parameter->getName(); if ($dependency) { $dependencies[] = $this->getObjectParam($dependency->getName(), $vars); } elseif ('figure' == $type && !empty($vars)) { $dependencies[] = array_shift($vars); } elseif ('letter' == $type && isset($vars[$name])) { $dependencies[] = $vars[$name]; } elseif ($parameter->isDefaultValueAvailable()) { $dependencies[] = $parameter->getDefaultValue(); } else { throw new ReflectionException('The constructor of the ' . $parameter->getDeclaringClass()->getName() . ' class has no default value of $' . $name); } } return $dependencies; } /** * 获取对象类型的参数值 * @access protected * @param string $className 类名 * @param array $vars 参数 * @return mixed */ protected function getObjectParam($className, &$vars) { $array = $vars; $value = array_shift($array); if ($value instanceof $className) { $result = $value; array_shift($vars); } else { $result = $this->make($className); } return $result; } /** * @param null $key * @return array|mixed|null */ public function getInstances($key = null) { if (is_null($key)) { return $this->instances; } elseif (isset($this->instances[$key])) { return $this->instances[$key]; } else { return null; } }}// run/* | 模拟容器绑定 */$ioc = Ioc::getInstance();$ioc->bind(Request::class);//绑定类$ioc->bind(Log::class, FileLog::class);//绑定接口//$ioc->bind(Log::class, DataBaseLog::class);$ioc->bind('test', function () {//绑定闭包 return 'test' . PHP_EOL;});/* | 模拟路由访问 User 控制器下的 login 方法 */$ioc->bind(User::class, null, true);$method = 'login';$reflectionMethod = new ReflectionMethod(User::class, $method);$parameters = $reflectionMethod->getParameters();$dependencies = $ioc->getDependencies($parameters);$user = $ioc->make(User::class, ['参数1', '参数2']);call_user_func_array([$user, $method], $dependencies);// 查看参数$user->getExtra();var_dump($ioc->getInstances());
以上是"服务容器Ioc的示例分析"这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!
容器
服务
参数
应用程序
程序
应用
控制
对象
接口
篇文章
角度
登录
示例
分析
不同
内容
资源
闭包
强大
不怎么
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
网络安全三证合一
虚无世界服务器枪械怎么获得
用excel实现数据库的管理
网页登录数据库验证不通过
利用信息和网络技术的新环境
保险监管软件开发定制推荐
软件开发竞聘报告
怎样制作dns服务器
数据库日期默认今天
北京戴尔服务器回收电话
技术软件开发公司前台的工作
三维图形软件开发
vpn美国服务器地址
opc与数据库
网络安全知多少竞赛
.net软件开发思想
网络安全论文答辩怎么问
2016年网络技术模拟试卷
王瑛玮公安部网络安全保卫局
嘉兴app软件开发要求
一站式网络技术优点
国家电网内网网络安全保密
迪斯杰dsg在数据库中排名多少
自制服务器机柜
法院网络安全培训简报
冬季运动项目数据库
sql数据库执行
樟树市政协关注网络安全治理
集成服务器虚拟机
每天自动更新数据库某一值