IOC 即控制反转(Inversion of Control)关于其基础解释,网上大多都有(大多都是一些不明不白的例子)。本文不再赘述。这里我们从代码的角度来说一说 IOC 容器(以 PHP 为例)
IOC 的实质是一个超级工厂类,目的是为了解耦
先说一说最基本的 IOC 容器有什么
- bind
- make
bind
protected $binds;
protected $instances;
public function bind($abstract, $concrete): void
{
if ($concrete instanceof Closure) {
$this->binds[$abstract] = $concrete;
} else {
$this->instances[$abstract] = $concrete;
}
}
bind 的作用就是将物品放入箱子,本质是告诉工厂这个类要怎么做出来。
所以在实际的使用中,你能看见它能绑定很多东西,比如绑定至接口,绑定至匿名函数,绑定至别名等等
bind 比较简单,在此不再解释
make
public function make($abstract, array $parameters = []): mixed
{
try {
$reflector = new ReflectionClass($abstract);
} catch (ReflectionException $e) {
throw new ReflectionException($e);
}
$constructor = $reflector->getConstructor();
$args = [];
if ($constructor) {
foreach ($constructor->getParameters() as $param) {
$class = $param->getType();
assert($class instanceof ReflectionNamedType);
if ($class) {
$args[] = $this->make($class->getName());
}
}
}
$args = array_merge($args, $parameters);
return $reflector->newInstanceArgs($args);
}
make 的作用是实例化一个类
make 有些复杂,接下来详细说说
有的时候一个类依赖其他类,依赖的类又依赖别的类,这会导致实例化的时候异常麻烦,make 正是为了解决类的相互依赖而设计的
ReflectionClass
是一个 php 的反射类,此类报告了一个类的有关信息
解释
既然要实例化一个类,那必然就要获取类的构造函数即 getConstructor()
方法,如果这个类有构造函数那么便获取它的参数 getParameters()
,去迭代这个参数,获取参数类型 getType()
,从中获取要被实例化的这个类的依赖,如果还有依赖,那么便递归,最后合并这个参数和类,从给出的参数创建一个新的类实例 newInstanceArgs($args)
更多
自 PHP7.1.0 起,ReflectionType::__toString()
已弃用 ReflectionParameter::getType()
可能会返回 ReflectionNamedType
的实例。要获取参数类型的名称,在这种情况下可以使用 ReflectionNamedType()
例如:
function someFunction(int $param, $param2) {}
$reflectionFunc = new ReflectionFunction('someFunction');
$reflectionParams = $reflectionFunc->getParameters();
$reflectionType1 = $reflectionParams[0]->getType();
$reflectionType2 = $reflectionParams[1]->getType();
echo $reflectionType1, PHP_EOL;
var_dump($reflectionType2);
自 PHP8.0.0 起,此方法可能会返回一个 ReflectionNamedType
实例或一个 ReflectionUnionType
实例。后者是前者的集合。为了分析一个类型,将它规范化为一个 ReflectionNamedType
对象数组通常很方便。
例如:
function getAllTypes(ReflectionParameter $reflectionParameter): array
{
$reflectionType = $reflectionParameter->getType();
if (!$reflectionType) return [];
return $reflectionType instanceof ReflectionUnionType
? $reflectionType->getTypes()
: [$reflectionType];
}
Comments 2 条评论
博主 JIeJaitt
大佬这是 wordpress 的 sakurairo 主题吧,为啥会有这么优秀的加载速度呀,是做过相关优化嘛?
博主 不明
@JIeJaitt 其实也没做多少优化,只是开了 opcache 和使用最新的 php 而已