Эта страница содержит краткое введение в Guzzle и вводные примеры. Если вы еще не установили его, рекомендую обратиться к странице Установка Guzzle.
- Как делать запросы
- Создание клиента
- Отправка запросов
- Асинхронные запросы
- Параллельные запросы
- Использование ответов
- Параметры строки запроса
- Загрузка данных
- POST/Form запросы
- Отправка полей формы
- Отправка файлов форм
- Cookies
- Редиректы (перенаправления)
- Исключения при обработке ошибок
- Переменные окружения
- Соответствующие настройки php.ini
Как делать запросы
Можно делать запросы в Guzzle, используя объект GuzzleHttp\ClientInterface
:
Создание клиента
use GuzzleHttp\Client; $client = new Client([ // Базовый URI используется с относительными запросами 'base_uri' => 'http://httpbin.org', // Можно установить любое количество параметров запроса по умолчанию. 'timeout' => 2.0, ]);
Клиенты являются неизменными в Guzzle 6, что означает, что вы не можете изменить значения по умолчанию, используемые клиентом после его создания.
Конструктор клиента принимает ассоциативный массив опций:
- base_uri
- (string|UriInterface) Базовый URI клиента, который объединен в относительные URI. Может быть строкой или экземпляром UriInterface. Когда клиенту предоставляется относительный URI, клиент объединяет базовый URI с относительным URI, используя правила, описанные в RFC 3986, section 2.
// Создать клиента с базовым URI $client = new GuzzleHttp\Client(['base_uri' => 'https://foo.com/api/']); // Отправить запрос на https://foo.com/api/test $response = $client->request('GET', 'test'); // Отправить запрос на https://foo.com/root $response = $client->request('GET', '/root');
Не хочется читать RFC 3986? Вот несколько быстрых примеров того, как base_uri разрешается с другим URI:
base_uri URI Результат http://foo.com
/bar
http://foo.com/bar
http://foo.com/foo
/bar
http://foo.com/bar
http://foo.com/foo
bar
http://foo.com/bar
http://foo.com/foo/
bar
http://foo.com/foo/bar
http://foo.com
http://baz.com
http://baz.com
http://foo.com/?bar
bar
http://foo.com/bar
- handler
- (callable) Функция, которая передает HTTP-запросы по сети. Функция вызывается с
Psr7\Http\Message\RequestInterface
и массив опций передачи, и должен возвращатьGuzzleHttp\Promise\PromiseInterface
который выполняется сPsr7\Http\Message\ResponseInterface
в случае успеха.handler
это опция только для конструктора, которая не может быть переопределена в параметрахper/request
. - …
- (mixed) Все остальные параметры, передаваемые конструктору, используются в качестве параметров запроса по умолчанию для каждого запроса, создаваемого клиентом.
Отправка запросов
Магические методы на клиенте позволяют легко отправлять синхронные запросы:
$response = $client->get('http://httpbin.org/get'); $response = $client->delete('http://httpbin.org/delete'); $response = $client->head('http://httpbin.org/get'); $response = $client->options('http://httpbin.org/get'); $response = $client->patch('http://httpbin.org/patch'); $response = $client->post('http://httpbin.org/post'); $response = $client->put('http://httpbin.org/put');
Вы можете создать запрос и затем отправить запрос клиенту, когда будете готовы:
use GuzzleHttp\Psr7\Request; $request = new Request('PUT', 'http://httpbin.org/put'); $response = $client->send($request, ['timeout' => 2]);
Клиентские объекты обеспечивают большую гибкость в том, как передаются запросы, включая параметры запроса по умолчанию, промежуточное программное обеспечение стека обработчиков по умолчанию, которое используется каждым запросом, и базовый URI, который позволяет отправлять запросы с относительными URI.
Вы можете узнать больше о клиентском промежуточном программном обеспечении на странице Обработчики и связующее ПО документации.
Асинхронные запросы
Вы можете отправлять асинхронные запросы, используя магические методы, предоставляемые клиентом:
$promise = $client->getAsync('http://httpbin.org/get'); $promise = $client->deleteAsync('http://httpbin.org/delete'); $promise = $client->headAsync('http://httpbin.org/get'); $promise = $client->optionsAsync('http://httpbin.org/get'); $promise = $client->patchAsync('http://httpbin.org/patch'); $promise = $client->postAsync('http://httpbin.org/post'); $promise = $client->putAsync('http://httpbin.org/put');
Вы также можете использовать методы sendAsync()
и requestAsync()
клиента:
// Создать объект запроса PSR-7 для отправки $headers = ['X-Foo' => 'Bar']; $body = 'Hello!'; $request = new Request('HEAD', 'http://httpbin.org/head', $headers, $body); $promise = $client->sendAsync($request); // Или, если вам не нужно передавать экземпляр запроса: $promise = $client->requestAsync('GET', 'http://httpbin.org/get');
$promise
, возвращаемые этими методами, реализуют Promises/A+ spec, предоставленные библиотекой Guzzle promises. Это означает, что вы сможете связать цепочкой then()
вызовы promise
. Эти then
затем реализуют либо успешный результат с помощью Psr\Http\Message\ResponseInterface
, либо запрос отклоняется с выбросом исключения exception
:
use Psr\Http\Message\ResponseInterface; use GuzzleHttp\Exception\RequestException; $promise = $client->requestAsync('GET', 'http://httpbin.org/get'); $promise->then( function (ResponseInterface $res) { echo $res->getStatusCode() . "\n"; }, function (RequestException $e) { echo $e->getMessage() . "\n"; echo $e->getRequest()->getMethod(); } );
Параллельные запросы
Вы можете отправлять несколько запросов одновременно, используя Promise и асинхронные запросы:
use GuzzleHttp\Client; use GuzzleHttp\Promise; $client = new Client(['base_uri' => 'http://httpbin.org/']); // Инициируем каждый запрос, но не блокируем $promises = [ 'image' => $client->getAsync('/image'), 'png' => $client->getAsync('/image/png'), 'jpeg' => $client->getAsync('/image/jpeg'), 'webp' => $client->getAsync('/image/webp') ]; // Дождаться завершения всех запросов. Выдает исключение ConnectException // если какой-либо из запросов не выполнен $results = Promise\unwrap($promises); // Дождемся завершения запросов, даже если некоторые из них завершатся неудачно $results = Promise\settle($promises)->wait(); // Можно получить доступ к каждому результату, используя key, предоставленный для функции развертки echo $results['image']['value']->getHeader('Content-Length')[0]; echo $results['png']['value']->getHeader('Content-Length')[0];
Можно использовать GuzzleHttp\Pool
объект, когда у вас есть неопределенное количество запросов, которые вы хотите отправить:
use GuzzleHttp\Pool; use GuzzleHttp\Client; use GuzzleHttp\Psr7\Request; $client = new Client(); $requests = function ($total) { $uri = 'http://127.0.0.1:8126/guzzle-server/perf'; for ($i = 0; $i < $total; $i++) { yield new Request('GET', $uri); } }; $pool = new Pool($client, $requests(100), [ 'concurrency' => 5, 'fulfilled' => function ($response, $index) { // Тут обработка успешного запроса }, 'rejected' => function ($reason, $index) { // Тут обработка запроса, который завершился неудачей }, ]); // Инициализируем трансферы и создаём promise $promise = $pool->promise(); // Ожидаем ответ promise // Принудительно завершаем пул запросов $promise->wait();
Или используя замыкание, которое вернет promise, как только пул вызовет замыкание:
$client = new Client(); $requests = function ($total) use ($client) { $uri = 'http://127.0.0.1:8126/guzzle-server/perf'; for ($i = 0; $i < $total; $i++) { yield function() use ($client, $uri) { return $client->getAsync($uri); }; } }; $pool = new Pool($client, $requests(100));
Использование ответов
В предыдущих примерах мы получили $response
или мы получили ответ от promise. Объект ответа реализует ответ PSR-7, Psr\Http\Message\ResponseInterface
, и содержит много полезной информации.
Вы можете получить код состояния и фразу ответа:
$code = $response->getStatusCode(); // 200 $reason = $response->getReasonPhrase(); // OK
Вы можете извлечь заголовки из ответа:
// Проверка, есть ли заголовок if ($response->hasHeader('Content-Length')) { echo "It exists"; } // Получаем заголовок из ответа echo $response->getHeader('Content-Length')[0]; // Получаем все заголовки ответа foreach ($response->getHeaders() as $name => $values) { echo $name . ': ' . implode(', ', $values) . "\r\n"; }
Тело ответа может быть получено с помощью метода getBody
. Тело ответа может быть использовано как строка, приведено к строке или как объект, подобный потоку:
$body = $response->getBody(); // Неявно приводим тело ответа к строке и отображаем его echo $body; // Явное приведение тела к строке $stringBody = (string) $body; // Читаем первые 10 байт тела ответа $tenBytes = $body->read(10); // Прочитать оставшееся содержимое тела ответа как строку $remainingBytes = $body->getContents();
Параметры строки запроса
Вы можете предоставить параметры строки запроса несколькими способами.
Можно установить параметры строки запроса в URI запроса:
$response = $client->request('GET', 'http://httpbin.org?foo=bar');
Можно указать параметры строки запроса, используя query
как массив:
$client->request('GET', 'http://httpbin.org', [ 'query' => ['foo' => 'bar'] ]);
Предоставление опции в качестве массива будет использовать нативную функцию PHP
http_build_query
для форматирования строки с параметрами.
И, наконец, можно предоставить query
в роли строки:
$client->request('GET', 'http://httpbin.org', ['query' => 'foo=bar']);
Загрузка данных
Guzzle предоставляет несколько способов загрузки данных.
Можно отправлять запросы, содержащие поток данных, передавая строку, ресурс возвращается из fopen
, или как экземпляр Psr\Http\Message\StreamInterface
в опцию запроса body
:
// Предоставляем тело запроса в виде строки $r = $client->request('POST', 'http://httpbin.org/post', [ 'body' => 'raw data' ]); // Предоставляем fopen ресурс $body = fopen('/path/to/file', 'r'); $r = $client->request('POST', 'http://httpbin.org/post', ['body' => $body]); // Используем функцию stream_for() для создания потока PSR-7 $body = \GuzzleHttp\Psr7\stream_for('hello!'); $r = $client->request('POST', 'http://httpbin.org/post', ['body' => $body]);
Простой способ загрузить данные JSON и установить соответствующий заголовок — использовать опцию запроса json
:
$r = $client->request('PUT', 'http://httpbin.org/put', [ 'json' => ['foo' => 'bar'] ]);
POST/Form запросы
В дополнение к указанию необработанных данных запроса с использованием опции запросаbody
, Guzzle предоставляет полезные абстракции при отправке данных POST.
Отправка полей формы
Для отправки POST-запросов application/x-www-form-urlencoded
необходимо указать поля POST в виде массива в параметрах запроса form_params
:
$response = $client->request('POST', 'http://httpbin.org/post', [ 'form_params' => [ 'field_name' => 'abc', 'other_field' => '123', 'nested_field' => [ 'nested' => 'hello' ] ] ]);
Отправка файлов форм
Можно отправлять файлы вместе с формой (POST-запросы multipart/form-data
), используя опцию запроса multipart
. Она принимает массив ассоциативных массивов, где каждый ассоциативный массив содержит следующие ключи:
- name: (required, string) имя ключа поля формы.
- contents: (required, mixed) Укажите тут строку для отправки содержимого файла в виде строки, предоставьте ресурс
fopen
для потоковой передачи содержимого из потока PHP или укажитеPsr\Http\Message\StreamInterface
для потоковой передачи содержимого из потока PSR-7.
$response = $client->request('POST', 'http://httpbin.org/post', [ 'multipart' => [ [ 'name' => 'field_name', 'contents' => 'abc' ], [ 'name' => 'file_name', 'contents' => fopen('/path/to/file', 'r') ], [ 'name' => 'other_file', 'contents' => 'hello', 'filename' => 'filename.txt', 'headers' => [ 'X-Foo' => 'this is an extra header to include' ] ] ] ]);
Cookies
Guzzle может поддерживать для вас сеанс файлов cookie, если это указано с помощью параметра запроса файлов cookie
. При отправке запроса параметр cookie должен быть установлен на экземпляр GuzzleHttp\Cookie\CookieJarInterface
:
// Использование конкретного cookie jar $jar = new \GuzzleHttp\Cookie\CookieJar; $r = $client->request('GET', 'http://httpbin.org/cookies', [ 'cookies' => $jar ]);
Можно установить для cookie
значение true
в конструкторе клиента, если хотите использовать общий файл cookie для всех запросов:
// Используем общий клиентский файл cookie $client = new \GuzzleHttp\Client(['cookies' => true]); $r = $client->request('GET', 'http://httpbin.org/cookies');
Редиректы (перенаправления)
Guzzle будет автоматически следовать за редиректами, только если чётко не указать этого не делать. Вы можете настроить поведение перенаправления, используя опцию запроса allow_redirects
:
- Установите значение
true
, чтобы включить нормальные перенаправления с максимальным количеством 5 перенаправлений. Это значение по умолчанию. - Установите в
false
, чтобы отключить перенаправления. - Передайте ассоциативный массив, содержащий ключ
max
, чтобы указать максимальное количество перенаправлений, и при необходимости укажите значение ключаstrict
, чтобы указать, следует ли использовать строгие перенаправления, совместимые с RFC (что означает запросы перенаправления POST со следующими запросами тоже типа POST, тогда как в обычном режиме большинство браузеров по умолчанию перенаправляют запросы POST со следующими запросами GET).
$response = $client->request('GET', 'http://github.com'); echo $response->getStatusCode(); // 200
В следующем примере показано, как можно отключить редиректы:
$response = $client->request('GET', 'http://github.com', [ 'allow_redirects' => false ]); echo $response->getStatusCode(); // 301
Исключения при обработке ошибок
Guzzle генерирует исключения для ошибок, возникающих во время передачи:
- В случае сетевой ошибки (тайм-аут соединения, ошибки DNS и т.д.) выдается сообщение
GuzzleHttp\Exception\RequestException
. Это исключение распространяется наGuzzleHttp\Exception\TransferException
. Поймав это исключение, вы поймете любое исключение, которое может быть сгенерировано при передаче запросов. Пример:use GuzzleHttp\Psr7; use GuzzleHttp\Exception\RequestException; try { $client->request('GET', 'https://github.com/_abc_123_404'); } catch (RequestException $e) { echo Psr7\str($e->getRequest()); if ($e->hasResponse()) { echo Psr7\str($e->getResponse()); } }
- Исключение
GuzzleHttp\Exception\ConnectException
выдается в случае сетевой ошибки. Это исключение происходит отGuzzleHttp\Exception\RequestException
. GuzzleHttp\Exception\ClientException
выбрасывается для ошибок уровня 400, если для параметра запросаhttp_errors
установлено значениеtrue
. Это исключение распространяется наGuzzleHttp\Exception\BadResponseException
иGuzzleHttp\Exception\BadResponseException
распространяется наGuzzleHttp\Exception\RequestException
. Пример:use GuzzleHttp\Exception\ClientException; try { $client->request('GET', 'https://github.com/_abc_123_404'); } catch (ClientException $e) { echo Psr7\str($e->getRequest()); echo Psr7\str($e->getResponse()); }
GuzzleHttp\Exception\ServerException
генерируется для ошибок уровня 500, если для параметра запроса http_errors установлено значение true. Это исключение происходит отGuzzleHttp\Exception\BadResponseException
.GuzzleHttp\Exception\TooManyRedirectsException
генерируется, когда выполняется слишком много перенаправлений. Это исключение происходит отGuzzleHttp\Exception\RequestException
.
Все вышеперечисленные исключения происходят из GuzzleHttp\Exception\TransferException
.
Переменные окружения
Guzzle предоставляет несколько переменных среды, которые можно использовать для настройки поведения библиотеки:
- GUZZLE_CURL_SELECT_TIMEOUT
- Управляет продолжительностью в секундах, которую обработчик
curl_multi_*
будет использовать при выборе обработчика curl, используяcurl_multi_select()
. Некоторые системы имеют проблемы с реализацией PHPcurl_multi_select()
, где вызов этой функции всегда приводит к ожиданию максимальной продолжительности времени ожидания. - HTTP_PROXY
- Определяет прокси для использования при отправке запросов по протоколу http.
Поскольку переменная
HTTP_PROXY
может содержать произвольный пользовательский ввод в некоторых (CGI) средах, эта переменная используется только в CLI SAPI. Смотрите https://httpoxy.org для получения дополнительной информации. - HTTPS_PROXY
- Определяет прокси для использования при отправке запросов по протоколу https.
Соответствующие настройки php.ini
Guzzle может использовать настройки php.ini
при настройке клиентов:
- openssl.cafile
- Указывает путь на диске к файлу CA (сертификат SSL/TLS безопасности) в формате PEM, который будет использоваться при отправке запросов через «https». Подробнее: https://wiki.php.net/rfc/tls-peer-verification#phpini_defaults
Смотрите далее: Опции запросов Guzzle | Ранее: Обзор и установка Guzzle | Главная по Guzzle
Свежие комментарии