Как настроить параметры запроса по умолчанию с помощью Guzzle 6?

При переходе с 5 на 6 я столкнулся с проблемой и не могу найти соответствующие документы.

Поглотите документы здесь, 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' ],
]);

Это сгенерирует GET на http://google.com/this/that.json?a=b

Как изменить конструкцию клиента, чтобы она выдавала:

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

Спасибо за вашу помощь!


person Saeven    schedule 04.08.2016    source источник
comment
См.: github.com/guzzle/guzzle/issues/1138.   -  person Ayell    schedule 04.08.2016
comment
Хороший соус. Должна быть книга: Предупреждающие сигналы. Когда вы закончили проектирование своей библиотеки Спасибо, чувак.   -  person Saeven    schedule 04.08.2016


Ответы (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,
        ]);

Если кто-нибудь знает, как сделать его менее зловещим, я бы сказал спасибо!

person Saeven    schedule 04.08.2016
comment
Я нашел обходной путь для этого, если вам все еще интересно, посмотрите ответ, который я дал. - person DazBaldwin; 18.11.2019
comment
Другой способ изменить запрос $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)); - person Vladimir Pak; 13.10.2020

Я нашел хорошее решение здесь.

По сути, все, что определено в первом массиве аргументов, становится частью 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 добавляется к вложенным массивы, а не перезаписывает. Если вы планируете изменить значение по умолчанию, вам понадобится другая служебная функция. Это хорошо работает, когда значения по умолчанию неизменны.

person DazBaldwin    schedule 18.11.2019
comment
Это действительно выглядит не очень хорошо. Используя промежуточный подход, подобный предложенному Saeven, вы должны настроить все это один раз (в промежуточном программном обеспечении), а не перед каждым запросом (как в вашем коде). - person Nico Haase; 18.11.2019
comment
@NicoHaase, я имею в виду, что значения по умолчанию устанавливаются только один раз. Дополнительная одна строка намного читабельнее и декларативнее, чем возиться с HandlerStack, Middleware, RequestInterface и Request объектами и функциями IMO. - person DazBaldwin; 18.11.2019
comment
Но если вы используете несколько запросов Guzzle в разных частях вашего приложения, вы должны не забывать добавлять одну дополнительную строку при каждом вызове. Настройка его с использованием промежуточного программного обеспечения абстрагирует это лучше ИМХО - person Nico Haase; 18.11.2019
comment
Спасибо @NicoHaase, это верное замечание. На самом деле я создаю статические классы для доступа к своим клиентам, поэтому эта функциональность в любом случае выполняется неявно, а не явно, и мне даже не нужна дополнительная строка для каждого запроса (я просто извлек код, чтобы было более понятно, что происходит). Я думаю, вам все равно нужно будет сделать что-то подобное с ответом, предоставленным Сивеном. Они также попросили менее зловещее решение, которое я думаю. - person DazBaldwin; 18.11.2019
comment
Используя ответ Seavens, вы можете создать ClientFactory, который возвращает идеально настроенный клиент (содержащий надлежащее промежуточное программное обеспечение), поэтому вам просто нужно было написать этот код один раз. И я не хотел сказать, что ваше решение плохое, но я бы предпочел промежуточный подход. Спасибо за хорошую дискуссию, Даз :) - person Nico Haase; 18.11.2019
comment
Тот же @NicoHaase, я как бы делаю это со своими статическими классами (не строго заводской шаблон, но очень похожий), я всегда делаю это с клиентами Guzzle. Лично я всегда чувствовал, что в документации промежуточного программного обеспечения жужжания чего-то не хватает для такой масштабной функции. Дело в том, что, когда я наткнулся на этот вопрос, все, что я хотел сделать, это добавить key=val к URL-адресу для всех запросов, сделанных с одного конкретного клиента. Я не считал оправданным тратить время на просмотр различных источников документации. Что-нибудь более сложное, хотя и решение Савена определенно было бы способом - person DazBaldwin; 19.11.2019
comment
+1000 за ДОКУМЕНТИРОВАНИЕ $client-›getConfig(param_passed_to_constructor); Я нигде не мог найти, как можно получить конфигурацию по умолчанию после создания клиента. - person cnlevy; 20.07.2021

решение, предложенное в github, выглядит довольно некрасиво. Это выглядит не намного лучше, но, по крайней мере, более читаемо и также работает. Я хотел бы получить отзыв, если кто-нибудь знает, почему его нельзя использовать:

$query = $uri . '/person/id?personid=' . $personid . '&name=' . $name;    
return $result = $this->client->get(
  $query
  )
  ->getBody()->getContents();
person Alejandro Moreno    schedule 06.11.2018
comment
Я нашел обходной путь для этого, если вам все еще интересно, посмотрите ответ, который я дал. - person DazBaldwin; 18.11.2019
comment
Почему бы не использовать части query в массиве параметров? Данный код выглядит не очень хорошо и не использует экранирование для параметров. - person Nico Haase; 18.11.2019