Эта страница содержит краткое введение в 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/barhttp://foo.com/barhttp://foo.com/foo/barhttp://foo.com/barhttp://foo.com/foobarhttp://foo.com/barhttp://foo.com/foo/barhttp://foo.com/foo/barhttp://foo.comhttp://baz.comhttp://baz.comhttp://foo.com/?barbarhttp://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
Свежие комментарии