HTTPクライアントであるGuzzleで並列リクエスを試す

Published: 2017年2月19日 by tomsato

概要

GuzzleとはHTTPリクエストを簡単に送信できるPHPのHTTPクライアントである

HTTPクライアントの中でも現在最も主流となっていて、複数のリクエストを並列で送信することもできる

Guzzleをとりあえず使うところから、並列リクエストの方法も書いてみる

Guzzleのドキュメント(英語)

Guzzleを試してみる

準備

検証環境について

$ cat /etc/redhat-release
CentOS release 6.8 (Final)

composer install

$ curl -sS https://getcomposer.org/installer | php
$ sudo mv composer.phar /usr/local/bin/composer

guzzle install

$ mkdir sample && cd sample
$ composer require guzzlehttp/guzzle

GETのサンプル

サンプルソース

$ cat sample.php
<?php
require __DIR__ . '/vendor/autoload.php';

$client = new GuzzleHttp\Client();

// Guzzleを使ってAPIを叩く、叩き方は2種類あるので使いやすい方を使う
$response = $client->get('http://httpbin.org/get');
$response = $client->request('GET', 'http://httpbin.org/get');

// ステータスコード取得
var_dump($response->getStatusCode());

// レスポンスボディ取得
// 扱いやすいようにJSONからPHPの配列に変換する
var_dump(json_decode($response->getBody(), true));

サンプル実行

$ php sample.php
int(200)
array(4) {
 ["args"]=>
 array(0) {
 }
 ["headers"]=>
 array(2) {
 ["Host"]=>
 string(11) "httpbin.org"
 ["User-Agent"]=>
 string(39) "GuzzleHttp/6.2.1 curl/7.19.7 PHP/5.6.30"
 }
 ["origin"]=>
 string(13) "126.112.54.50"
 ["url"]=>
 string(22) "http://httpbin.org/get"
}

POSTのサンプル

サンプルソース
オプションについて: request-options

<?php
require __DIR__ . '/vendor/autoload.php';

$client = new GuzzleHttp\Client();

// 第1引数: HTTPメソッド
// 第2引数: URL
// 第3引数: オプション
$response = $client->request(
  'POST',
  'http://httpbin.org/post',
  [
    // headers: HTTPヘッダを指定できる
    'headers' => [
      'Content-Type' => 'application/json'
    ],
    // form_params: PHPの配列をフォーム形式に変換してリクエストする
    'form_params' => [
      'q' => 'hoge'
    ]
  ]
);
var_dump($response->getStatusCode());
var_dump(json_decode($response->getBody(), true));

非同期処理を試してみる

Promiseとは非同期処理を抽象化したオブジェクト
今回は使わないが複数のPromiseをメソッドチェインで繋げることもできる

Promiseを使ったサンプル

<?php
use GuzzleHttp\Client;
use GuzzleHttp\Promise;
use GuzzleHttp\Psr7\Response;
require __DIR__ . '/vendor/autoload.php';

$urls = [
  'sample1' => 'http://httpbin.org/get',
  'sample2' => 'http://httpbin.org/get',
  'sample3' => 'http://httpbin.org/get',
  'sample4' => 'http://httpbin.org/get',
  'sample5' => 'http://sample.error.url/',
];

$client = new Client();
$promises = [];
$results  = [];

// それぞれのURLに対して非同期でURLを投げる
foreach ($urls as $key => $url) {
  $promises[$key] = $client->requestAsync('GET', $url);
}

// requestが完了するのを待った後、結果によって処理を行う
foreach (Promise\settle($promises)->wait() as $key => $obj) {
  switch ($obj['state']) {
    case 'fulfilled':
      // 成功時
      $results[$key] = $obj['value'];
      break;
    case 'rejected':
      // 失敗時
      $results[$key] = new Response($obj['reason']->getCode());
      break;
    default:
      // 想定外としてエラー扱いにする
      $results[$key] = new Response(0);
  }
}

// 成功したrequestの結果だけ表示する
foreach ($results as $result) {
  if ($result->getReasonPhrase() === 'OK') {
    var_dump(json_decode($result->getBody()->getContents(), true));
  }
}

並列でHTTPリクエストを実行しているのでURLの数を増やしても時間はほとんど変わらない

PHP

コメントを書く

※ 個別に返信が必要な時のみご記入ください

※ Emailは公開されません

※ 承認されると名前・コメントが下記に表示されます

コメント一覧

最近の投稿

ビジュアルリグレッションテストについてまとめ、ネットで調べると数多くのライブラリがありどれがどんな立ち位置なのか全体像がわかりずらかったのでどんな種類があるのか入門の入門としてまとめます、またPlaywrightを使って実際に触ってみました

社内ツールなどの超小規模なAPIをGolangで実装する際にフレームワークを使うべきかを、実際にnet/httpを使った実装とフレームワークを使った実装を比較することでどれだけ優位性があるかを見ていきたいと思います。今回はフレームワークにはシンプルで使いやすそうなEchoを使うことにします。

vue-pdfを使ってNuxt.jsで作成しているアプリケーションに pdfスライドを表示させるサンプルを作成しました README.md通りに実装してもうまくいかないところがあったのでそのあたり含めてまとめます

Vue.js / Nuxt.jsにおけるログインの実装方法をまとめる Auth0やNuxt.jsのAuth Moduleとmiddlewareについて調べつつサンプルを作成することで理解を深める

コンポーネント設計について考える Atomic DesignやPresentational Component, Container Componentについてまとめつつ 自分だったらVue.js / Nuxt.jsでどういうコンポーネント設計にするかについてまとめます

カテゴリ一覧

タグ一覧