strictphp / http-clients
提供各种 http 客户端实现,以提升开发者和 DevOps 的体验。
Requires
- php: >=8.1
- guzzlehttp/psr7: ^2.5
- illuminate/filesystem: ^9.0 || ^10.0 || ^11.0
- psr/container: ^2.0
- psr/event-dispatcher: ^1.0
- psr/http-client: ^1.0
- psr/http-message: ^1.0 || ^2.0
- psr/log: ^3.0
- psr/simple-cache: ^3.0
Requires (Dev)
- phpstan/phpstan: ^1.8
- phpstan/phpstan-deprecation-rules: ^1.1.3
- phpstan/phpstan-strict-rules: ^1.4
- phpunit/phpunit: ^11.2
- strictphp/conventions: ^1.0
This package is auto-updated.
Last update: 2024-09-12 09:15:21 UTC
README
HTTP 客户端包提供了一系列 HTTP 客户端,可用于在 PHP 应用程序中管理 HTTP 请求和响应。该包包含一个 ClientsFactory,通过允许您定义一系列 ClientFactoryContract 实现来简化客户端的创建。
功能
- 使用 PSR 容器进行依赖注入。
- CacheResponseClient:利用 PSR-6(simple-cache)进行响应缓存,通过为后续请求提供缓存响应来提高开发速度。
- CustomizeRequestClient:您可以在发送请求之前修改请求。
- EventClient:依赖于 PSR-14(event-dispatcher),允许您在请求之前、期间或之后附加事件,这对于日志记录或其他操作很有用。
- RetryClient:如果 sendRequest 调用抛出异常,它将尝试再次发送请求。
- SleepClient:允许您在请求之间引入等待间隔,这对于与需要速率限制的外部 API 交互可能是必要的。
- StoreClient:将您的 REQest 保存为 PHPStorm
REQ.http
文件,并将相应的 RESponse 保存为后缀为RES.<code>.[headers|xml|txt|json|html|pdf]
的文件。
安装
您可以通过 Composer 安装 HTTP 客户端包。
composer require strictphp/http-clients
用法
ClientsFactory 通过允许您使用依赖注入定义一系列 ClientFactoryContract 实现来简化客户端的创建。
示例
use Psr\Container\ContainerInterface; use Psr\Http\Client\ClientInterface; use StrictPhp\HttpClients\Clients\CacheResponse\CacheResponseClientFactory; use StrictPhp\HttpClients\Clients\CustomizeRequest\CustomizeRequestClientFactory; use StrictPhp\HttpClients\Clients\Event\EventClientFactory; use StrictPhp\HttpClients\Clients\Retry\RetryClientFactory; use StrictPhp\HttpClients\Clients\Sleep\SleepClientFactory; use Strictphp\HttpClients\Factories\ClientsFactory; use Strictphp\HttpClients\Iterators\FactoryToServiceIterator; // Assuming $client is the main client like GuzzleHttp\Client /** @var ClientInterface $client */ /** @var ContainerInterface $container */ // the order of classes is important, see image below $clients = [ CacheResponseClientFactory::class, // used like first RetryClientFactory::class, SleepClientFactory::class, EventClientFactory::class, CustomizeRequestClientFactory::class, // Other client factories... ]; /** * This iterator change array<class-string<ClientFactoryContract>> to array<ClientFactoryContract> */ $toService = new FactoryToServiceIterator($container, $clients); $clientFactory = new ClientsFactory($client); $client = $clientFactory->create($toService); // Alternatively, you can use second parameter of constructor: $clientFactory = new ClientsFactory($client, $toService); $client = $clientFactory->create();
以下示例演示了如何使用提供的 HTTP 客户端类和 ClientsFactory 在 PHP 应用程序中有效地管理 HTTP 请求和响应。
ConfigManager
ConfigManager 旨在为每个主机(IP、域名)设置不同的配置。每个 HTTP 客户端都可以在其命名空间中包含 Config
类。
设置默认配置
use StrictPhp\HttpClients\Managers\ConfigManager; use StrictPhp\HttpClients\Clients\Sleep; // set up for SleepClient $config = new Sleep\SleepConfig(1000, 2000); /** @var ConfigManager $configManager */ $configManager->addDefault($config);
设置给定域的覆盖配置
use StrictPhp\HttpClients\Managers\ConfigManager; use StrictPhp\HttpClients\Clients\Sleep; // set up for SleepClient $config = new Sleep\SleepConfig(1000, 2000); /** @var ConfigManager $configManager */ $configManager->add('strictphp.com', $config);
您应将 DI 容器设置为提供 ConfigManager 作为单例。
客户端
- 每个客户端都可以使用其自己的 Factory 类(在其命名空间中)构建。Factory 使用一个 DI 容器,该容器应解析:用于 HTTP/s 通信的 ClientInterface 和 ConfigManaer
- 每个客户端都可以由 ConfigManager 进行配置。
CacheResponseClient (文件)
CacheResponseClient 利用 PSR-6(simple-cache)进行响应缓存,通过为后续请求提供缓存响应来提高开发速度。以下是优点和考虑因素:
- 开发效率:通过缓存响应加快开发速度,减少在开发期间重复 API 调用的需要。
- 本地测试:在生产环境中启用
saveOnly
选项以缓存响应并下载到本地主机进行测试,确保一致性和性能。 - 定制:通过在 CacheKeyMakerAction.php 中实现自己的合同来自定义缓存键的制备。
自定义响应客户端 (文件)
内容可能有所更改。
您可以定义自定义响应文件。
构造函数中的第1个参数可以是
- 由 SerializableResponse 创建的序列化路径,该文件扩展名为
shttp
,表示序列化 http
- 纯文本文件的路径,这仅用于正文
您需要设置容器依赖项以添加所需的内容。
自定义请求客户端 (文件)
在将请求发送到HTTPClient之前修改请求。您可以抛出ClientExceptionInterface。此客户端可用于测试应用程序中的错误处理机制并使用缓存的*.shttp文件。
use Psr\Http\Message\RequestInterface; use StrictPhp\HttpClients\Clients\CustomizeRequest\CustomizeRequestConfig; use StrictPhp\HttpClients\Managers\ConfigManager; /** @var ConfigManager $configManager */ $configManager->add('www.example.com', new CustomizeRequestConfig(function(RequestInterface $request): RequestInterface { return $request->withHeader('uuid', generate_uuid()); }));
事件客户端 (文件)
依赖于PSR-14(事件分发器)
您可以在请求之前、失败或请求成功时附加事件。这对于日志记录非常有用。
- 为PHPStorm保存HTTP文件 SaveForPhpstormRequest.php
- 保存响应 SaveResponse.php
重试客户端 (文件)
重试客户端旨在通过定义尝试次数和允许列表(基于异常)来重试失败的请求。
睡眠客户端 (文件)
SleepClient 允许您在请求之间引入等待间隔,这对于与需要速率限制的外部API交互可能是必要的。
存储客户端 (文件)
StoreClient 保存请求和响应,不依赖于 PSR-14
- 为PHPStorm保存HTTP文件 SaveForPhpstormRequest.php
- 保存响应 SaveResponse.php
编写自己的客户端
您可以通过实现这些接口简单地编写自己的客户端
- 客户端必须实现
Psr\Http\Client\ClientInterface
。 - 配置必须实现
StrictPhp\HttpClients\Contracts\ConfigInteface
- 客户端工厂实现
StrictPhp\HttpClients\Contracts\ClientFactoryContract
以下是一个实现示例
测试
您可以通过 SaveResponse 保存扩展名为 *.shttp 的文件或使用我们的 PSR16 实现 CachePsr16Service。您可以通过 CustomResponseClient 在测试中使用此文件。
use StrictPhp\HttpClients\Clients\CustomResponse\CustomResponseClient; /** @var \Psr\Http\Message\RequestInterface $request */ $client = new CustomResponseClient(__DIR__ . '/dir/filename.shttp'); $response = $client->sendRequest($request); $response instanceof \Psr\Http\Message\ResponseInterface;
配置
namespace My; use StrictPhp\HttpClients\Contracts\ConfigInterface; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; use StrictPhp\HttpClients\Entities\AbstractConfig; /** * parameters of constructor must have to filled default values */ class Config extends AbstractConfig { public function __construct( private readonly int $optionA = 1, private readonly int int $optionB = 2, ) { } public function initFromDefaultConfig(ConfigInterface $object): void { // if you want to pass an object reference from the default configuration /** @see \StrictPhp\HttpClients\Clients\CacheResponse\CacheResponseConfig */ // or empty /** @see \StrictPhp\HttpClients\Clients\Sleep\SleepConfig */ } }
客户端
namespace My; use Psr\Http\Client\ClientInterface; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; use StrictPhp\HttpClients\Managers\ConfigManager; use My\Config; class MyClient implements ClientInterface { public function __construct( private ClientInterface $client, private ConfigManager $configManager, ) { } public function sendRequest(RequestInterface $request): ResponseInterface { $host = $request->getUri()->getHost(); $config = $this->configManager->get(Config::class, $host); $config->optionA; $config->optionB; // do anything $response = $this->client->sendRequest($request) // do anything return $response; } }
客户端工厂
namespace My; use StrictPhp\HttpClients\Contracts\ClientFactoryContract; use Psr\Http\Client\ClientInterface; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; use My\Config; class ClientFactory implements ClientFactoryContract { public function __construct( private ConfigManager $configManager, ) { } public function create(ClientInterface $client): ClientInterface { return new MyClient($client, $this->configManager); } }