http-interop / http-factory-discovery
用于定位可用的 HTTP 工厂实现
1.6.0
2023-11-06 13:40 UTC
Requires
- php: >=7.1
- psr/http-client: ^1.0
- psr/http-factory: ^1.0
Requires (Dev)
- nyholm/psr7: ^1.0
- php-http/guzzle6-adapter: ^2.0
- phpstan/phpstan: ^0.10.3
- phpstan/phpstan-phpunit: ^0.10.0
- phpunit/phpunit: ^7.3
- squizlabs/php_codesniffer: ^3.3
Suggests
- http-interop/http-factory-diactoros: HTTP Factory implementation for Zend Diactoros
- http-interop/http-factory-guzzle: HTTP Factory implementation for Guzzle
- http-interop/http-factory-slim: HTTP Factory implementation for Slim
- nyholm/psr7: HTTP Messages with Factory implementation
- php-http/guzzle6-adapter: HTTP Client implementation for Guzzle
- sunrise/http-factory: HTTP Messages with Factory implementation
- zendframework/zend-diactoros: HTTP Messages with Factory implementation
README
自动发现提供 HTTP 功能的实现。允许在最小的工作量下快速切换不同的实现。
默认情况下,可以发现以下实现
HTTP 工厂
HTTP 客户端
可以注册其他额外的实现 。
安装
composer require http-interop/http-factory-discovery
使用方法
HTTP 工厂
use Http\Factory\Discovery\HttpFactory; /** @var \Psr\Http\Message\RequestFactoryInterface */ $requestFactory = HttpFactory::requestFactory(); /** @var \Psr\Http\Message\ResponseFactoryInterface */ $responseFactory = HttpFactory::responseFactory(); /** @var \Psr\Http\Message\ServerRequestFactoryInterface */ $serverRequestFactory = HttpFactory::serverRequestFactory(); /** @var \Psr\Http\Message\StreamFactoryInterface */ $streamFactory = HttpFactory::streamFactory(); /** @var \Psr\Http\Message\UriFactoryInterface */ $uriFactory = HttpFactory::uriFactory(); /** @var \Psr\Http\Message\UploadedFileFactoryInterface */ $uploadedFileFactory = HttpFactory::uploadedFileFactory();
HTTP 客户端
use Http\Factory\Discovery\HttpClient; /** @var \Psr\Http\Client\ClientInterface */ $client = HttpClient::client();
最佳实践
HTTP 工厂
使用 HTTP 工厂的示例之一是编写 PSR-15 中间件。
namespace Acme\Middleware; use Http\Factory\Discovery\HttpFactory; use Psr\Http\Message\ResponseFactoryInterface; use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Message\StreamFactoryInterface; use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface as Handler; class CatchErrors extends MiddlewareInterface { /** @var ResponseFactoryInterface */ private $responseFactory; /** @var StreamFactoryInterface */ private $streamFactory; public function __construct( ResponseFactoryInterface $responseFactory = null, StreamFactoryInterface $streamFactory = null ) { $this->responseFactory = $responseFactory ?? HttpFactory::responseFactory(); $this->streamFactory = $streamFactory ?? HttpFactory::streamFactory(); } public function process(Request $request, Handler $handler): Response { try { return $handler->handle($request); } catch (\Throwable $error) { $stream = $this->streamFactory->createStream($e->getMessage()); $response = $this->responseFactory->createResponse(500); $response = $response->withHeader('content-type', 'text/plain'); $response = $response->withBody($stream); return $response; } } }
HTTP 客户端
同时使用 HTTP 客户端和 HTTP 工厂的示例是编写发送 HTTP 请求的功能。
namespace Acme; use Http\Factory\Discovery\HttpClient; use Http\Factory\Discovery\HttpFactory; use Psr\Http\Client\ClientInterface; use Psr\Http\Message\RequestFactoryInterface; class Api { /** @var ClientInterface */ private $client; /** @var RequestFactoryInterface */ private $requestFactory; public function __construct( ClientInterface $client = null, RequestFactoryInterface $requestFactory = null ) { $this->client = $client ?? HttpClient::client(); $this->requestFactory = $requestFactory ?? HttpFactory::requestFactory(); } public function query(): string { $request = $this->requestFactory->createRequest('GET', 'http://acme.com/api'); return $this->client->sendRequest($request)->getBody()->getContents(); } }
注册额外的实现
可以注册额外的实现
HTTP 工厂
use Acme\RequestFactory; use Http\Factory\Discovery\FactoryLocator; use Psr\Http\Message\RequestFactoryInterface; FactoryLocator::register(RequestFactoryInterface::class, RequestFactory::class);
HTTP 客户端
use Acme\Client; use Http\Factory\Discovery\ClientLocator; use Psr\Http\Client\ClientInterface; ClientLocator::register(ClientInterface::class, Client::class);
如果不想使用它们,也可以取消注册实现
HTTP 工厂
use Http\Factory\Discovery\FactoryLocator; use Http\Factory\Guzzle\UriFactory; use Psr\Http\Message\UriFactoryInterface; FactoryLocator::unregister(UriFactoryInterface::class, UriFactory::class);
HTTP 客户端
use Http\Factory\Discovery\ClientLocator; use Http\Adapter\Guzzle6\Client; use Psr\Http\Client\ClientInterface; ClientLocator::unregister(ClientInterface::class, Client::class);
清除缓存
可以清除已发现实现的缓存
HTTP 工厂
use Http\Factory\Discovery\HttpFactory; use Psr\Http\Message\UriFactoryInterface; // Clear a single interface HttpFactory::clearCache(UriFactoryInterface::class); // Clear all interfaces HttpFactory::clearCache();
HTTP 客户端
use Http\Factory\Discovery\HttpClient; use Psr\Http\Client\ClientInterface; // Clear a single interface HttpClient::clearCache(ClientInterface::class); // Clear all interfaces HttpClient::clearCache();
注意:当调用 FactoryLocator::unregister()
或 ClientLocator::unregister()
时,会自动清除缓存。