guzzleの並列処理

こんばんは、エキサイト中尾です。

PHPのguzzleを使った並列処理を簡単に説明します。

単純に並列処理するシンプルな実装だと思います。

<?php 

public function multi(){
        $urls = [
            'google' => "https://google.com",
            'yahoo' => "https://yahoo.co.jp",
            'excite' => "https://excite.co.jp",
            'hogehoge' => "https://hogehoge.co.jp",
        ];

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

        foreach ($urls as $key => $url) {
            $promises[$key] = $client->requestAsync('GET', $url);
        }

        foreach (Promise\Utils::settle($promises)->wait() as $key => $obj) {
            switch ($obj['state']) {
                case PromiseInterface::FULFILLED:
                    if ($obj['value']->getReasonPhrase() === 'OK') {
                        // 成功時
                        $results[$key] = json_decode($obj['value']->getBody()->getContents(), true);
                    }else{
                        error_log($key . " : " . $obj['value']->getReasonPhrase());
                        $results[$key] = null;
                    }
                    break;
                case PromiseInterface::REJECTED:
                    error_log($key . " : " . $obj['reason']->getCode());
                    $results[$key] = null;
                    break;
                default:
                    error_log($key . " : unknown");
                    $results[$key] = null;
            }
        }
}

unwrapは使用していません。 unwrapとsettleには以下の違いがあります。

  • unwrap
    • Wait for the requests to complete; throws a ConnectException if any of the requests fail (リクエストが完了するまで待ちます。いずれかのリクエストが失敗した場合に ConnectException をスローします)
  • settle
    • Wait for the requests to complete, even if some of them fail (一部のリクエストが失敗した場合でも、リクエストが完了するまで待機します)

docs.guzzlephp.org

つまり、リクエスト先が100%成功しないといけない場合はunwrap、一部かけていても問題ない場合はsettleが適していると判断します。

ケースによってunwrapとsettleを使い分けてください。