Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【PHP8.x】CURLMOPT_MAX_CONCURRENT_STREAMS定数の使い方

CURLMOPT_MAX_CONCURRENT_STREAMS定数の使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

CURLMOPT_MAX_CONCURRENT_STREAMS定数は、PHPのcURL拡張機能において、HTTP/2プロトコルを使用する際に、一つのネットワーク接続(コネクション)上で同時に処理できるストリームの最大数を表す定数です。

この定数は、主に複数のcURLリクエストを効率的に並行処理するための「マルチハンドル」機能(curl_multi_*関数群)と組み合わせて利用されます。HTTP/2は、単一のTCP接続を再利用して複数のリクエストとレスポンスを同時に送受信できる「多重化」という特徴を持っていますが、クライアント側やサーバー側のリソースを過度に消費しないよう、同時にアクティブにできるストリームの数には上限を設けることが一般的です。

CURLMOPT_MAX_CONCURRENT_STREAMS定数を使用することで、curl_multi_setopt()関数を通じて、この同時並行ストリームの最大値を明示的に設定できます。例えば、多数の外部APIに対してHTTP/2経由でリクエストを送信するアプリケーションにおいて、この値を適切に調整することで、一度に処理されるリクエスト数を制御し、サーバーへの負荷を軽減したり、クライアント側のメモリやCPUなどのリソース消費を最適化したりすることが可能になります。この設定は、特に大量の並列処理が求められるシステムにおいて、安定性とパフォーマンスのバランスを取る上で重要な役割を果たします。

構文(syntax)

1CURLMOPT_MAX_CONCURRENT_STREAMS;

引数(parameters)

引数なし

引数はありません

戻り値(return)

戻り値なし

戻り値はありません

サンプルコード

CURLMOPT_MAX_CONCURRENT_STREAMS を設定する

1<?php
2
3/**
4 * CURLMOPT_MAX_CONCURRENT_STREAMS 定数の使用例。
5 *
6 * HTTP/2プロトコルにおいて、同時に許可されるストリームの最大数を設定します。
7 * これは、クライアントがサーバーに対して同時に開くことができるHTTP/2ストリームの数を制限するために使われます。
8 *
9 * @return void
10 */
11function demonstrateMaxConcurrentStreamsOption(): void
12{
13    // cURLマルチハンドルを初期化
14    $mh = curl_multi_init();
15
16    if ($mh === false) {
17        echo "Error: Failed to initialize cURL multi handle.\n";
18        return;
19    }
20
21    // CURLMOPT_MAX_CONCURRENT_STREAMS を設定
22    // ここでは最大2つのストリームを同時に許可するように設定します。
23    // この設定はHTTP/2接続にのみ適用され、HTTP/1.1接続には影響しません。
24    $maxConcurrentStreams = 2;
25    if (curl_multi_setopt($mh, CURLMOPT_MAX_CONCURRENT_STREAMS, $maxConcurrentStreams)) {
26        echo "CURLMOPT_MAX_CONCURRENT_STREAMS updated to " . $maxConcurrentStreams . ".\n";
27    } else {
28        echo "Error: Failed to set CURLMOPT_MAX_CONCURRENT_STREAMS.\n";
29        curl_multi_close($mh);
30        return;
31    }
32
33    // 複数のHTTP/2リクエストをシミュレートするためのURLリスト
34    $urls = [
35        "https://httpbin.org/delay/1", // 1秒遅延するダミーURL
36        "https://httpbin.org/delay/2", // 2秒遅延するダミーURL
37        "https://httpbin.org/delay/3", // 3秒遅延するダミーURL
38    ];
39
40    $chs = []; // cURLハンドルの配列
41
42    // 各URLに対してcURLハンドルを作成し、マルチハンドルに追加
43    foreach ($urls as $key => $url) {
44        $ch = curl_init();
45        if ($ch === false) {
46            echo "Error: Failed to initialize cURL handle for " . $url . ".\n";
47            continue;
48        }
49        curl_setopt($ch, CURLOPT_URL, $url);
50        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
51        // HTTP/2を使用するように設定します。サーバーがサポートしている場合に有効です。
52        curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
53        curl_setopt($ch, CURLOPT_TIMEOUT, 10); // 各リクエストのタイムアウトを10秒に設定
54
55        curl_multi_add_handle($mh, $ch);
56        $chs[$key] = $ch;
57        echo "Request added for: " . $url . "\n";
58    }
59
60    // 全てのリクエストが完了するまでcURLマルチリクエストを実行
61    $running = null;
62    do {
63        // cURLマルチハンドルでリクエストを実行
64        curl_multi_exec($mh, $running);
65        // CPU使用率を抑えるため、短い間隔でスリープ
66        usleep(100);
67    } while ($running > 0);
68
69    // 各リクエストの結果を取得し、ハンドルをクローズ
70    foreach ($chs as $key => $ch) {
71        // リクエストの応答内容を取得
72        $response = curl_multi_getcontent($ch);
73        // リクエストの情報を取得 (例: HTTPステータスコード)
74        $info = curl_getinfo($ch);
75        
76        echo "--- Result for " . $urls[$key] . " ---\n";
77        echo "HTTP Status Code: " . ($info['http_code'] ?? 'N/A') . "\n";
78        // 必要であれば $response の内容をここで表示できます。
79        // echo "Response content length: " . strlen($response) . " bytes\n";
80        
81        // マルチハンドルから個別のハンドルを削除し、クローズ
82        curl_multi_remove_handle($mh, $ch);
83        curl_close($ch);
84    }
85
86    // マルチハンドルをクローズ
87    curl_multi_close($mh);
88    echo "cURL multi handle closed.\n";
89}
90
91// 関数を実行
92demonstrateMaxConcurrentStreamsOption();
93

PHPのCURLMOPT_MAX_CONCURRENT_STREAMSは、cURL拡張機能において、HTTP/2プロトコルで同時に許可されるストリームの最大数を設定するための定数です。HTTP/2では、一つの接続上で複数のリクエストとレスポンスを同時にやり取りできますが、この並行にデータを送受信する個々の経路を「ストリーム」と呼びます。

この定数をcurl_multi_setopt()関数に渡して設定することで、クライアントがサーバーに対して同時に開くことができるHTTP/2ストリームの数を制限できます。これにより、ネットワークリソースの効率的な利用やサーバーへの過度な負荷を避けることが可能となります。CURLMOPT_MAX_CONCURRENT_STREAMS自体は引数を取らず、特定の整数値として機能し、戻り値もありません。

サンプルコードでは、まずcurl_multi_init()で複数のHTTPリクエストを効率的に管理するための「マルチハンドル」を初期化しています。次に、curl_multi_setopt()関数を使用してCURLMOPT_MAX_CONCURRENT_STREAMSオプションに2という値を設定し、同時に2つのHTTP/2ストリームのみが許可されるように指定しています。その後、複数のHTTP/2リクエストを作成し、それぞれにCURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0を設定してHTTP/2プロトコルを使用するように準備しています。これらのリクエストはcurl_multi_exec()によって並行して実行され、設定された同時ストリーム数の制限内で処理が進められます。この設定は、HTTP/2通信のパフォーマンスと安定性を調整する上で重要な役割を果たします。

このCURLMOPT_MAX_CONCURRENT_STREAMSはHTTP/2接続でのみ有効な設定であり、サンプルコードのようにCURLOPT_HTTP_VERSIONでHTTP/2を明示的に指定し、接続先のサーバーがHTTP/2をサポートしているか確認することが重要です。設定する同時ストリーム数が多すぎるとサーバーに負荷をかけ、少なすぎるとパフォーマンスが低下する可能性があるため、適切な値を検討してください。また、cURLマルチハンドルや個別のハンドルは、処理が完了したら必ずcurl_multi_close()curl_close()で解放し、リソースリークを防ぎましょう。各cURL関数の実行結果は常に確認し、エラーが発生した場合は適切に処理する習慣をつけることが安全なコードを書く上で非常に大切です。

CURLMOPT_MAX_CONCURRENT_STREAMS を設定する

1<?php
2
3/**
4 * CURLMOPT_MAX_CONCURRENT_STREAMS 定数の使用方法を示すサンプルコード。
5 *
6 * この定数は、HTTP/2のような多重化プロトコルにおいて、単一の接続で
7 * 許可されるストリームの最大数を設定するために使用されます。
8 * 例えば、HTTP/2接続で同時に処理できるリクエストの数を制限する際に役立ちます。
9 */
10function demonstrateMaxConcurrentStreams(): void
11{
12    // cURLマルチハンドルを初期化します。これを使って複数のcURLリクエストを並行して実行できます。
13    $multiHandle = curl_multi_init();
14
15    if ($multiHandle === false) {
16        echo "cURLマルチハンドルの初期化に失敗しました。\n";
17        return;
18    }
19
20    // CURLMOPT_MAX_CONCURRENT_STREAMS オプションを設定します。
21    // キーワードに従い、最大同時ストリーム数を128に設定します。
22    // これは、HTTP/2などの多重化プロトコルで、単一の接続を介して
23    // 同時に実行できる論理的なリクエスト(ストリーム)の最大数を制限します。
24    // PHP 8では、この定数は int 型の値を取ります。
25    $optionSet = curl_multi_setopt($multiHandle, CURLMOPT_MAX_CONCURRENT_STREAMS, 128);
26
27    if (!$optionSet) {
28        echo "CURLMOPT_MAX_CONCURRENT_STREAMS の設定に失敗しました。\n";
29        curl_multi_close($multiHandle);
30        return;
31    }
32
33    echo "CURLMOPT_MAX_CONCURRENT_STREAMS を " . CURLMOPT_MAX_CONCURRENT_STREAMS . " (値: 128) に設定しました。\n";
34
35    // ダミーのURLをいくつか用意し、それぞれにcURLハンドルを作成します。
36    // これらのリクエストは、設定された最大同時ストリーム数の範囲内で並行して実行されます。
37    $urls = [
38        'https://jsonplaceholder.typicode.com/posts/1',
39        'https://jsonplaceholder.typicode.com/posts/2',
40        'https://jsonplaceholder.typicode.com/posts/3',
41    ];
42    $curlHandles = [];
43
44    foreach ($urls as $id => $url) {
45        $ch = curl_init($url);
46        if ($ch === false) {
47            echo "cURLハンドルの初期化に失敗しました: {$url}\n";
48            continue;
49        }
50        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 結果を文字列で返すように設定
51        curl_setopt($ch, CURLOPT_HEADER, false);       // レスポンスヘッダーを含めない
52        $curlHandles[$id] = $ch;
53        curl_multi_add_handle($multiHandle, $ch);      // マルチハンドルに個々のハンドルを追加
54    }
55
56    // すべてのリクエストが完了するまでループします。
57    $running = null;
58    do {
59        // cURLマルチハンドルの活動を監視し、実行します。
60        // $running にはまだ実行中のハンドルの数が設定されます。
61        $status = curl_multi_exec($multiHandle, $running);
62
63        // まだ実行中のハンドルがあり、エラーがない場合、
64        // curl_multi_select でファイルディスクリプタのアクティビティを待機します。
65        // これにより、CPU使用率を抑えることができます。
66        if ($running > 0 && $status === CURLM_OK) {
67            // イベントが発生するか、最大0.5秒待機します。
68            // curl_multi_select は -1 を返す場合があるため、その際は短いスリープで対応します。
69            if (curl_multi_select($multiHandle, 0.5) == -1) {
70                usleep(100); // CPU負荷を軽減するために少しスリープ
71            }
72        }
73    } while ($running > 0 && $status === CURLM_OK);
74
75    // 各リクエストの結果を取得し、リソースを解放します。
76    $results = [];
77    foreach ($curlHandles as $id => $ch) {
78        $info = curl_getinfo($ch); // リクエスト情報を取得
79        $content = curl_multi_getcontent($ch); // レスポンスボディを取得
80        $error = curl_error($ch); // エラーメッセージを取得
81
82        if ($error) {
83            $results[$id] = "URL " . $urls[$id] . " の取得中にエラー: " . $error;
84        } else {
85            // 初心者向けに、取得したコンテンツの最初の数文字のみ表示
86            $results[$id] = "URL " . $urls[$id] . " のレスポンス (ステータス: " . $info['http_code'] . "): " . substr($content, 0, 100) . "...";
87        }
88
89        curl_multi_remove_handle($multiHandle, $ch); // マルチハンドルから個々のハンドルを削除
90        curl_close($ch); // 個々のcURLハンドルをクローズ
91    }
92
93    curl_multi_close($multiHandle); // cURLマルチハンドルをクローズ
94
95    // 結果を出力します。
96    echo "\n--- リクエスト結果 ---\n";
97    foreach ($results as $result) {
98        echo $result . "\n";
99    }
100
101    echo "\nサンプルコードの実行が完了しました。\n";
102}
103
104// 関数を実行してデモンストレーションを開始します。
105demonstrateMaxConcurrentStreams();

CURLMOPT_MAX_CONCURRENT_STREAMSは、PHPのcURL拡張機能で利用される定数です。この定数は、主にHTTP/2のような多重化プロトコルにおいて、一つのネットワーク接続で同時に処理できる「ストリーム」(論理的なリクエスト)の最大数を設定するために使用されます。これにより、サーバーやネットワークにかかる負荷を調整し、効率的な通信管理を行うことができます。

サンプルコードでは、curl_multi_setopt関数を用いて、cURLマルチハンドルに対してこの定数を設定しています。具体的には、curl_multi_setopt($multiHandle, CURLMOPT_MAX_CONCURRENT_STREAMS, 128)のように記述することで、同時に実行できるストリームの最大数を128に制限しています。この定数自体は引数を取りませんし、特定の値を返すわけでもありませんが、curl_multi_setopt関数に渡す設定値として機能します。

この設定により、例えば多数の外部APIを呼び出す際に、同時に送出されるHTTP/2リクエストの数を制御し、接続先のサーバーに過度な負担をかけないように調整できます。結果として、安定したアプリケーション動作に貢献します。

この定数はPHP 8以降で利用可能であり、HTTP/2のような多重化プロトコルにおいて、単一の接続で同時に処理できるリクエストの最大数を設定するために使用します。HTTP/1.xではこの設定は効果がありませんのでご注意ください。設定値128はサンプルですが、実際に利用する環境や接続先のサーバー負荷を考慮し、最適な値を設定することが重要です。安易に大きな値を設定すると、サーバーに過度な負担をかけたり、かえってパフォーマンスが低下したりする可能性があります。サンプルコードのようにcurl_multi_setoptで設定した後は、必ずcurl_multi_closeでリソースを解放してください。また、curl_multi_initcurl_multi_setoptの戻り値をチェックし、エラー発生時に適切に処理するエラーハンドリングも重要です。

関連コンテンツ

関連IT用語

関連プログラミング言語