PHP code example of kode / middleware

1. Go to this page and download the library: Download kode/middleware library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

kode / middleware example snippets




ode\Middleware\Pipe;
use Kode\Middleware\Routing\RouteResult;
use Kode\Middleware\Routing\RouteMiddleware;
use Kode\Middleware\TraceMiddleware;
use Kode\Middleware\ScopeMiddleware;
use Nyholm\Psr7\Response;
use Nyholm\Psr7\ServerRequest;

// 路由匹配器:返回 RouteResult
$matcher = new RouteMiddleware(function (ServerRequest $req): RouteResult {
    if ($req->getUri()->getPath() === '/user/{id}') {
        return RouteResult::matched(
            handler: fn ($r) => new Response(200, [], 'user'),
            params:   ['id' => '42'],
            name:     'user.show'
        );
    }
    return RouteResult::notFound();
});

$response = Pipe::create()
    ->alias('auth', AuthMiddleware::class)
    ->beforeRoute(new TraceMiddleware(), new ScopeMiddleware()) // 全局前置
    ->router($matcher)
    ->afterRoute('auth')                                       // 路由后:可读路由元数据
    ->fallback(fn ($req) => new Response(404, [], 'Not Found'))
    ->handle(new ServerRequest('GET', '/user/42'));

echo $response->getBody(); // "user"



use Kode\Middleware\Pipeline;
use Kode\Middleware\middleware;

$pipeline = (new Pipeline())
    ->add(new TraceMiddleware())                                   // 最外层
    ->add(middleware(fn ($req, $next) =>
        $next->handle($req->withAttribute('t', microtime(true)))))  // 闭包式中间件
    ->withDestination($controller);                                // 最内层终点

$response = $pipeline->handle($request);

use function Kode\Middleware\pipeline;
use function Kode\Middleware\pipe;
use function Kode\Middleware\middleware;
use function Kode\Middleware\handler;
use function Kode\Middleware\lazy;
use function Kode\Middleware\when;
use function Kode\Middleware\boundary;
use function Kode\Middleware\profiler;
use function Kode\Middleware\profile_of;
use function Kode\Middleware\route_of;
use function Kode\Middleware\runner_of;
use function Kode\Middleware\concurrently;
use function Kode\Middleware\capabilities;
use function Kode\Middleware\kernel;

$p = pipeline([
    new TraceMiddleware(),
    when(fn ($req) => $req->getUri()->getPath() === '/health' ? false : true, $auth),
]);

// 探测当前环境的并发能力
print_r(capabilities());
// ['sync' => true, 'fiber' => true, 'thread' => false, 'process' => false]

// 框架集成入口
$k = kernel(pipe()->beforeRoute(boundary(fn ($e) => new Response(500))));



use Kode\Middleware\Pipe;
use Kode\Middleware\Kernel;

$kernel = Pipe::create()
    ->onError(fn (\Throwable $e) => new Response(500, [], 'E:' . $e->getMessage())) // 洋葱最外层异常边界
    ->beforeRoute(new TraceMiddleware(), new ScopeMiddleware())
    ->router($matcher)
    ->afterRoute('auth')
    ->fallback(fn () => new Response(404, [], 'Not Found'))
    ->kernel()                                  // 洋葱之外的壳
    ->onRequest(fn ($req) => $req->withAttribute('boot', 1))
    ->onResponse(fn ($resp) => $resp->withHeader('X-Done', '1'));

// 常驻内存(Swoole / RoadRunner):boot 一次,每请求 handle,写回后 terminate
$kernel->boot();
$response = $kernel->handle($request);
emit($response);
$kernel->terminate($request, $response);

// 传统 FPM:handle + terminate 一体
$response = $kernel->run($request);

use Kode\Middleware\Registry;

$registry = (new Registry())
    ->alias('auth', AuthMiddleware::class)
    ->group('guard', ['session', 'csrf', 'auth'])      // 引用别名
    ->group('api', ['cors', 'guard']);                // 递归引用分组

$registry->expand('api'); // ['cors', 'session', 'csrf', AuthMiddleware::class]

use Kode\Middleware\Pipe;

$pipe = Pipe::create()
    // 内联一条嵌套子管道,作为当前位置的一层洋葱(共享容器与注册表)
    ->nest(fn (Pipe $sub) => $sub
        ->beforeRoute(Factory::tagging('inner-a'))
        ->afterRoute(Factory::tagging('inner-b')))
    // 把已注册的命名分组作为一层嵌套洋葱插入
    ->useGroup('guard')
    ->beforeRoute(TraceMiddleware::class)
    ->fallback(fn () => new Response(404));

use Kode\Middleware\Pipe;
use Kode\Middleware\Routing\Router;

$router = (new Router())
    ->add('/', fn ($req) => new Response(200, [], 'home'))
    ->add('/users/{id}', UserController::class . '@show', ['api.guard'], 'user.show', ['GET'])
    ->add('/admin/{path:.+}', AdminController::class, ['admin.guard']);

$pipe = Pipe::create($container)
    ->group('api.guard', ['cors', 'auth'])      // 分组定义
    ->router($router->matcher())                // 接入路由收集器
    ->fallback(fn () => new Response(404));

$pipe->handle($request);
// 命中 /users/42 时:auth/cors(api.guard 分组展开为嵌套层)→ 控制器
// 路径参数 {id}=42 会被平铺到 $request->getAttribute('id')

$router = (new Router())
    ->group('/api', ['cors'], function (Router $r): void {
        $r->add('/users', UserController::class, ['auth']);
        $r->group('/v1', ['v1'], function (Router $r): void {
            $r->add('/ping', PingController::class);
        });
    });

// /api/users    → 中间件 [cors, auth]
// /api/v1/ping  → 中间件 [cors, v1]

$pipe = Pipe::create()->router($router)->fallback(fn () => new Response(404));

$pipe = Pipe::create()
    ->group('auth', [AuthMiddleware::class])        // 命名中间件分组
    ->route('/', fn () => new Response(200, [], 'home'))
    ->route('/users/{id}', UserController::class . '@show', ['auth'], 'user.show', ['GET'])
    ->routeGroup('/api', ['cors'], function (Pipe $p): void {
        $p->route('/ping', fn () => new Response(200, [], 'pong'));
        $p->route('/secure', fn () => new Response(200, [], 's'), ['auth']);
    })
    ->fallback(fn () => new Response(404));

// /api/ping    → 命中 cors 分组链路
// /api/secure  → 同时命中 cors(路由分组)+ auth(路由级命名分组)

use function Kode\Middleware\bridge;

$kernel = bridge(
    pipe: Pipe::create($container)
        ->route('/', fn () => new Response(200, [], 'home'))
        ->route('/users/{id}', UserController::class . '@show', ['auth'])
        ->fallback(fn () => new Response(404)),
    hooks: [
        'boot'       => fn (Kernel $k) => RouteCache::warm(),
        'onResponse' => fn (ResponseInterface $r, $q) => $r->withHeader('X-Powered-By', 'kode'),
        'rescue'     => fn (\Throwable $e, $q) => new Response(500, [], 'err'),
    ],
    renderer: fn (\Throwable $e, $q) => new Response(500, [], $e->getMessage()), // 异常边界渲染器(必填)
);

$kernel->boot();                 // 常驻内存:启动期一次
$response = $kernel->handle($request); // 每请求,协程安全

use Kode\Middleware\Codegen\MiddlewareGenerator;

$code = (new MiddlewareGenerator('App\Middleware'))
    ->generate('AuthMiddleware', ['priority' => 1000, 'description' => '鉴权']);

file_put_contents(__DIR__ . '/AuthMiddleware.php', $code);

// 命名空间函数版
$code = \Kode\Middleware\generate_middleware('AuthMiddleware', [
    'priority' => 1000,
    'namespace' => 'App\Middleware',
]);

use Kode\Middleware\Concurrency\Runner\RunnerFactory;

$runner = RunnerFactory::make(RunnerFactory::DRIVER_AUTO, RunnerFactory::PROFILE_IO);



use Kode\Middleware\Concurrency\ConcurrentMiddleware;
use function Kode\Middleware\concurrently;

$pipe = Pipe::create()
    ->beforeRoute(new ConcurrentMiddleware(RunnerFactory::DRIVER_AUTO, RunnerFactory::PROFILE_IO))
    ->router($matcher)
    ->fallback($notFound);

// 控制器内
[$user, $orders, $coupons] = array_values(concurrently($request, [
    'user'    => fn () => $userApi->find($id),
    'orders'  => fn () => $orderApi->recent($id),
    'coupons' => fn () => $couponApi->usable($id),
], timeout: 2.0));



use Kode\Middleware\Distributed\TraceMiddleware;
use Kode\Middleware\Distributed\Propagator;

$pipe->beforeRoute(new TraceMiddleware(exposeResponseHeaders: true, syncToContext: true));

// 业务任意深处读取链路 ID
$traceId = TraceMiddleware::traceIdOf($request);

// 调用下游服务时透传(把当前链路继续往下传)
$client->get($url, ['headers' => Propagator::forward($request)]);



use Kode\Middleware\Registry;
use Kode\Middleware\Pipeline;
use Kode\Middleware\Resolver;

$registry = (new Registry())
    ->alias('auth', AuthMiddleware::class)
    ->group('web', ['session', 'csrf', 'auth'])
    ->factory('throttle', fn (string $max = '60', string $per = '1') =>
        new RateLimitMiddleware((int) $max, (int) $per));

$pipeline = Pipeline::of(['web', 'throttle:100,1'], new Resolver(null, $registry));



use Kode\Middleware\Blueprint;

// 主进程 / 配置中心
$json = $pipe->blueprint()->toJson();

// Worker 进程 / 其它节点
$pipeline = Blueprint::fromJson($json)->rebuild($container);