proklung / symfony-guzzle-bundle
Symfony 的 Guzzle 工作包。
Requires
- php: >=7.1 || ^8.0
- ext-dom: *
- ext-json: *
- doctrine/cache: ^1
- guzzlehttp/guzzle: ~6|~7
- psr/cache: ^1.0
- psr/simple-cache: ^1.0
- symfony/config: ^4.4 || ^5.0
- symfony/dependency-injection: ^4.4 || ^5.0
- symfony/filesystem: ^4.4 || ^5.0
- symfony/http-kernel: ^4.4 || ^5.0
- twig/twig: ~2 | ~3
Requires (Dev)
- icanhazstring/composer-unused: ^0.7.5
- proklung/phpunit-testing-tools: ^1.4.0
README
该包是基于CsaGuzzleBundle进行改进的,以满足个人需求(例如,添加了适用于Bitrix的缓存适配器等)。
安装
composer require proklung/symfony-guzzle-bundle
使用
配置
您也可以启用内置的记录器,以记录输出请求
csa_guzzle: logger: true
自动装配
如果您依赖于 Symfony 的自动装配,可以选择将特定的服务别名指定为 GuzzleHttp\ClientInterface
接口和 GuzzlHttp\Client
类。
csa_guzzle: profiler: '%kernel.debug%' logger: true clients: github_api: config: base_uri: 'https://api.github.com' headers: Accept: application/vnd.github.v3+json jsonplaceholder: config: base_uri: 'https://jsonplaceholder.typicode.com' headers: Accept: application/json default_client: github_api
然后,github_api 客户端将自动注入到您的控制器或服务中
<?php namespace App\Controller; use Twig\Environment; use Symfony\Component\HttpFoundation\Response; use GuzzleHttp\Client; class DefaultController { private $twig; private $client; public function __construct(Environment $twig, Client $client) { $this->twig = $twig; $this->client = $client; } public function index() { $this->client->get('/users'); return new Response($this->twig->render("base.html.twig"), 200, ['Content-Type' => 'text/html']); } }
创建客户端服务
创建客户端服务有两种方法
- 使用语义配置(入门级)
- 注册自己的服务(高级用户)
使用语义配置创建客户端
只需编写以下代码
csa_guzzle: clients: github_api: config: # you can specify the options as in http://docs.guzzlephp.org/en/latest/quickstart.html#creating-a-client base_uri: https://api.github.com timeout: 2.0 headers: Accept: application/vnd.github.v3+json
前面的代码将创建一个新的服务,称为 csa_guzzle.client.github_api
,您可以在控制器中使用它,或者将其注入到另一个服务中
<?php use Symfony\Bundle\FrameworkBundle\Controller\Controller; class MyController extends Controller { public function indexAction() { $client = $this->get('csa_guzzle.client.github_api'); // ... } }
您可能希望将该服务标记为 延迟加载。
csa_guzzle: clients: my_client: lazy: true # ...
如果您覆盖了客户端的类,您也可以设置客户端的类
csa_guzzle: clients: my_client: class: AppBundle\Client # ...
当然,您需要确保客户端类的构造函数与 Guzzle 的 Client 类的签名完全相同。
注册自己的服务
为了使客户端支持该包,只需将其标记为这样
YAML
acme.client: class: %acme.client.class% arguments: [{ base_uri: http://acme.com, timeout: 2.0} ]
创建新的中间件
创建一个新的 Guzzle 中间件就像创建一个 symfony 服务并使用 csa_guzzle.middleware
标签一样,给它一个别名,并(可选地)一个优先级
<service id="acme.middleware" class="Closure"> <factory class="My\Middleware" method="my_middleware" /> <tag name="csa_guzzle.middleware" alias="my_middleware" priority="100" /> </service>
您还可以定义具有 __invoke
方法的类作为中间件,如下所示
class Middleware { public function __invoke(callable $handler): callable { return function (RequestInterface $request, array $options) use ($handler) { $request = $request->withHeader('X-Test', 'I was here'); return $handler($request, $options); }; } }
此类服务的定义是
My\Middleware: tags: - { name: csa_guzzle.middleware, alias: my_middleware, priority: 100 }
如果使用语义配置,中间件将自动用于所有客户端。但是,如果您愿意,您可以限制客户端使用特定的中间件列表
csa_guzzle: # ... clients: # Prototype github_api: config: base_uri: https://api.github.com headers: Accept: application/vnd.github.v3+json middleware: ['debug', 'my_middleware'] # Note the use of the alias defined earlier in the service definition.
您还可以禁用特定的中间件,通过在中间件名称前加上一个 !
字符
csa_guzzle: # ... clients: github_api: # ... middleware: ['!my_middleware']
您可以选择性地列出中间件,或者黑名单中间件。同时使用白名单和黑名单将触发异常。
当使用该包注册自己的客户端时,您可以明确列出所有启用的中间件。 middleware
属性接受以空格分隔的中件间名称列表。在这种情况下,只有指定的中间件将为该客户端注册
YAML
acme.client: class: %acme.client.class% tags: - { name: csa_guzzle.client, middleware: 'my_middleware another_middleware'}
BitrixCacheAdapter
定义缓存服务。例如,如下所示
bitrix.psr.cacher: class: WebArch\BitrixCache\AntiStampedeCacheAdapter arguments: ['/', 3600, 'cache/s1/psr-cache'] bitrix.psr.cacher.adapter: class: Local\Bundles\GuzzleBundle\Middlewares\Cache\Adapter\PsrAdapter arguments: ['@bitrix.psr.cacher', 3600]
然后在包的配置中指定
cache: enabled: true adapter: bitrix.psr.cacher.adapter
可用的中间件
目前,有五种中间件可用
- the
logger
中间件 - the
cache
中间件 - the
mock
中间件
The logger
中间件
The logger
中间件的目标是提供一个简单的工具来记录 Guzzle 请求。
启用请求记录,您只需在 Symfony 的配置中启用它
csa_guzzle: logger: enabled: true
类似于 debug
中间件,也存在简写语法来启用它
csa_guzzle: logger: true
使用高级配置,您还可以配置自己的记录器,只要它实现了 PSR-3 LoggerInterface
csa_guzzle: logger: enabled: true service: my_logger_service
您可以使用在guzzlehttp/guzzle的文档中描述的语法来配置日志格式。您还可以使用格式化程序中描述的三个级别:clf
(Apache日志格式)、debug
或short
csa_guzzle: logger: enabled: true format: debug
您还可以更改日志级别,对于dev
,您可能想要debug
,对于prod
,您可能想要error
。您可以在php-fig的LogLevel中找到更多日志级别。
csa_guzzle: logger: enabled: true level: debug
cache
中间件
cache
中间件的目标是提供一个非常简单的缓存,以便缓存Guzzle响应。
尽管只提供了一个doctrine/cache适配器(Prokl\GuzzleBundle\GuzzleHttp\Cache\DoctrineAdapter
),但中间件是无状态的。如果您想在cache
中间件中使用自己的缓存实现,您只需实现Prokl\GuzzleBundle\GuzzleHttp\Cache\StorageAdapterInterface
即可!
此中间件可以使用以下配置进行配置
csa_guzzle: cache: enabled: true adapter: my_storage_adapter
要使用doctrine缓存适配器,您需要使用Prokl\GuzzleBundle\GuzzleHttp\Cache\DoctrineAdapter
类,您应该在其中注入您的doctrine缓存服务。例如,使用doctrine/cache的FilesystemCache
<services> <service id="my_storage_adapter" class="Prokl\GuzzleBundle\GuzzleHttp\Cache\DoctrineAdapter"> <argument type="service" id="my_cache_service" /> </service> <service id="my_cache_service" class="Doctrine\Common\Cache\FilesystemCache"> <argument>%kernel.cache_dir%/my_cache_folder</argument> </service> </services>
mock
中间件
当运行测试时,您通常想禁用对您的(或外部的)API的真实HTTP请求。mock
中间件可以记录这些请求以便在测试中回放。
mock
中间件可以在两种模式下工作
- record,它将您的HTTP请求保存到您的文件系统中的一个目录中
- replay,它使用同一目录中保存的您的HTTP请求
当然,此中间件仅在test
环境(或dev
,如果您无法访问远程服务器)中使用
# config_test.yml csa_guzzle: mock: storage_path: "%kernel.root_dir%/../features/fixtures/guzzle" mode: record
生成的文件可以随后提交到版本控制系统(VCS)。
要使用它们,只需将模式更改为replay
# config_test.yml csa_guzzle: mock: storage_path: "%kernel.root_dir%/../features/fixtures/guzzle" mode: replay
可以使用mock
中间件进行一些自定义设置。您确实可以添加黑名单
- 请求头,因此它们不会用于生成mock的文件名。
- 响应头,因此它们不会保存到mock文件中。
为此,您只需按如下方式配置您的客户端
# config_test.yml csa_guzzle: mock: # ... request_headers_blacklist: ['User-Agent', 'Host', 'X-Guzzle-Cache', 'X-Foo'] response_headers_blacklist: ['X-Guzzle-Cache', 'X-Bar']
配置参考
csa_guzzle: profiler: enabled: false # The maximum size of the body which should be stored in the profiler (in bytes) max_body_size: 65536 # Example: 65536 logger: enabled: false service: ~ format: '{hostname} {req_header_User-Agent} - [{date_common_log}] "{method} {target} HTTP/{version}" {code} {res_header_Content-Length}' level: debug default_client: ~ cache: enabled: false adapter: ~ clients: # Prototype name: class: GuzzleHttp\Client lazy: false config: ~ middleware: [] alias: null mock: enabled: false storage_path: ~ # Required mode: replay request_headers_blacklist: [] response_headers_blacklist: []
要记录请求/响应体,您可以在format
设置中使用分别代表请求和响应体的{req_body}
和{res_body}
。
日志变量的完整列表及其描述
参考 Guzzle日志插件文档
其他
- 替代Guzzle Logger - 用于包外使用 -
Prokl\GuzzleBundle\Middlewares\Raw\GuzzleLogger
Prokl\GuzzleBundle\Middlewares\Raw\GuzzleLogger: class: Prokl\GuzzleBundle\Middlewares\Raw\GuzzleLogger arguments: ['@logger', '@custom.guzzle.formatter'] custom.guzzle.formatter: class: GuzzleHttp\MessageFormatter arguments: ['[{date_common_log}] [{request}] "{method} {target} HTTP/{version}" {response}']