概述
一个框架中的中间件是必不可少的一部分。
以前对这方面是有点懵逼的,只知其然但不知其所以然,在网上看了一些大佬写的文章后,有点想法,希望对初学者有所帮助。
中间件就是给应用外面加一个 “结界” ,在进入应用之前,要经过结界;离开应用之后,也要经过它。
怎么感觉我越说越迷啊。。。。。。
step-0
先看一段很简单很普通的代码。
function main()
{
// 前置操作,例如对身份的验证之类
echo 'this is before middleware';
// 业务逻辑操作
// ....
echo 'this body of application';
// 后置操作,发射响应包之类
echo 'this is back middleware';
}
// 执行
main();
复制代码
step-1
然后,我们试着把前置操作和后置操作从业务逻辑部分抽离出来,用到了闭包,也是本次的主角:
$before_middleware = function () {
echo 'this is before middleware';
};
$back_middleware = function () {
echo 'this is back middleware';
};
$body = function () {
echo 'this body of application';
};
function main($fmw, $body, $bmw)
{
$fmw();
$body();
$bmw();
}
// 执行
main($before_middleware, $back_middleware);
复制代码
step-2
“我裤子都脱了,你就给我看这个??”
哈哈,好吧,这只是为了从无到有展现我的心路历程,也是强调基础的重要性,毕竟那些了不起的应用和框架都是由基础的语法构建的。还有一个更重要的原因,就是先让大家适应一下php的闭包。
来点不一样的写法:
$before_middleware = function ($body) {
return function () use ($body) {
echo 'this is before middleware' . "\n";
return $body();
};
};
$back_middleware = function ($body) {
return function () use ($body) {
$bd = $body();
echo 'this is back middleware' . "\n";
return $bd;
};
};
$body = function () {
echo 'this body of application' . "\n";
};
// 准备
$body = $before_middleware($body);
$body = $back_middleware($body);
// 执行
$body();
复制代码
step-3
是不是感觉有点意思了?? 然后再把 “准备” 步骤进行一下封装,比如说这样:
$before_middleware = function ($body) {
return function () use ($body) {
echo 'this is before middleware' . "\n";
return $body();
};
};
$back_middleware = function ($body) {
return function () use ($body) {
$bd = $body();
echo 'this is back middleware' . "\n";
return $bd;
};
};
$body = function () {
echo 'this body of application' . "\n";
};
// 准备
$conf = array(
$before_middleware,
$back_middleware,
);
function ready($body, $conf)
{
foreach ($conf as $midd) {
$body = $midd($body);
}
return $body;
}
// 执行
$res = ready($body, $conf);
$res();
复制代码
最后
这个是我便于理解,所以写的超简化版本,也就是介绍一下原理。
想一下,这个前置和后置的操作是不是还可以做一个抽象??试试把真正要执行的中间件函数作为参数传入,从而代替 echo
的位置呢??或者在这个之上再做一层闭包封装??
额,貌似还是没讲明白......希望对小白同学有所帮助~~
我看了网上的版本,除了闭包实现的中间件,yield
这个不怎么常用的东西也可以。正好今天公司里,我写的一个脚本因为一次性从数据库里拉的数据量大,导致了内存的fatal错误。打算对 yield
做一次系统学习。
欲知后事如何,且听下回分解!