依赖注入是通过 php 的映射函数,解析到类在实例化的时候所依赖的类,直接将类实例化
<?php
namespace Core;
/**
* 容器文件
* Class Container
* @package Core
*/
class Container
{
/**
* @var array 实例化的类
*/
protected $binds = [];
/**
* 获取一个类的实例化 因为实例化的时候参数都是固定的,所以可以使用此数组方法
* @param $class
* @param array $params
* @return mixed
* @throws \ReflectionException
*/
public function make($class, array $params = [])
{
if (isset($this->binds[$class])) {
return $this->binds[$class];
}
return $this->binds[$class] = $this->resolve($class, $params);
}
/**
* 移除某个类的实例
* @param $class
* @return $this
*/
public function removeClass($class)
{
unset($this->binds[$class]);
return $this;
}
/**
* 解析一个类的构造函数,并且实例化
* @param $abstract
* @param $request_params
* @return mixed
* @throws \ReflectionException
*/
protected function resolve($abstract, $request_params)
{
// 1. 获取构造函数
$constructor = (new \ReflectionClass($abstract))->getConstructor();
// 2.没有构造函数,则直接返回类的实例化
if (is_null($constructor)) {
return new $abstract;
}
// // 3. 如果是配置中的类,则直接获取配置参数实例化
// $isProviderClass = $this->getProviderClass($abstract);
// if ($isProviderClass) {
// return $isProviderClass;
// }
// 获取构造函数中的参数
$params = $constructor->getParameters();
$arguments = [];
foreach ($params as $param) {
if (is_null($param->getClass())) {
if (is_null($request_params[$param->getPosition()])) {
// 如果实参没又传递,则终止循环
break;
}
$arguments[] = $request_params[$param->getPosition()]; // 对应的位置赋值对应的参数
// 参数不是类
} else {
$arguments[] = $this->make($param->getClass()->getName());
}
}
return new $abstract(...$arguments);
}
// /**
// * 如果是 config/app.php 的 privider 数组中的函数,则直接获取配置中的参数进行实例化
// * @param $class
// * @return bool
// * @throws \ReflectionException
// */
// protected function getProviderClass($class)
// {
// // 如果是 config/app.php 里面绑定的,则获取相应的实例化即可
// if (array_key_exists($class, config('app', 'providers'))) {
// return new $class(...config('app', 'providers.' . $class));
// }
// return false;
// }
}
封装一个全局函数
if (!function_exists('app')) {
/**
* 获取一个类的实例化
* @param $class
* @param array $params
* @return mixed
* @throws ReflectionException
*/
function app($class, $params = [])
{
static $container;
if (!$container) {
$container = new \Core\Container();
}
return $container->make($class, $params);
}
}
使用
比如有一个 test 类
app(Test::class); 即可得到 new Test();
网友评论