Быстрый старт

Эта страница содержит краткое введение в Guzzle и ознакомительные примеры. Если вы еще не установили Guzzle, перейдите на Установка страницу.

Создание запроса

Вы можете отправлять запросы с помощью Guzzle, используя объект GuzzleHttp\ClientInterface.

Создание клиента

use GuzzleHttp\Client;

$client = new Client([
    // Base URI is used with relative requests
    'base_uri' => 'http://httpbin.org',
    // You can set any number of default request options.
    'timeout'  => 2.0,
]);

Клиенты неизменяемы в Guzzle, что означает, что вы не можете изменить значения по умолчанию, используемые клиентом после его создания.

Конструктор клиента принимает ассоциативный массив опций:

base_uri

(string|UriInterface) Базовый URI клиента, который объединяется в относительные URI. Может быть строкой или экземпляром UriInterface. Когда относительный URI предоставляется клиенту, клиент объединяет базовый URI с относительным URI, используя правила, описанные в RFC 3986, раздел 5.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 Result
http://foo.com /bar http://foo.com/bar
http://foo.com/foo /bar http://foo.com/bar
http://foo.com/foo бар http://foo.com/bar
http://foo.com/foo/ бар http://foo.com/foo/bar
http://foo.com http://baz.com http://baz.com
http://foo.com/?bar бар http://foo.com/bar
обработчик.
(вызываемая) Функция, передающая HTTP-запросы по проводам. вызывается с Psr7\Http\Message\RequestInterface и массивом опций передачи, и должен возвращать GuzzleHttp\Promise\PromiseInterface, который выполняется с помощью Psr7\Http\Message\ResponseInterface при успехе.
....
(смешанный) Все остальные параметры, переданные в конструктор, используются как параметры по умолчанию опции запроса с каждым запросом, создаваемым клиентом.

Отправка запросов

Магические методы на клиенте упрощают отправку синхронных запросов:

$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.

Вы можете узнать больше о клиентском промежуточном ПО на странице Handlers and Middleware документации.

Async Requests

Вы можете отправлять асинхронные запросы, используя магические методы, предоставляемые клиентом:

$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() клиента:

use GuzzleHttp\Psr7\Request;

// Create a PSR-7 request object to send
$headers = ['X-Foo' => 'Bar'];
$body = 'Hello!';
$request = new Request('HEAD', 'http://httpbin.org/head', $headers, $body);
$promise = $client->sendAsync($request);

// Or, if you don't need to pass in a request instance:
$promise = $client->requestAsync('GET', 'http://httpbin.org/get');

Обещание, возвращаемое этими методами, реализует стандарт Promises/A+ spec, предоставляемый Guzzle promises library. Это означает. что вы можете создавать цепочки then() вызовов от обещания. Эти вызовы then либо выполняются с успешным Psr\Http\Message\ResponseInterface, либо отклоняется с исключением.

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();
    }
);

Одновременные запросы

Вы можете отправлять несколько запросов одновременно, используя обещания и асинхронные запросы.

use GuzzleHttp\Client;
use GuzzleHttp\Promise;

$client = new Client(['base_uri' => 'http://httpbin.org/']);

// Initiate each request but do not block
$promises = [
    'image' => $client->getAsync('/image'),
    'png'   => $client->getAsync('/image/png'),
    'jpeg'  => $client->getAsync('/image/jpeg'),
    'webp'  => $client->getAsync('/image/webp')
];

// Wait for the requests to complete; throws a ConnectException
// if any of the requests fail
$responses = Promise\Utils::unwrap($promises);

// You can access each response using the key of the promise
echo $responses['image']->getHeader('Content-Length')[0];
echo $responses['png']->getHeader('Content-Length')[0];

// Wait for the requests to complete, even if some of them fail
$responses = Promise\Utils::settle($promises)->wait();

// Values returned above are wrapped in an array with 2 keys: "state" (either fulfilled or rejected) and "value" (contains the response)
echo $responses['image']['state']; // returns "fulfilled"
echo $responses['image']['value']->getHeader('Content-Length')[0];
echo $responses['png']['value']->getHeader('Content-Length')[0];

Вы можете использовать объект GuzzleHttp\Pool, когда у вас есть неопределенное количество запросов, которые вы хотите отправить.

use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Pool;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Response;

$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 $response, $index) {
        // this is delivered each successful response
    },
    'rejected' => function (RequestException $reason, $index) {
        // this is delivered each failed request
    },
]);

// Initiate the transfers and create a promise
$promise = $pool->promise();

// Force the pool of requests to complete.
$promise->wait();

Или использовать закрытие, которое вернет обещание, когда пул вызовет закрытие.

$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 или нам был получили ответ из обещания. Объект response реализует PSR-7 ответ, Psr\Http\Message\ResponseInterface, и содержит много полезной информации.

Вы можете получить код состояния и фразу причины ответа:

$code = $response->getStatusCode(); // 200
$reason = $response->getReasonPhrase(); // OK

Вы можете получить заголовки из ответа:

// Check if a header exists.
if ($response->hasHeader('Content-Length')) {
    echo "It exists";
}

// Get a header from the response.
echo $response->getHeader('Content-Length')[0];

// Get all of the response headers.
foreach ($response->getHeaders() as $name => $values) {
    echo $name . ': ' . implode(', ', $values) . "\r\n";
}

Тело ответа можно получить с помощью метода getBody. Тело может быть использовано как строка, приведено к строке или использовано как потокоподобный объект.

$body = $response->getBody();
// Implicitly cast the body to a string and echo it
echo $body;
// Explicitly cast the body to a string
$stringBody = (string) $body;
// Read 10 bytes from the body
$tenBytes = $body->read(10);
// Read the remaining contents of the body as a string
$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 запроса.

use GuzzleHttp\Psr7;

// Provide the body as a string.
$r = $client->request('POST', 'http://httpbin.org/post', [
    'body' => 'raw data'
]);

// Provide an fopen resource.
$body = Psr7\Utils::tryFopen('/path/to/file', 'r');
$r = $client->request('POST', 'http://httpbin.org/post', ['body' => $body]);

// Use the Utils::streamFor method to create a PSR-7 stream.
$body = Psr7\Utils::streamFor('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 Requests

Помимо указания исходных данных запроса с помощью опции запроса body, Guzzle предоставляет полезные абстракции для отправки POST-данных.

Поля формы отправки

Отправка application/x-www-form-urlencoded POST-запросов требует указания POST-полей в виде массива в опциях запроса form_params.

$response = $client->request('POST', 'http://httpbin.org/post', [
    'form_params' => [
        'field_name' => 'abc',
        'other_field' => '123',
        'nested_field' => [
            'nested' => 'hello'
        ]
    ]
]);

Отправка файлов формы

Вы можете отправлять файлы вместе с формой (multipart/form-data POST-запросы), используя опцию multipart запроса. multipart принимает массив из ассоциативных массивов, где каждый ассоциативный массив содержит следующие ключи:

  • name: (required, string) ключ, отображающий имя поля формы.
  • содержимое: (требуется, смешанный) Предоставьте строку для отправки содержимого файла в виде строки, предоставить ресурс fopen для передачи содержимого из потока PHP потока, или Psr\Http\Message\StreamInterface для передачи содержимого из потока PSR-7. содержимого из потока PSR-7.
use GuzzleHttp\Psr7;

$response = $client->request('POST', 'http://httpbin.org/post', [
    'multipart' => [
        [
            'name'     => 'field_name',
            'contents' => 'abc'
        ],
        [
            'name'     => 'file_name',
            'contents' => Psr7\Utils::tryFopen('/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 для вас, если вы проинструктированы с помощью опции cookies опцию запроса. При отправке запроса опция cookies должна быть установлена на экземпляр GuzzleHttp\Cookie\CookieJarInterface.

// Use a specific cookie jar
$jar = new \GuzzleHttp\Cookie\CookieJar;
$r = $client->request('GET', 'http://httpbin.org/cookies', [
    'cookies' => $jar
]);

Вы можете установить cookies в true в конструкторе клиента, если вы хотите использовать общий банк cookie для всех запросов.

// Use a shared client cookie jar
$client = new \GuzzleHttp\Client(['cookies' => true]);
$r = $client->request('GET', 'http://httpbin.org/cookies');

Для GuzzleHttp\Cookie\CookieJarInterface существуют различные реализации:

  • Класс GuzzleHttp\Cookie\CookieJar хранит cookies в виде массива.
  • Класс GuzzleHttp\Cookie\FileCookieJar сохраняет несеансовые cookies используя файл в формате JSON.
  • Класс GuzzleHttp\Cookie\SessionCookieJar сохраняет cookies в клиентской сессии.

Вы можете вручную установить куки в банку куки с помощью именованного конструктора fromArray(array $cookies, $domain).

$jar = \GuzzleHttp\Cookie\CookieJar::fromArray(
    [
        'some_cookie' => 'foo',
        'other_cookie' => 'barbaz1234'
    ],
    'example.org'
);

Вы можете получить cookie по его имени с помощью метода getCookieByName($name), который возвращает экземпляр GuzzleHttp\Cookie\SetCookie.

$cookie = $jar->getCookieByName('some_cookie');

$cookie->getValue(); // 'foo'
$cookie->getDomain(); // 'example.org'
$cookie->getExpires(); // expiration date as a Unix timestamp

Куки также могут быть собраны в массив благодаря методу toArray(). Интерфейс GuzzleHttp\Cookie\CookieJarInterface расширяет. Traversable, поэтому его можно итерировать в цикле foreach.

Перенаправления

Guzzle будет автоматически следовать перенаправлениям, если вы не запретите ему это делать. Вы можете настроить поведение перенаправления с помощью опции запроса allow_redirects.

  • Установите значение true, чтобы включить нормальные перенаправления с максимальным числом 5 перенаправлений. Это значение установлено по умолчанию.
  • Установите значение false, чтобы отключить перенаправления.
  • Передайте ассоциативный массив, содержащий ключ 'max' для указания максимального количество перенаправлений и, по желанию, значение ключа 'strict' для указания того. использовать ли строгие RFC-совместимые перенаправления (то есть перенаправлять POST-запросы с 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 зависят друг от друга.

. \RuntimeException
└── TransferException (implements GuzzleException)
    ├── ConnectException (implements NetworkExceptionInterface)
    └── RequestException
        ├── BadResponseException
        │   ├── ServerException
        │   └── ClientException
        └── TooManyRedirectsException

Guzzle выбрасывает исключения для ошибок, возникающих во время передачи.

  • Исключение GuzzleHttp\Exception\ConnectException выбрасывается в случае ошибки подключения к сети. в случае ошибки подключения к сети. Это исключение расширяется от GuzzleHttp\Exception\TransferException.

  • Исключение GuzzleHttp\Exception\ClientException бросается для 400 уровня, если опция http_errors запроса установлена в true. Этот исключение расширяется от GuzzleHttp\Exception\BadResponseException и GuzzleHttp\Exception\BadResponseException расширяется от GuzzleHttp\Exception\RequestException.

    use GuzzleHttp\Psr7;
    use GuzzleHttp\Exception\ClientException;
    
    try {
        $client->request('GET', 'https://github.com/_abc_123_404');
    } catch (ClientException $e) {
        echo Psr7\Message::toString($e->getRequest());
        echo Psr7\Message::toString($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(). Некоторые системы имеют проблемы с реализацией PHP curl_multi_select(), где вызов этой функции всегда приводит к ожиданию максимальной продолжительности таймаута.
HTTP_PROXY

Определяет прокси-сервер для использования при отправке запросов по протоколу "http"

Примечание: поскольку переменная HTTP_PROXY может содержать произвольный пользовательский ввод в некоторых (CGI) средах, эта переменная используется только в CLI SAPI. См. https://httpoxy.org для получения дополнительной информации.

HTTPS_PROXY
Определяет прокси-сервер, который будет использоваться при отправке запросов по протоколу "https".
NO_PROXY
Определяет URL, для которых не следует использовать прокси. Об использовании см. в proxy.

Relevant ini Settings

Guzzle может использовать параметры PHP ini при настройке клиентов.

openssl.cafile
Указывает путь на диске к файлу CA в формате PEM для использования при отправке запросов по протоколу "https". См: https://wiki.php.net/rfc/tls-peer-verification#phpini_defaults