一 、 什麼是中間件
中間件是一個輕量級、底層的插件系統,可以介入應用主題從請求到響應的處理過程。
說明白點,中間件其實就是一個閉包,而且返回一個閉包。中間件爲過濾進入應用的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
以上目的是理解。這個代碼僅用與學習。