news 2026/6/6 12:24:31

PHP中间件架构与管道模式实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PHP中间件架构与管道模式实现

PHP中间件架构与管道模式实现

中间件是PHP框架的核心概念。请求经过一层层中间件处理,每层都可以决定放行还是拦截。今天说说中间件架构的原理和实现。

中间件的洋葱模型。请求从外到内经过每层中间件,响应从内到外再经过每层中间件。

```php
interface Middleware
{
public function handle(Request $request, callable $next): Response;
}

class Request
{
private array $attributes = [];

public function __construct(
private string $method = 'GET',
private string $uri = '/'
) {}

public function getMethod(): string { return $this->method; }
public function getUri(): string { return $this->uri; }

public function setAttribute(string $name, mixed $value): void
{
$this->attributes[$name] = $value;
}

public function getAttribute(string $name, mixed $default = null): mixed
{
return $this->attributes[$name] ?? $default;
}
}

class Response
{
public function __construct(
private string $body = '',
private int $statusCode = 200,
private array $headers = []
) {}

public function getBody(): string { return $this->body; }
public function getStatusCode(): int { return $this->statusCode; }
}
?>

具体的中间件实现。

```php
class AuthMiddleware implements Middleware
{
public function handle(Request $request, callable $next): Response
{
$token = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
if (empty($token)) {
return new Response('未授权', 401);
}
$request->setAttribute('user_id', 123);
return $next($request);
}
}

class LoggingMiddleware implements Middleware
{
public function handle(Request $request, callable $next): Response
{
$start = microtime(true);
$response = $next($request);
$duration = (microtime(true) - $start) * 1000;
error_log("{$request->getMethod()} {$request->getUri()} - {$duration}ms");
return $response;
}
}

class CorsMiddleware implements Middleware
{
public function handle(Request $request, callable $next): Response
{
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE');

if ($request->getMethod() === 'OPTIONS') {
return new Response('', 204);
}

return $next($request);
}
}

class RateLimitMiddleware implements Middleware
{
private int $maxRequests;
private array $counts = [];

public function __construct(int $maxRequests = 60)
{
$this->maxRequests = $maxRequests;
}

public function handle(Request $request, callable $next): Response
{
$ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
$this->counts[$ip] = ($this->counts[$ip] ?? 0) + 1;

if ($this->counts[$ip] > $this->maxRequests) {
return new Response('请求过多', 429);
}

return $next($request);
}
}
?>

中间件管道把多个中间件串联起来。

```php
class MiddlewarePipeline
{
private array $middlewares = [];

public function add(Middleware $middleware): self
{
$this->middlewares[] = $middleware;
return $this;
}

public function run(Request $request, callable $coreHandler): Response
{
$pipeline = $coreHandler;

foreach (array_reverse($this->middlewares) as $middleware) {
$pipeline = function (Request $request) use ($middleware, $pipeline) {
return $middleware->handle($request, $pipeline);
};
}

return $pipeline($request);
}
}

$pipeline = new MiddlewarePipeline();
$pipeline->add(new CorsMiddleware());
$pipeline->add(new LoggingMiddleware());
$pipeline->add(new AuthMiddleware());
$pipeline->add(new RateLimitMiddleware(100));

$response = $pipeline->run(new Request('GET', '/api/users'), function ($request) {
return new Response("Hello User #{$request->getAttribute('user_id')}");
});

echo $response->getBody() . "\n";
echo "状态码: {$response->getStatusCode()}\n";
?>

中间件让应用的功能模块化。每个中间件只负责自己的那点事,职责单一。想加缓存就加个CacheMiddleware,想加验证就加个ValidationMiddleware。这种架构让应用的扩展变得很方便。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/6 12:24:06

Horos开源医学影像查看器:macOS上免费的DICOM处理终极指南

Horos开源医学影像查看器:macOS上免费的DICOM处理终极指南 【免费下载链接】horos Horos™ is a free, open source medical image viewer. The goal of the Horos Project is to develop a fully functional, 64-bit medical image viewer for OS X. Horos is base…

作者头像 李华
网站建设 2026/6/6 12:23:27

STC12到STC15单片机硬件迁移:引脚不兼容的挑战与解决方案

1. 项目概述:从STC12到STC15的“惊喜”与挑战作为一名常年泡在实验室和万用板上的硬件工程师,我对STC单片机系列一直抱有复杂的情感。它们价格亲民、资料丰富,是很多学生和电子爱好者入门、甚至小批量产品开发的“老朋友”。我手头的主力型号…

作者头像 李华
网站建设 2026/6/6 12:22:39

LinkSwift:打破网盘下载限制的浏览器脚本终极解决方案

LinkSwift:打破网盘下载限制的浏览器脚本终极解决方案 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天翼…

作者头像 李华