SuperAPI AI 工具集

php-http-psr

编程与开发

查看项目

更新于 10-26 16:23

技能介绍

用途

该技能用于在编写与框架无关的 PHP HTTP 代码时提供指导,覆盖 PSR-7、PSR-15、PSR-17、PSR-18 四项标准。这些标准让库能够处理 HTTP 而不与任何框架耦合:代码依赖接口(Psr\Http*),具体实现通过注入提供。

不适用于 Laravel 自身的 HTTP 层(应改用 laravel-expert),也不适用于 Symfony 的 HttpFoundation 组件——后者是另一种非 PSR-7 的 HTTP 模型;需要时可通过 symfony/psr-http-message-bridge 桥接两者(参见 references/implementations.md)。

主要能力

四项标准及其对应包与提供内容:

  • PSR-7(psr/http-message):不可变 HTTP 消息,包括 MessageInterface、RequestInterface、ResponseInterface、ServerRequestInterface、StreamInterface、UriInterface、UploadedFileInterface。
  • PSR-15(psr/http-server-handler + psr/http-server-middleware):RequestHandlerInterface、MiddlewareInterface,即中间件管道。
  • PSR-17(psr/http-factory):在不指定具体类的情况下创建 PSR-7 对象的工厂。
  • PSR-18(psr/http-client):ClientInterface::sendRequest(),发送 PSR-7 请求并获得 PSR-7 响应。

技能还包含参考实现(nyholm/psr7、guzzlehttp/psr7、laminas-diactoros)及其选择指导,以及一个完整的中间件管道模板。

关键规则

  • 消息是不可变的:每个 with*() 返回新实例,原实例不变。单独调用 $r->withHeader(...) 是空操作,必须重新赋值。
  • 依赖接口而非类:类型提示使用 ResponseInterface,注入 ResponseFactoryInterface。可复用代码中绝不 new Response()。
  • 流不是不可变的:StreamInterface 包装真实资源;请求/响应应使用只读流。
  • PSR-18 的 4xx/5xx 不是错误:客户端必须将其作为正常响应返回;仅在传输失败(NetworkExceptionInterface)或请求格式错误(RequestExceptionInterface)时抛出异常。
  • 头部大小写不敏感:getHeaderLine('foo') == getHeaderLine('FOO');getHeaders() 保留原始大小写。

使用方式

技能规定了强制性的代理工作流:在任何实现之前,并行启动 3 个代理,每个 Agent 调用带一个名称:

  • fuse-ai-pilot:explore-codebase:检测 composer.json 中已在使用的 PSR-7 实现。
  • fuse-ai-pilot:research-expert:在 php-fig.org 与 Packagist 上核实当前接口版本。
  • mcp__context7__query-docs:检查所选实现的工厂 API。

实现之后,运行 fuse-ai-pilot:sniper 进行验证。

架构示例:

src/ ├── Http/ │ ├── Middleware/ # implements Psr\Http\Server\MiddlewareInterface │ │ ├── ErrorHandlerMiddleware.php │ │ └── AuthMiddleware.php │ ├── Handler/ # implements Psr\Http\Server\RequestHandlerInterface │ │ └── Dispatcher.php # the pipeline runner │ └── Client/ # wraps a Psr\Http\Client\ClientInterface └── interfaces/ # your own contracts (SOLID)

完整可运行的管道参见 middleware-pipeline.md。

参考指南按主题组织:消息(psr7-messages.md)、中间件(psr15-middleware.md)、工厂(psr17-factories.md)、HTTP 客户端(psr18-client.md)、实现选择(implementations.md)。模板包括 middleware-pipeline.md(构建带中间件队列的 PSR-15 调度器)。

快速参考示例:

不可变更新(需重新赋值):

$response = $response ->withStatus(201) ->withHeader('Content-Type', 'application/json');

最小中间件:

final class AuthMiddleware implements MiddlewareInterface { public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface { if (!$request->hasHeader('Authorization')) { return $this->responseFactory->createResponse(401); } return $handler->handle($request); } }

PSR-17 工厂(不指定具体类):

$request = $requestFactory->createRequest('GET', 'https://api.example.com'); $request = $request->withBody($streamFactory->createStream('{"ping":true}'));

全部六个工厂接口参见 psr17-factories.md。

最佳实践

应当:注入 ResponseFactoryInterface,使中间件不指定具体类;将捕获异常的中间件放在队列最前(PSR-15 建议);需要轻量、严格的 PSR-7 + PSR-17 单包时使用 nyholm/psr7;对每个 with*() 调用的结果重新赋值。

不应:就地修改消息——with*() 返回新对象;将 PSR-18 客户端返回的 404/500 响应视为异常;混淆 Symfony HttpFoundation 与 PSR-7——两者不同,需通过 symfony/psr-http-message-bridge 桥接;在库代码中硬编码 new GuzzleHttp\Psr7\Response()——应依赖工厂。

适用场景

适用于构建与框架无关的 PHP HTTP 代码,包括 PSR-7/15/17/18 消息、中间件、工厂和客户端。

限制

不适用于 Laravel 自身的 HTTP 层,也不适用于 Symfony 的 HttpFoundation 组件。