【问题标题】:How do I configure default query parameters with Guzzle 6?如何使用 Guzzle 6 配置默认查询参数?
【发布时间】:2016-12-09 21:33:42
【问题描述】:

从 5 迁移到 6,我遇到了障碍,找不到相关文档。

Guzzle 文档在这里,http://guzzle.readthedocs.io/en/latest/quickstart.html#creating-a-client,我们可以添加“任意数量的默认请求选项”的站点。

我想在每个请求中发送“foo=bar”。例如:

$client = new Client([
    'base_uri' => 'http://google.com',
]);

$client->get('this/that.json', [
    'query' => [ 'a' => 'b' ],
]);

这将在 http://google.com/this/that.json?a=b 上生成 GET

如何修改客户端构造以使其产生:

http://google.com/this/that.json?foo=bar&a=b

感谢您的帮助!

【问题讨论】:

标签: php guzzle guzzle6


【解决方案1】:

我找到了一个不错的解决方案here

基本上,在第一个参数数组中定义的任何内容都会成为客户端 config 的一部分。

这意味着你可以在初始化时这样做:

$client = new Client([
    'base_uri' => 'http://google.com',
    // can be called anything but defaults works well
    'defaults' => [
        'query'  => [
            'foo' => 'bar',
        ]
    ]
]);

那么,在使用客户端时:

$options = [
    'query'  => [
        'nonDefault' => 'baz',
    ]
];

// merge non default options with default ones
$options = array_merge_recursive($options, $client->getConfig('defaults'));

$guzzleResponse = $client->get('this/that.json', $options);

值得注意的是array_merge_recursive 函数附加到嵌套数组而不是覆盖。如果您计划更改默认值,您将需要不同的实用程序函数。但是,当默认值不可变时,它可以很好地工作。

【讨论】:

  • 这看起来不太好。使用 Saeven 给出的中间方法,您必须一次(在中间件中)配置所有这些东西,而不是在每个请求之前(如在您的代码中)
  • 但是,如果您在应用程序的不同部分使用多个 Guzzle 请求,则必须记住在每次调用时都添加一行。使用中间件配置它可以更好地抽象这个恕我直言
  • 谢谢@NicoHaase,这是一个有效的观点。我实际上创建了静态类来访问我的客户,所以这个功能是隐式而不是显式地发生的,我什至不需要每个请求额外的一行(我只是提取了代码以使其更清楚正在发生的事情)。我认为无论如何你都需要对 Seaven 提供的答案做类似的事情。他们还要求提供一个看起来不那么险恶的解决方案,我认为是这样。
  • 同样的@NicoHaase,我的静态类就是这样做的(严格来说不是工厂模式,但非常相似),我总是对 Guzzle 客户端这样做。就个人而言,我一直觉得 guzzle 中间件文档对于如此庞大的功能有些缺乏。问题是,当我偶然发现这个问题时,我想做的只是将key=val 添加到来自一个特定 guzzle 客户端的所有请求的 URL 中。我觉得花时间浏览各种文档来源是不合理的。任何更复杂的事情,Saeven 的解决方案肯定会是这种方式
  • +1000 for DOCUMENTING $client->getConfig(param_passed_to_constructor);我在任何地方都找不到客户端创建后如何检索默认配置
【解决方案2】:

github 中提出的解决方案看起来很丑。这看起来并没有好多少,但至少更具可读性并且也有效。如果有人知道为什么不应该使用,我想要反馈:

$query = $uri . '/person/id?personid=' . $personid . '&name=' . $name;    
return $result = $this->client->get(
  $query
  )
  ->getBody()->getContents();

【讨论】:

  • 我找到了一些解决方法,如果您碰巧仍然感兴趣,请参阅我给出的答案。
  • 为什么不在选项数组中使用query 部分?给定的代码看起来不太好,并且没有对参数使用任何转义
【解决方案3】:

好的,到目前为止,这在这里有效:

        $extraParams = [
            'a' => $config['a'],
            'b' => $config['b'],
        ];

        $handler = HandlerStack::create();
        $handler->push(Middleware::mapRequest(function (RequestInterface $request) use ($extraParams) {

            $uri  = $request->getUri();
            $uri .= ( $uri ? '&' : '' );
            $uri .= http_build_query( $extraParams );

            return new Request(
                $request->getMethod(),
                $uri,
                $request->getHeaders(),
                $request->getBody(),
                $request->getProtocolVersion()
            );
        }));

        $this->client = new Client([
            'base_uri' => $url,
            'handler' => $handler,
            'exceptions' => false,
        ]);

如果有人知道如何让它看起来不那么险恶,我会说谢谢!

【讨论】:

  • 我找到了一些解决方法,如果您碰巧仍然感兴趣,请参阅我给出的答案。
  • 另一种方式修改查询 $queryString = $request->getUri()->getQuery(); $queryParts = \GuzzleHttp\Psr7\parse_query($queryString); $queryParts[$this->name] = $this->value; $queryString = \GuzzleHttp\Psr7\build_query($queryParts); return $request->withUri($request->getUri()->withQuery($queryString));
猜你喜欢
  • 1970-01-01
  • 2018-06-21
  • 1970-01-01
  • 1970-01-01
  • 2016-01-20
  • 1970-01-01
  • 2019-12-05
  • 2023-04-02
  • 2013-07-19
相关资源
最近更新 更多