前段时间一直在看tp5 发现他内部实现了控制器的依赖注入。。下面 我通过代码来说明一下是怎么实现的。
首先我们准备好几个类文件 我们先看目录安排
其中 start.php是启动文件
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/4/17
* Time: 21:04
*/
header("Content-type: text/html; charset=utf-8");
require 'auto1.php';
require 'auto2.php';
require 'auto3.php';
require 'auto4.php';
class App{
public static function run()
{
$class = 'auto1';
$sh1 = 'sh1';
$sh3 = 'sh3';
self::exec($class,$sh1);
}
//执行反射类方法。
public static function exec($class,$methodname)
{
//注入的实质是通过php的反射类 来执行被注入类的行为
//通过反射 可以得到类的一些信息 主要包括方法 属性
//通过注入 我们可以实现类对方法和构造方法的依赖。下面我举例说明
//1.先肯定是从一个类的构造函数开始。
//2.利用反射得到这个类的构造函数 在执行
$reflect = new \ReflectionClass($class);
$constructor = $reflect->getConstructor();
$p1 = self::getParamValue($constructor);
//执行被反射类的构造函数 实现构造函数的依赖注入
$instance = $reflect->newInstanceArgs($p1);
//执行注入类的方法。
$reflect = new \ReflectionMethod($class, $methodname);
$p2 = self::getParamValue($reflect);
//执行方法注入。
$reflect->invokeArgs($instance, $p2);
}
//这个类用来 反射出当前注入类所在的参数。
private static function getParamValue($reflect,$avgs=[])
{
if ($reflect->getNumberOfParameters() > 0)
{
foreach ($reflect->getParameters() as $param) {
$param_type = $param->getClass();//获取当前注入对象的类型提示
$param_value = $param->getName();//获取参数名称
if($param_type)
{
//表示是对象类型的参数
$avgs[] = new $param_value;
}
else
{
$avgs[] = $param_value;
}
}
}
return $avgs;
}
}
//执行应用程序
App::run();
auto1.php
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/4/17
* Time: 21:30
*/
class auto1{
public function __construct(auto4 $auto4)
{
$auto4->sh();
}
public function sh1(){
echo '我是没有参数的方法sh1,我被执行了<br>';
}
public function sh3(auto2 $auto2,auto3 $auto3)
{
$auto2->sh();
$auto3->sh();
}
}
auto2.php
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/4/17
* Time: 21:31
*/
class auto2{
public function sh(){
echo '我是auto2,我被执行到了,说明依赖注入成功了<br>';
}
}
auto3.php
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/4/17
* Time: 23:18
*/
class auto3{
public function sh(){
echo '我是auto3,我被执行到了,说明依赖注入成功了<br>';
}
}
auto4.php
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/4/18
* Time: 21:03
*/
class auto4{
public function sh(){
echo '我是auto4,我被执行到了,说明依赖注入成功了<br>';
}
}
调用方式
执行效果
执行效果
这样就实现了。你可以想象一下 tp5的控制器是不是就是我们这里的auto1这个类啊。我剥离了它的依赖代码,核心就是我那个App类的2个方法了。