Статьи

Guzzle — PHP HTTP-клиент

Как вы, наверное, знаете, разработка сайта может быть разбита на 2 основных области:

  • Внешний интерфейс (что видит конечный пользователь)
  • Back end (что сервер должен сделать для предоставления запрошенных данных)

В то время как при разработке интерфейса часто используется несколько источников данных для отображения страницы, простые динамические сайты будут зависеть только от данных, поступающих из базы данных, размещенной на одном сервере. Как бэкэнд-разработчикам сегодня нам нужно извлекать данные с сервера базы данных на другом хосте или использовать API от стороннего провайдера, при этом создавая впечатление, что все происходит на нашем сервере.

PHP поставляется с собственным клиентом cURL (если он включен), который может быть пугающим для новичка или трудным для использования сервисов SOAP. Другие платформы в некоторой степени реализуют свои версии клиентов HTTP, REST и SOAP. Однако, если вы не хотите использовать cURL, у вас нет фреймворка, или вы не являетесь поклонником решения вашей фреймворки, Guzzle to the rescue.

Guzzle — это независимый HTTP-клиент для PHP. Установить Guzzle очень просто: сначала нужно получить композитора ( http://www.sitepoint.com/php-dependency-management-with-composer/ ). После того, как вы установили и подготовили composer, создайте основной файл composer.json , который будет выглядеть следующим образом:

  { "name": "jd/guzzle demo", "authors": [ { "name": "John Doe", "email": "john@doe.tst" } ], "require": { } } 

Теперь просто добавьте библиотеку guzzle в файл composer.json в разделе require :

  { "name": "jd/guzzle demo", "authors": [ { "name": "John Doe", "email": "john@doe.tst" } ], "require": { "guzzle/guzzle": "~3.7" } } 

Сохранив файл, вам просто нужно запустить команду composer install и вы должны быть готовы!

основы

Как энтузиаст криптографии, поиск источников энтропийных данных для генерации ключей — мое хобби. Один хороший источник — сервер квантовых случайных чисел ANU по адресу https://qrng.anu.edu.au . Предположительно, их RNG основан на квантовой физике, поэтому стоит взглянуть при генерации случайных данных с хорошим уровнем энтропии.

К счастью, у них есть общедоступный API, который мы можем использовать, так что вот где Guzzle пригодится:

  <?php chdir(dirname(__DIR__)); require_once 'vendor/autoload.php'; use Guzzle\Http\Client; use Guzzle\Http\EntityBody; use Guzzle\Http\Message\Request; use Guzzle\Http\Message\Response; /** @var $client Client */ $client = new Client("https://qrng.anu.edu.au"); 

Первые две строки должны быть знакомы любому, кто использует composer и его механизмы автозагрузки. Когда мы создаем экземпляр объекта Client, мы должны передать в качестве параметра конструктора URL-адрес, к которому мы хотим подключиться. Обратите внимание, что он не использует параметры пути и / или URL — это произойдет через минуту.

  /** @var $request Request */ $request = $client->get('/API/jsonI.php?length=10&type=uint8'); /** @var $response Response */ $response = $request->send(); /** @var $body EntityBody */ $body = $response->getBody(true); 

Наконец, мы указываем /API/jsonI.php путь ( /API/jsonI.php ) и параметры URL ( length=10&type=uint8 ), создавая HTTP-запрос GET с помощью метода $client->get() . Если мы хотим построить запрос POST, у объекта client есть post() и многие другие методы HTTP-запроса. Для отправки запроса должен быть вызван метод $request->send() , перехватывающий ответ в переменной $response . Наконец, если мы хотим увидеть ответ от удаленного сервера, мы выполняем метод $response->getBody() . getBody() TRUE может быть отправлено в качестве параметра в метод getBody() для получения результата в виде строки.

Параметры пути и URL-адреса

В предыдущем примере мы использовали строку для указания пути и параметров URL для построения запроса … Это может быть не самым элегантным решением. Мы можем решить передать определенные параметры URL или использовать другие пути в соответствии с определенными условиями. Мы можем легко выполнить правильную обработку параметров пути и URL, внеся некоторые изменения в код.

  /** @var $request Request */ $request = $client->createRequest(); $request->setPath('/API/jsonI.php'); $request->getQuery() ->set('length', 10) ->set('type', 'uint8'); 

Сначала мы создаем пустой запрос от клиента Guzzle с помощью метода $client->getRequest() . Объект запроса имеет несколько методов; в этом случае мы будем использовать setPath() и getQuery() . setPath() должен быть довольно простым; getQuery касается getQuery , мы используем свободный интерфейс Guzzle, чтобы установить параметры URL один за другим.

логирование

Когда мы разрабатываем приложения, которые используют сторонние сервисы через сеть, часто возникают проблемы со связью, поэтому очень важно вести журнал со всеми запросами и ответами, по крайней мере, на этапах разработки, чтобы мы могли отлаживать происходящее.

Guzzle предоставляет несколько плагинов. В случае с подключаемыми плагинами у нас есть несколько доступных адаптеров. Для этого примера мы будем использовать монолог

Чтобы монолог был доступен в вашем проекте, вам нужно изменить файл composer.json и запустить команду обновления composer. Ваш файл composer.json должен выглядеть следующим образом:

  { "name": "jd/guzzle demo", "authors": [ { "name": "John Doe", "email": "john@doe.tst" } ], "require": { "guzzle/guzzle": "~3.7", "monolog/monolog": "1.6.0" } } 

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

  <?php chdir(dirname(__DIR__)); require_once 'vendor/autoload.php'; //... use Guzzle\Log\MessageFormatter; use Guzzle\Log\MonologLogAdapter; use Guzzle\Plugin\Log\LogPlugin; use Monolog\Handler\StreamHandler; use Monolog\Logger; $logger = new Logger('client'); $logger->pushHandler(new StreamHandler('guzzle.log')); $logAdapter = new MonologLogAdapter($logger); $logPlugin = new LogPlugin($logAdapter, MessageFormatter::DEBUG_FORMAT); /** @var $client Client */ $client = new Client("https://qrng.anu.edu.au"); $client->addSubscriber($logPlugin); 

Сначала мы создаем экземпляр монолога с помощью $logger = new Logger('client'); , Monolog обладает несколькими обработчиками, в этом случае мы будем использовать StreamHandler для записи в файл с именем guzzle.log . Затем мы создаем монологический адаптер жадности, создавая экземпляр объекта MonologLogAdapter. Затем мы создаем объект подключаемого модуля журнала, используя менеджер подключаемых модулей журнала Guzzle LogPlugin. Обратите внимание на константу MessageFormatter::DEBUG_FORMAT которая указывает Guzzle регистрировать полные сообщения с запросами и ответами. Пожалуйста, обратитесь к документации Guzzle, чтобы увидеть, какие форматы сообщений доступны. Наконец, мы добавляем плагин log-файла в клиент $client->addSubscriber($logPlugin); вызывая $client->addSubscriber($logPlugin);

Взаимодействие с Github API

Давайте посмотрим на этот код, а затем я объясню его построчно

  <?php chdir(dirname(__DIR__)); require_once 'vendor/autoload.php'; use Guzzle\http\Client; use Guzzle\Log\MonologLogAdapter; use Guzzle\Plugin\Log\LogPlugin; use Guzzle\Log\MessageFormatter; use Monolog\Logger; use Monolog\Handler\StreamHandler; $client = new Client('https://api.github.com'); $log = new Logger('log'); $log->pushHandler(new StreamHandler('requests.log')); $adapter = new MonologLogAdapter($log); $logPlugin = new LogPlugin($adapter, MessageFormatter::DEBUG_FORMAT); $client->addSubscriber($logPlugin); $request = $client->post('authorizations', array(), json_encode( array( 'scopes' => array( 'public_repo', 'user', 'repo', 'gist' ), 'note' => 'auto client' . uniqid() ))); $request->setAuth('john@doe.tst', 'yourpasswordhere'); $request->getCurlOptions()->set(CURLOPT_SSL_VERIFYPEER, false); $response = $request->send(); $body = json_decode($response->getBody(true)); $oauthToken = $body->token; $request = $client->get('user/keys'); $query = $request->getQuery(); $query->add('access_token', $oauthToken); $request->getCurlOptions()->set(CURLOPT_SSL_VERIFYPEER, false); try { $response = $request->send(); $body = $response->getBody(true); echo $body; } catch (Exception $e) { echo $request->getResponse()->getRawHeaders(); } 

Подробное объяснение приведено ниже.

 $client = new Client('https://api.github.com'); 

Мы создаем клиента, который будет использовать базовый URL Github API.

  $log = new Logger('log'); $log->pushHandler(new StreamHandler('requests.log')); $adapter = new MonologLogAdapter($log); $logPlugin = new LogPlugin($adapter, MessageFormatter::DEBUG_FORMAT); $client->addSubscriber($logPlugin); 

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

  $request = $client->post('authorizations', array(), json_encode( array( 'scopes' => array( 'public_repo', 'user', 'repo', 'gist' ), 'note' => 'auto client' . uniqid() ))); 

Сначала мы хотим запросить авторизацию для использования API Github ( http://developer.github.com/v3/oauth/ ) без необходимости каждый раз использовать имя пользователя и пароль, поэтому нам нужно выполнить HTTP-глагол POST для https://api.github.com/authorizations . Помните, что мы создали базовый URL при создании нашего клиента, поэтому нам нужно только указать путь. Чтобы увидеть список возможных параметров, которые можно отправить в API Github, обратитесь к их документации.

  $request->setAuth('john@doe.tst', 'yourpasswordhere'); $request->getCurlOptions()->set(CURLOPT_SSL_VERIFYPEER, false); 

В этот раз мы будем использовать HTTP Basic Authentication. Помните, что единственным механизмом, препятствующим отправке ваших учетных данных в виде простого текста, является HTTPS (как показано в URL-адресе API) — выполнение запроса через что-то настолько небезопасное, что HTTP может привести к тому, что кто-то перехватит ваши данные. Во второй строке мы настраиваем cURL, чтобы не проверять сертификат SSL, так как это может решить несколько проблем связи.

  $response = $request->send(); $body = json_decode($response->getBody(true)); 

Наконец мы отправляем запрос. Ответ получен через метод getBody (), флаг TRUE используется для настройки Guzzle на возврат простой строки. Помните, что API Github является RESTful, поэтому все будет закодировано в JSON, и, таким образом, мы будем декодировать его в объект с помощью json_decode ().

  $oauthToken = $body->token; 

Токен Oauth будет находиться внутри атрибута ‘token’. Пожалуйста, обратитесь к документации Github API для подробного объяснения формата ответа.

  $request = $client->get('user/keys'); $query = $request->getQuery(); $query->add('access_token', $oauthToken); 

Мы будем выполнять новый запрос. На этот раз мы хотим перечислить наши авторизованные ключи, которые настроены в нашей учетной записи, в основном для доступа к нашим репозиториям через SSH. На этот раз необходимо отправить HTTP-запрос GET, но вместо использования наших учетных данных в виде простого текста мы будем использовать выданный нам токен Oauth; этот токен должен быть добавлен в качестве параметра запроса к URL-адресу, который мы запрашиваем.

  $response = $request->send(); $body = $response->getBody(true); echo $body; 

Наконец, мы отправляем запрос и получаем тело ответа, готовое для анализа и использования в любых целях.

Вывод

Эта небольшая демонстрация — лишь вершина айсберга того, на что способен Guzzle. С хорошо структурированной системой плагинов, механизмом обработки запросов и ответов вы можете, наконец, приручить большое количество API, которые может предложить Интернет.

Если у вас есть конкретный пример использования Guzzle, который вы хотели бы продемонстрировать, или просто общие замечания, дайте нам знать!