This commit is contained in:
2025-11-26 05:09:36 +08:00
parent 926cbea0b9
commit 90ee572092
2 changed files with 103 additions and 1 deletions
+102
View File
@@ -0,0 +1,102 @@
<?php
use PhpParser\Error;
use PhpParser\Node;
use PhpParser\NodeDumper;
use PhpParser\NodeFactory;
use PhpParser\NodeTraverser;
use PhpParser\NodeVisitorAbstract;
use PhpParser\ParserFactory;
use PhpParser\PrettyPrinter\Standard;
use Psr\Http\Message\ResponseInterface;
class MiddlewareProxyGenerator {
private static string $cacheFile = __DIR__ . '/middleware_proxy.php';
private static NodeFactory $factory;
public static function generateProxy(array $middlewares): string {
self::$factory = new NodeFactory();
// 创建类结构(v5.5.0兼容写法)
$class = new Node\Stmt\Class_(
'MiddlewareProxy',
[
'implements' => [new Node\Name\FullyQualified(\Psr\Http\Server\MiddlewareInterface::class)],
'stmts' => []
]
);
// 生成中间件调用链
$method = self::createMethodNode($middlewares);
$class->stmts[] = $method;
// 生成代码
$printer = new Standard();
return $printer->prettyPrintFile([$class]);
}
private static function createMethodNode(array $middlewares): Node\Stmt\Function_ {
$method = new Node\Stmt\Function_(
'process',
[
'params' => [
new Node\Param(
new Node\Expr\Variable('request'),
null,
new Node\UnionType([new Node\Expr\Variable(\Psr\Http\Message\ServerRequestInterface::class)])
),
new Node\Param(
new Node\Expr\Variable('handler'),
null,
new Node\UnionType([new Node\Expr\Variable(\Psr\Http\Server\RequestHandlerInterface::class)])
)
],
'returnType' => new Node\Name(ResponseInterface::class),
'stmts' => []
]
);
// 生成中间件调用链(v5.5.0闭包写法)
$chain = [];
$count = count($middlewares);
for ($i = 0; $i < $count; $i++) {
$className = $middlewares[$i]::class;
$chain[] = self::createMiddlewareCall($i, $className, $count);
}
$method->stmts = array_reverse($chain);
return $method;
}
private static function createMiddlewareCall(int $index, string $className, int $count): Node {
$mwVar = new Node\Expr\Variable("mw{$index}");
$nextHandler = new Node\Expr\Variable("next");
// 创建中间件实例(v5.5.0兼容)
$instanciate = new Node\Expr\New_($className);
// 创建闭包表达式(v5.5.0语法)
$closure = new Node\Expr\Closure([
'static' => true,
'params' => [new Node\Param($nextHandler)],
'stmts' => [
new Node\Stmt\Expression(
new Node\Expr\MethodCall(
$instanciate,
'process',
[new Node\Arg($nextHandler), new Node\Arg($mwVar)]
)
)
]
]);
return new Node\Stmt\Expression($closure);
}
}
// 生成代理类代码
$middlewares = [AuthMiddleware::class, LogMiddleware::class];
$proxyCode = MiddlewareProxyGenerator::generateProxy($middlewares);
// 写入代理类文件
file_put_contents(MiddlewareProxyGenerator::$cacheFile, $proxyCode);