一 、 什么是中间件
中间件是一个轻量级、底层的插件系统,可以介入应用主题从请求到响应的处理过程。
说明白点,中间件其实就是一个闭包,而且返回一个闭包。中间件为过滤进入应用的HTTP请求提供了一套便利的机制,常用于验证用户是否经过认证,添加响应头(跨域),记录请求日志等。
二 、 用到的一些概念
1.闭包函数
也就是常说的匿名函数(什么是匿名?没有函数名不就是匿名了么…秀- -),允许临时创建一个没有指定名称的函数。最经常用作回调函数(callback)参数的值。
PHP中的匿名函数:PHP在5.3的版本之后支持了匿名函数,并统归属于Closure类下,通过Closure类来实现。那这就给我们在判断匿名函数时带来一定的好处了(稍后代码体现)。
三 、 服务注册配置思路
- 注册服务 按一下格式
/**
* @brief 注册获取服务
*
* @param string[]
*
* @return string[]
*/
static public function getServiceProviders()
{
return [
"test1" => A::class,
"test2" => C::class,
"test3" => C::class,
];
}
- 初始化中间件
/**
* @brief 初始化中间件
*
* @param $this
*
* @return $this
*/
public function initMiddleware() {
$this->test1 (["===","-++++++++"]);
$this->test2 ('================');
$this->test5 ('---------');
return $this;
}
/**
* @brief 方法不存在,进行重载函数
*
* @param void
*
* @return void
*/
public function __call($name, $arg)
{
// TODO: Implement __call() method.
$service = new Service();
//PHP7 中的 Closure :: call()方法具有更好的性能,该方法被添加为临时将对象范围绑定到闭包并调用它。
var_dump ($service->getName(self::getServiceProviders (),$name)->call($this,...$arg));
return $service->getName(self::getServiceProviders (),$name)->call($this,...$arg);
}
四、中间件开发思路
- 构建中间件服务类,首先通过getName()方法获取服务名称
/**
* @brief 获取服务名称
*
* @param mixed|void
*
* @return mixed|void
*/
public function getName($serviceProviders,$name)
{
if (array_key_exists ($name,$serviceProviders))
{
$class = $serviceProviders[$name];
return $this->inject($name,$class);
}
exit("没有匹配");
return;
}
- 通过inject 方法进行注册服务
/**
* @brief 注册服务
*
* @param mixed
*
* @return mixed
*/
public function inject($name,$class)
{
return (new $class())->callback($name);
}
- 通过匿名函数,进行具体的业务实现
class A
{
/**
* @brief 匿名函数
*
* @param mixed
*
* @return mixed
*/
public function callback($name)
{
$name =function ($str) {
//进行具体业务
return $str;
};
return $name;
}
}
class C
{
/**
* @brief 匿名函数
*
* @param mixed
*
* @return mixed
*/
public function callback($name)
{
$name = function ($str) {
//进行具体业务
return $str;
};
return $name;
}
}
完整代码
<?php
/**
* @Created by PhpStorm.
* @brief
* @User: gzy
* @Date: 2020/5/7
*/
class A
{
/**
* @brief 匿名函数
*
* @param mixed
*
* @return mixed
*/
public function callback($name)
{
$name =function ($str) {
return $str;
};
return $name;
}
}
class C
{
/**
* @brief 匿名函数
*
* @param mixed
*
* @return mixed
*/
public function callback($name)
{
$name = function ($str) {
return $str;
};
return $name;
}
}
class Service
{
/**
* @brief 注册服务
*
* @param mixed
*
* @return mixed
*/
public function inject($name,$class)
{
return (new $class())->callback($name);
}
/**
* @brief 获取服务名称
*开始
* @param mixed|void
*
* @return mixed|void
*/
public function getName($serviceProviders,$name)
{
if (array_key_exists ($name,$serviceProviders))
{
$class = $serviceProviders[$name];
return $this->inject($name,$class);
}
exit("没有匹配");
return;
}
}
class B
{
/**
* @brief 注册获取服务
*
* @param string[]
*
* @return string[]
*/
static public function getServiceProviders()
{
return [
"test1" => A::class,
"test2" => C::class,
"test3" => C::class,
];
}
/**
* @brief 初始化中间件
*
* @param $this
*
* @return $this
*/
public function initMiddleware() {
$this->test1 (["===","-++++++++"]);
$this->test2 ('================');
$this->test5 ('---------');
return $this;
}
/**
* @brief 方法不存在,进行重载函数
*
* @param void
*
* @return void
*/
public function __call($name, $arg)
{
// TODO: Implement __call() method.
$service = new Service();
//PHP7 中的 Closure :: call()方法具有更好的性能,该方法被添加为临时将对象范围绑定到闭包并调用它。
var_dump ($service->getName(self::getServiceProviders (),$name)->call($this,...$arg));
return $service->getName(self::getServiceProviders (),$name)->call($this,...$arg);
}
}
$B = new B();
$B->initMiddleware();
结果
[root@localhost Creeper-new]# php test.php
array(2) {
[0]=>
string(3) "==="
[1]=>
string(9) "-++++++++"
}
string(16) "================"
没有匹配
PHP函数的参数里,前面三个点的形式…$args是什么含义和用法?
function add($a, $b, $c)
{
return $a + $b + $c;
}
$num=[2, 3];
echo add(1, ...$num); //6
以上目的是理解。这个代码仅用与学习。