Често задавани въпроси

Изисква ли Guzzle cURL?

Не. Guzzle може да използва всеки HTTP манипулатор за изпращане на заявки. Това означава, че Guzzle може да се използва с cURL, обвивката за потоци на PHP, сокети и неблокиращи библиотеки като React. Необходимо е само да конфигурирате HTTP манипулатор да използвате различен метод за изпращане на заявки.

Забележка

В миналото Guzzle е използвал само cURL за изпращане на HTTP заявки. cURL е е невероятен HTTP клиент (вероятно най-добрият) и Guzzle ще продължи да използва по подразбиране, когато е наличен. Рядко се случва, но някои разработчици не имат инсталиран cURL на своите системи или се сблъскват с проблеми, свързани с конкретната версия. С разрешаването на сменяеми HTTP манипулатори Guzzle вече е много по-персонализиран и може да се адаптира към нуждите на повече разработчици.

Може ли Guzzle да изпраща асинхронни заявки?

Да. Можете да използвате requestAsync, sendAsync, getAsync, headAsync, putAsync, postAsync, deleteAsync и patchAsync на клиент, за да изпрати асинхронна заявка. Клиентът ще върне GuzzleHttp\Promise\PromiseInterface обект. Можете да свържете then функции от обещанието.

$promise = $client->requestAsync('GET', 'http://httpbin.org/get');
$promise->then(function ($response) {
    echo 'Got a response! ' . $response->getStatusCode();
});

Можете да принудите асинхронния отговор да завърши, като използвате метода wait() на върнатото обещание.

$promise = $client->requestAsync('GET', 'http://httpbin.org/get');
$response = $promise->wait();

Как мога да добавя потребителски cURL опции?

cURL предлага огромен брой опции за персонализиране. Въпреки че Guzzle нормализира много от тези опции в различните обработващи програми, има понякога се налага да зададете персонализирани опции на cURL. Това може да бъде постигнато чрез предаване на асоциативен масив от cURL настройки в ключа curl на заявка.

Например, да кажем, че трябва да персонализирате изходящия мрежов интерфейс, използван с даден клиент.

$client->request('GET', '/', [
    'curl' => [
        CURLOPT_INTERFACE => 'xxx.xxx.xxx.xxx'
    ]
]);

Ако използвате асинхронни заявки с мултиобработчик на cURL и искате да го настроите, допълнителни опции могат да бъдат зададени като асоциативен масив в options ключа на CurlMultiHandler конструктора.

use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Handler\CurlMultiHandler;

$client = new Client(['handler' => HandlerStack::create(new CurlMultiHandler([
    'options' => [
        CURLMOPT_MAX_TOTAL_CONNECTIONS => 50,
        CURLMOPT_MAX_HOST_CONNECTIONS => 5,
    ]
]))]);

Как мога да добавя потребителски опции за контекста на потока?

Можете да предавате потребителски опции за контекста на потока като използвате ключа stream_context на опцията за заявка. Ключът stream_context е асоциативен масив, в който всеки ключ е PHP транспорт, а всяка стойност е асоциативен масив от опции за транспорт.

Например, да кажем, че трябва да персонализирате изходящия мрежов интерфейс, използван с клиент, и да разрешите самоподписани сертификати.

$client->request('GET', '/', [
    'stream' => true,
    'stream_context' => [
        'ssl' => [
            'allow_self_signed' => true
        ],
        'socket' => [
            'bindto' => 'xxx.xxx.xxx.xxx'
        ]
    ]
]);

Защо получавам грешка при проверка на SSL?

Трябва да посочите пътя на диска до пакета на CA, използван от Guzzle за проверка на партньорския сертификат. Вижте verify.

Каква е тази грешка за влагане на максимална функция?

Maximum function nesting level of '100' reached, aborting

Тази грешка може да възникне, ако сте инсталирали разширението XDebug и изпълнявате много заявки в обратни извиквания. Това съобщение за грешка идва специално от разширението XDebug. Самият PHP не разполага с функция ограничение за влагане на функции. Променете тази настройка в php.ini, за да увеличите ограничението:

xdebug.max_nesting_level = 1000

Защо получавам отговор за грешка 417?

Това може да се случи по редица причини, но ако изпращате PUT, POST или PATCH заявки с хедър Expect: 100-Continue, сървър, който не не поддържа този хедър, ще върне отговор 417. Можете да заобиколите това, като като зададете опцията за заявка expect на false:

$client = new GuzzleHttp\Client();

// Disable the expect header on a single request
$response = $client->request('PUT', '/', ['expect' => false]);

// Disable the expect header on all client requests
$client = new GuzzleHttp\Client(['expect' => false]);

Как мога да проследя пренасочените заявки?

Можете да активирате проследяването на пренасочените URI и кодове на състоянието чрез track_redirects. Всеки пренасочен URI и код на състоянието ще се съхраняват в X-Guzzle-Redirect-History и X-Guzzle-Redirect-Status-History съответно заглавието.

URI на първоначалната заявка и крайният код на състоянието ще бъдат изключени от резултатите. По този начин ще можете лесно да проследите пълния път на пренасочване на заявката.

Например, да кажем, че трябва да проследявате пренасочвания и да предоставяте двата резултата заедно в един отчет:

// First you configure Guzzle with redirect tracking and make a request
$client = new Client([
    RequestOptions::ALLOW_REDIRECTS => [
        'max'             => 10,        // allow at most 10 redirects.
        'strict'          => true,      // use "strict" RFC compliant redirects.
        'referer'         => true,      // add a Referer header
        'track_redirects' => true,
    ],
]);
$initialRequest = '/redirect/3'; // Store the request URI for later use
$response = $client->request('GET', $initialRequest); // Make your request

// Retrieve both Redirect History headers
$redirectUriHistory = $response->getHeader('X-Guzzle-Redirect-History')[0]; // retrieve Redirect URI history
$redirectCodeHistory = $response->getHeader('X-Guzzle-Redirect-Status-History')[0]; // retrieve Redirect HTTP Status history

// Add the initial URI requested to the (beginning of) URI history
array_unshift($redirectUriHistory, $initialRequest);

// Add the final HTTP status code to the end of HTTP response history
array_push($redirectCodeHistory, $response->getStatusCode());

// (Optional) Combine the items of each array into a single result set
$fullRedirectReport = [];
foreach ($redirectUriHistory as $key => $value) {
    $fullRedirectReport[$key] = ['location' => $value, 'code' => $redirectCodeHistory[$key]];
}
echo json_encode($fullRedirectReport);