<?php

class MiddlewareStack
{
private $middlewares = [];
private $request;
private $response; /**
* 添加中间件到堆栈
*
* @param callable $middleware 中间件函数,接受请求、响应和下一个中间件作为参数
*/
public function add(callable $middleware)
{
$this->middlewares[] = $middleware;
} /**
* 设置请求和响应处理函数
*
* @param callable $request 请求处理函数,无参数,返回一个请求对象或数据
* @param callable $response 响应处理函数,接受请求处理结果作为参数,返回最终响应
*/
public function setHandlers(callable $request, callable $response)
{
$this->request = $request;
$this->response = $response;
} /**
* 处理请求,通过中间件堆栈
*
* @return mixed 响应结果
*/
public function handle()
{
$next = function ($requestData) use (&$next) {
// 如果没有更多的中间件,调用最终的响应处理函数
if (empty($this->middlewares)) {
return call_user_func($this->response, $requestData);
} // 取出下一个中间件并调用
$middleware = array_shift($this->middlewares);
return $middleware($requestData, $this->response, $next);
}; // 从第一个中间件开始处理
$requestData = call_user_func($this->request);
return $next($requestData);
}
} // 示例中间件:身份验证
function authMiddleware($requestData, $response, $next) {
// 模拟身份验证检查
if (!isset($requestData['user'])) {
return "Unauthorized"; // 或者返回一个适当的 HTTP 响应
}
return $next($requestData);
} // 示例中间件:日志记录
function loggingMiddleware($requestData, $response, $next) {
$startTime = microtime(true);
$responseData = $next($requestData);
$endTime = microtime(true);
// 这里可以记录日志,例如使用 monolog 或其他日志库
echo "Request took " . ($endTime - $startTime) . " seconds\n";
return $responseData;
} // 示例请求处理函数
function requestFunction() {
// 模拟一个请求,例如从 $_GET, $_POST, 或其他来源获取数据
return [
'user' => 'john_doe', // 模拟已验证的用户
// 其他请求数据...
];
} // 示例响应处理函数
function responseFunction($requestData) {
// 处理请求数据并生成响应
return "Hello, " . $requestData['user'] . "!";
} // 使用中间件
$middlewareStack = new MiddlewareStack();
$middlewareStack->add(authMiddleware);
$middlewareStack->add(loggingMiddleware);
$middlewareStack->setHandlers(requestFunction, responseFunction); // 处理请求
$response = $middlewareStack->handle();
echo $response;

稍微改造一下:

<?php

class MiddlewareStack
{
private $middlewares = [];
private $request;
private $response; /**
* 添加中间件到堆栈
*
* @param callable $middleware 中间件函数,接受请求、响应和下一个中间件作为参数
*/
public function add(callable $middleware)
{
$this->middlewares[] = $middleware;
} /**
* 设置请求和响应处理函数
*
* @param callable $request 请求处理函数,无参数,返回一个请求对象或数据
* @param callable $response 响应处理函数,接受请求处理结果作为参数,返回最终响应
*/
public function setHandlers(callable $request, callable $response)
{
$this->request = $request;
$this->response = $response;
} /**
* 处理请求,通过中间件堆栈
*
* @return mixed 响应结果
*/
public function handle()
{
$next = function ($requestData) use (&$next) {
// 如果没有更多的中间件,调用最终的响应处理函数
if (empty($this->middlewares)) {
return call_user_func($this->response, $requestData);
} // 取出下一个中间件并调用
$middleware = array_shift($this->middlewares);
return $middleware($requestData, $this->response, $next);
}; // 从第一个中间件开始处理
$requestData = call_user_func($this->request);
return $next($requestData);
}
} // 示例中间件:身份验证
class authMiddleware{
public static function is() {
return function($requestData, $response, $next){
// 模拟身份验证检查
if (!isset($requestData['user'])) {
return "Unauthorized"; // 或者返回一个适当的 HTTP 响应
}
return $next($requestData);
};
}
} // 示例中间件:身份验证
function authMiddleware1($requestData, $response, $next) {
// 模拟身份验证检查
if (!isset($requestData['user'])) {
return "Unauthorized"; // 或者返回一个适当的 HTTP 响应
}
return $next($requestData);
} // 示例中间件:日志记录
function loggingMiddleware($requestData, $response, $next) {
$startTime = microtime(true);
$responseData = $next($requestData);
$endTime = microtime(true);
// 这里可以记录日志,例如使用 monolog 或其他日志库
echo "Request took " . ($endTime - $startTime) . " seconds\n";
return $responseData;
} // 示例请求处理函数
function requestFunction() {
// 模拟一个请求,例如从 $_GET, $_POST, 或其他来源获取数据
return [
'user' => 'john_doe', // 模拟已验证的用户
// 其他请求数据...
];
} // 示例响应处理函数
function responseFunction($requestData) {
// 处理请求数据并生成响应
return "Hello, " . $requestData['user'] . "!";
} // 使用中间件
$middlewareStack = new MiddlewareStack();
$middlewareStack->add(authMiddleware::is());
$middlewareStack->add(loggingMiddleware);
$middlewareStack->setHandlers(requestFunction, responseFunction); // 处理请求
$response = $middlewareStack->handle();
echo $response;

AI回答:一个简洁的php中间件类的更多相关文章

  1. .NET Core中间件的注册和管道的构建(2)---- 用UseMiddleware扩展方法注册中间件类

    .NET Core中间件的注册和管道的构建(2)---- 用UseMiddleware扩展方法注册中间件类 0x00 为什么要引入扩展方法 有的中间件功能比较简单,有的则比较复杂,并且依赖其它组件.除 ...

  2. classmethod一个用处是创建可选类构造器

    Definition and Introduction通常来说, descriptor 是一种绑定着特殊行为属性的对象, 在访问它时行为被descriptor协议定义的方法所重载.这些方法是__get ...

  3. 用UseMiddleware扩展方法注册中间件类

    用UseMiddleware扩展方法注册中间件类 .NET Core中间件的注册和管道的构建(2)---- 用UseMiddleware扩展方法注册中间件类 0x00 为什么要引入扩展方法 有的中间件 ...

  4. 如何一秒钟从头构建一个 ASP.NET Core 中间件

    前言 其实地上本没有路,走的人多了,也便成了路. -- 鲁迅 就像上面鲁迅说的那样,其实在我们开发中间件的过程中,微软并没有制定一些策略或者文档来约束你如何编写一个中间件程序, 但是其中却存在者一些最 ...

  5. DevOps运动的缘起 将DevOps想象为一种编程语言里面的一个接口,而SRE类实现了这个接口

     SRE vs DevOps:是敌是友? - DockOne.io http://www.dockone.io/article/5935   RE vs DevOps:是敌是友? [编者的话]网站可靠 ...

  6. 3.实现一个名为Person的类和它的子类Employee,Employee有两个子类Faculty 和Staff。

    23.实现一个名为Person的类和它的子类Employee,Employee有两个子类Faculty 和Staff. 具体要求如下: (1)Person类中的属性有:姓名name(String类型) ...

  7. 一天一个Java基础——对象和类

    1.在Java中你所做的全部工作就是定义类,产生那些类的对象,以及发送消息给这些对象 2.可以在类中设置两种类型的元素:字段(也被称作数据成员)和方法(也被称作成员函数) 3.字段可以是任何类型的对象 ...

  8. 一个简洁的PHP可逆加密函数(分享)

    http://www.jb51.net/article/38018.htm 本篇文章是对一个简洁的PHP可逆加密函数进行了详细的分析介绍,需要的朋友参考下   很多时候我们需要对数据进行加密解密,比如 ...

  9. 一个简洁的小H车调运模型

    一个简洁的小H车调运模型 不久前, 帝都B城市到处都是小H车, 理想的小H车应该是布朗运动\均匀分布,可是现实上它们就是不均匀.于是有如下问题: 观察帝都 HD区SY村区域,将其划分成10个用车点,用 ...

  10. 一个漂亮的php验证码类

    一个漂亮的php验证码类(分享)   作者: 字体:[增加 减小] 类型:转载 下面小编就为大家分享一个漂亮的php验证码类.需要的朋友可以过来参考下   直接上代码: 复制代码 代码如下: //验证 ...

随机推荐

  1. 龙哥量化:通达信的函数ma均线,ema、sma、dma的计算原理是什么,XMA是未来函数

    注意均线也有未来函数,常见的是跨周期的用法,会导致信号闪烁, 不常见的是XMA这个未来函数太坑了, [代写公式,龙哥微信:Long622889] MA.EMA.SMA.DMA.TMA.WMA6种平均算 ...

  2. Qt开发经验小技巧161-165

    经常有人说Qt垃圾,说用Qt在1毫秒绘制几千个数据点卡成屎.其实显示器最高刷新频率一般才60帧,1毫秒就绘制一次有意义吗?不仅显示器没刷新过来,人肉眼也看不过来(有人可能又要抬杠说这是老板要求的,显示 ...

  3. Qt编写的项目作品29-RTSP播放器+视频监控(海康SDK版本)

    一.功能特点 支持播放视频流和本地MP4文件. 支持句柄和回调两种模式. 多线程显示图像,不卡主界面. 自动重连网络摄像头. 可设置边框大小即偏移量和边框颜色. 可设置是否绘制OSD标签即标签文本或图 ...

  4. [转]OpenCV学习笔记(十五)——摄像机的标定和3D重建calib3D

    OpenCV学习笔记(十五)--摄像机的标定和3D重建calib3D OpenCV学习笔记(16)双目测距与三维重建的OpenCV实现问题集锦(一)图像获取与单目定标 翻译 搜索 复制

  5. IDEA中基于SSM框架进行web开发部署项目到Tomcat时报错:Error:Cannot build artifact '******:war exploded' because it is included into a circular depency的解决办法

    在Idea中使用Maven创建父子工程,第一个Model的那个项目可以很好的运行,在创建一个Model运行时报这个错.原因是tomcat部署了多个Web项目,可能最开始是两个项目的配置文件混用用,最后 ...

  6. RL中on-policy和off-policy的本质区别/重要性采样

    本随笔的图片都来自UCL强化学习课程lec5 Model-free prediction的ppt (Teaching - David Silver ). 回忆值函数的表达式: \[v_\pi(s) = ...

  7. 前端学习openLayers配合vue3(圆形形状的绘制)

    上节课我们学了加载了矢量图片,这节我们来学绘制圆形 关键代码,第一段呢是设置圆点的操作,第二步是点击地图获取地图位置来设置圆点,ol还有很多类,各种形状的 //设置圆点 // let anchorLa ...

  8. 基于Qt的OFD阅读器开发原理与实践

    摘要 本文详细探讨了基于Qt开发OFD阅读器的原理与实践.通过解析OFD文件格式.构建文档结构.实现页面渲染.处理用户交互以及进行性能优化,本文展示了如何使用Qt框架开发一个功能强大.性能优异的OFD ...

  9. CDS标准视图:技术对象类别文本 I_TechnicalObjectTypeText

    视图名称:技术对象类别文本 I_TechnicalObjectTypeText 视图类型:基础 视图代码: 点击查看代码 @EndUserText.label: 'Technical Object T ...

  10. 经典算法的Java实现

    1.快速排序描述 1.每一轮排序选择一个基准点(pivot)进行分区 1.让小于基准点的元素进入一个分区,大于基准点的元素进入另一个分区 2.当分区完成时,基准点元素的位置就是其最终位置 2.在子分区 ...