我正在使用m6web_guzzle捆绑包注册多个http客户端:

m6web_guzzlehttp:
    clients:
        myclient:
            timeout: 3
            headers:
                "Accept": "application/json"
            delay: 0
            verify: false

我想在它动态生成的服务上调用方法。在这种情况下,生成的服务名称为:
@m6web_guzzlehttp.guzzle.handlerstack.myclient

这是我在服务构造函数中所做的事情:(注入(inject)的第三个参数是'@ m6web_guzzlehttp.guzzle.handlerstack.myclient')
/**
 * @param array        $parameters
 * @param Client       $client
 * @param HandlerStack $handlerStack
 */
public function __construct(array $parameters, Client $client, HandlerStack $handlerStack)
{
    $this->parameters = $parameters;
    $this->client = $client;
    $this->handlerStack->push(Middleware::retry([$this, 'retryDecider']));
}

到目前为止,它运行良好,但是如何在push文件中传输最后一行(services.yml调用)?还是其他更干净的方法来注册此重试处理程序?

最佳答案

因此,前面提到了编译器 channel 。那是一种选择。

使用工厂创建实例

但是您几乎也可以直接在您的服务定义中表达这一点。我几乎说了一下,因为您将需要某种代码,因为Symfony服务定义(AFAIK)无法评估闭包-这是我们对Guzzle中间件所需要的。

我写了这个services.yml作为例子:

m6web_guzzlehttp.guzzle.handlerstack.myclient:
    class: GuzzleHttp\HandlerStack
    factory: ['GuzzleHttp\HandlerStack', create]

retry_decider:
    class: MyBundle\RetryDecider
    factory: ['MyBundle\RetryDecider', createInstance]

retry_handler:
    class: GuzzleHttp\Middleware
    factory: ['GuzzleHttp\Middleware', retry]
    arguments:
        - '@retry_decider'

handlerstack_pushed:
    parent: m6web_guzzlehttp.guzzle.handlerstack.myclient
    calls:
        - [push, ['@retry_handler']]

什么是什么?
  • m6web_guzzlehttp.guzzle.handlerstack.myclient-您的动态服务-由于已经创建了示例,因此将其从示例中删除。
  • retry_decider-您的决定者。我们在createInstance方法中返回一个Closure。您可以根据需要添加更多参数,只需在YML中添加参数即可。
  • retry_handler-在这里,我们使用决定程序
  • 组成中间件
  • handlerstack_pushed-在这里,我们使用动态服务作为父服务,将处理程序push()放入堆栈。

  • 等等-我们拥有动态服务定义的堆栈,但是推送了我们的重试中间件。

    这是我们决策者的来源:
    <?php
    
    namespace MyBundle;
    
    class RetryDecider {
    
        public static function createInstance() {
            return function() {
                // do your deciding here
            };
        }
    
    }
    

    ->现在,您有了服务handlerstack_pushed,它是完整的堆栈。

    配置更多

    请注意,您可以将m6web_guzzlehttp.guzzle.handlerstack.myclient添加到parameters.yml:
    parameters:
        baseHandlerStackService: m6web_guzzlehttp.guzzle.handlerstack.myclient
    

    然后在handlerstack_pushed上使用它:
    handlerstack_pushed:
        parent: "%baseHandlerStackService%"
        calls:
            - [push, ['@retry_handler']]
    

    那样更好;-)

    关于symfony - 调用由包动态创建的服务上的方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46237784/

    10-14 14:00
    查看更多