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

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

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

作成日: 更新日:

基本的な使い方

CURLKHMATCH_MISMATCH定数は、PHP 8のcURL拡張機能において、SSH(Secure Shell)接続時に利用される既知ホスト(Known Hosts)の検証結果が「不一致」であることを示す定数です。cURLライブラリがSSHセッションを確立する際、接続先のホストが提供する公開鍵が、ローカルに保存されている既知ホストファイル(例: ~/.ssh/known_hosts)内の情報と一致するかどうかを確認します。

この定数は、主にCURLOPT_SSH_KNOWNHOSTSオプションと組み合わせて使用されます。CURLKHMATCH_MISMATCHが返された場合、それは接続しようとしているリモートホストの公開鍵が、既知ホストファイルに登録されている情報と異なっていることを意味します。この不一致は、ホストの身元が変更された可能性や、場合によっては中間者攻撃(Man-in-the-Middle attack)のようなセキュリティ上の脅威を示唆している可能性があります。

システムエンジニアを目指す初心者の方にとっては、この定数が返される状況は「接続しようとしているサーバーの正当性が確認できない」状態だと理解すると良いでしょう。プログラムがこの定数を受け取った場合、セキュリティリスクを回避するために、通常は接続を中断し、ユーザーや管理者に対して警告を発するなどの適切な対処が求められます。既知ホストファイルの内容を確認し、必要に応じて更新することが重要になります。

構文(syntax)

1<?php
2echo CURLKHMATCH_MISMATCH;
3?>

引数(parameters)

引数なし

引数はありません

戻り値(return)

int

CURLKHMATCH_MISMATCHは、証明書のハッシュ値が期待される値と一致しないことを示す整数値です。

サンプルコード

PHPで複数URLを並行取得する

1<?php
2
3/**
4 * 複数のURLに対して並行してcURLリクエストを実行し、結果を返します。
5 * システムエンジニアを目指す初心者が、複数のネットワークリクエストを効率的に処理する方法を学ぶのに役立ちます。
6 *
7 * @param array<string> $urls リクエストするURLの配列
8 * @return array<string, string|false> 各URLに対するレスポンスボディ、またはエラーメッセージ
9 */
10function performMultiCurlRequests(array $urls): array
11{
12    $mh = curl_multi_init(); // マルチcURLハンドルを初期化
13    $chHandles = [];         // 個々のcURLハンドルの配列を格納する配列
14
15    // 各URLに対してcURLハンドルを設定し、マルチハンドルに追加します。
16    foreach ($urls as $url) {
17        $ch = curl_init();
18        curl_setopt($ch, CURLOPT_URL, $url);
19        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // レスポンスを文字列として取得
20        curl_setopt($ch, CURLOPT_HEADER, false);      // レスポンスヘッダーを含めない
21
22        // 個々のcURLハンドルをマルチハンドルに追加
23        curl_multi_add_handle($mh, $ch);
24        // ハンドルID (cURLリソースの内部ID) をキーとして、URLとハンドルを保存します。
25        // これは、後でどのハンドルがどのURLに対応するかを識別するために使われます。
26        $chHandles[(string)$ch] = ['url' => $url, 'handle' => $ch];
27    }
28
29    $running = null; // 実行中のハンドルの数を保持する変数
30    do {
31        // アクティブな転送がある限り、cURLリクエストを実行します。
32        // curl_multi_exec は、実行中のハンドルの数を $running に設定し、
33        // 転送の状態を示すステータスコードを返します。
34        $status = curl_multi_exec($mh, $running);
35
36        // 転送中にエラーが発生した場合
37        if ($status > 0) {
38            // ここではエラーログに出力するだけですが、より詳細なエラー処理も可能です。
39            error_log("cURL multi exec error: " . curl_multi_strerror($status));
40        }
41
42        // まだ実行中のリクエストがある場合、イベントを待機してCPU使用率を抑えます。
43        // curl_multi_select は、cURLアクティビティがあるか、またはタイムアウトするまでブロックします。
44        if ($running > 0) {
45            curl_multi_select($mh);
46        }
47    } while ($running > 0); // 実行中のハンドルがなくなるまでループを続けます
48
49    $results = [];
50    // 全てのリクエストが完了した後、各cURLハンドルから結果を取得し、リソースを解放します。
51    foreach ($chHandles as $handleInfo) {
52        $url = $handleInfo['url'];
53        $ch = $handleInfo['handle'];
54
55        $response = curl_multi_getcontent($ch); // レスポンスボディを取得
56
57        if ($response === false) {
58            $results[$url] = 'エラー: ' . curl_error($ch);
59        } else {
60            $results[$url] = $response;
61        }
62
63        curl_multi_remove_handle($mh, $ch); // マルチハンドルから個々のcURLハンドルを削除
64        curl_close($ch); // 個々のcURLハンドルを閉じ、リソースを解放
65    }
66
67    curl_multi_close($mh); // マルチcURLハンドルを閉じ、リソースを解放
68
69    return $results;
70}
71
72// --- サンプルコードの実行例 ---
73
74// CURLKHMATCH_MISMATCH は、cURL拡張機能の一部として存在する定数です。
75// これはSSHプロトコル利用時にホストキーの不一致を示す整数値 (int) です。
76// 今回のHTTP GETリクエストの例では直接使用されませんが、その存在と値を確認できます。
77echo "CURLKHMATCH_MISMATCH の値: " . CURLKHMATCH_MISMATCH . PHP_EOL;
78
79// 取得したいURLのリスト
80$urlsToFetch = [
81    'https://httpbin.org/get?param=hello',     // シンプルなGETリクエスト
82    'https://www.example.com/',                // 標準的なウェブサイト
83    'https://httpbin.org/delay/2',             // 2秒の遅延が発生するリクエスト
84    'https://invalid.example.com/',            // 存在しないURL (エラーになる可能性あり)
85];
86
87echo "--- 並行cURLリクエストの実行開始 ---" . PHP_EOL;
88$startTime = microtime(true); // 処理開始時刻を記録
89
90$responses = performMultiCurlRequests($urlsToFetch); // 関数を実行して並行リクエスト処理
91
92$endTime = microtime(true); // 処理終了時刻を記録
93echo "--- 並行cURLリクエストの実行完了 (所要時間: " . round($endTime - $startTime, 2) . "秒) ---" . PHP_EOL;
94
95// 各URLからのレスポンス結果を表示
96foreach ($responses as $url => $content) {
97    echo PHP_EOL . "URL: " . $url . PHP_EOL;
98    if (str_starts_with($content, 'エラー:')) {
99        echo "  " . $content . PHP_EOL; // エラーメッセージを表示
100    } else {
101        // レスポンスが長い場合は、その長さと内容の抜粋のみを表示します。
102        echo "  レスポンスの長さ: " . strlen($content) . "バイト" . PHP_EOL;
103        echo "  内容の抜粋: " . substr($content, 0, 150) . "..." . PHP_EOL;
104    }
105}
106

このサンプルコードは、PHPのcURL拡張機能を利用して、複数のURLに対するネットワークリクエストを並行して実行し、その結果を効率的に取得する方法を示しています。これにより、個々のリクエストを順番に処理するよりも、全体の処理時間を大幅に短縮できるため、システムエンジニアを目指す初心者の方が、多くの外部サービスとの連携が必要なシステム開発において、ネットワーク処理のボトルネックを解消する基本的な手法を学ぶのに役立ちます。

主要な関数であるperformMultiCurlRequestsは、引数としてリクエスト対象のURLの配列(array<string> $urls)を受け取ります。この関数内では、まずcurl_multi_init()でマルチcURLハンドルを初期化し、次に各URLに対して個別のcURLハンドルを設定してマルチハンドルに追加します。その後、curl_multi_exec()curl_multi_select()を組み合わせたループ処理によって、実行中のリクエストがなくなるまで並行してデータ転送を続けます。全てのリクエストが完了すると、curl_multi_getcontent()で各ハンドルからレスポンスボディやエラー情報を取得し、最終的にすべてのリソースを解放します。戻り値は、各URLをキーとし、そのレスポンスボディまたはエラーメッセージを値とする連想配列(array<string, string|false>)です。

なお、CURLKHMATCH_MISMATCHはcURL拡張機能で定義されている定数の一つで、SSHプロトコル利用時にホストキーがサーバーと不一致であることを示す整数値(int)です。このサンプルコードはHTTP/HTTPSリクエストを扱っているため直接は使用されていませんが、cURL拡張機能には多様な定数が存在することを示しています。このコードを通じて、PHPで複数のネットワーク通信を効率的に扱うための基礎を習得できます。

このサンプルコードは、PHP 8でcurl_multi関数群を利用し、複数のHTTPリクエストを並行して効率的に処理する方法を示しています。CURLKHMATCH_MISMATCH定数は、SSH接続時のホストキー不一致を示すものであり、今回のHTTPリクエスト処理には直接関係しませんが、cURL拡張機能の一部としてその存在を確認できます。並行処理はネットワークI/Oを効率化しますが、一度に処理するリクエスト数が増えると、ターゲットサーバーへの負荷やスクリプトのメモリ消費が増大する可能性があります。curl_multi_execループ内のcurl_multi_selectは、CPU使用率を抑えるために重要です。エラー発生時はcurl_error()で詳細を確認し、本番環境ではより堅牢なエラー処理を実装しましょう。処理終了時には、個々のcURLハンドルとマルチハンドル両方のリソースを確実に解放することが重要です。

PHP curl_multi_select による非同期URL取得

1<?php
2
3/**
4 * CURLマルチハンドルを使用して複数のHTTPリクエストを非同期で実行するサンプルコード。
5 *
6 * システムエンジニアを目指す初心者向けに、curl_multi_select の基本的な使い方と、
7 * CURLKHMATCH_MISMATCH のような定数の存在を分かりやすく示します。
8 *
9 * @param array<string> $urls 取得するURLの配列
10 * @return array<string, array{http_code: int, content: string|null, error: string}> 各URLの取得結果
11 * @throws RuntimeException CURLマルチハンドルの初期化に失敗した場合
12 */
13function fetchMultipleUrlsAsync(array $urls): array
14{
15    $results = [];
16
17    // CURLマルチハンドルを初期化します。これにより、複数のCURLリクエストを同時に管理できます。
18    $mh = curl_multi_init();
19    if ($mh === false) {
20        throw new RuntimeException('Failed to initialize curl_multi_init.');
21    }
22
23    $chs = []; // 個々のCURLハンドルを格納する配列
24    foreach ($urls as $key => $url) {
25        // 各URLに対してCURLハンドルを作成します。
26        $ch = curl_init($url);
27        if ($ch === false) {
28            error_log("Failed to initialize curl for URL: {$url}");
29            continue; // このURLはスキップして次のURLへ
30        }
31
32        // CURLオプションを設定します。
33        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 結果を文字列として返します。
34        curl_setopt($ch, CURLOPT_HEADER, false);      // レスポンスヘッダーを含めません。
35        curl_setopt($ch, CURLOPT_TIMEOUT, 10);        // タイムアウトを10秒に設定します。
36
37        // `CURLKHMATCH_MISMATCH` は、PHPのCURL拡張機能に存在する整数定数です。
38        // これは、SSH/SCPなどのSecure Shellプロトコルでホストキーの検証を行った際に、
39        // 既知のホストキーとの不一致が発生したことを示す値です。
40        // HTTPリクエストでは直接使用されませんが、CURLが提供する多様な機能と定数の一例として参照されます。
41        // この定数の値は int 型です(例: PHP 8では通常2)。
42        // 実際のSSHホストキー検証ロジックでは、`CURLOPT_SSH_HOSTKEYFUNCTION` コールバック内で
43        // このような定数を返すことで、ホストキーの不一致を通知します。
44        // 例: echo "CURLKHMATCH_MISMATCH constant value: " . CURLKHMATCH_MISMATCH . "\n";
45
46        // 作成したCURLハンドルをマルチハンドルに追加します。
47        curl_multi_add_handle($mh, $ch);
48        $chs[$key] = $ch; // 後で結果を取得するためにハンドルを保存します。
49    }
50
51    $active = null; // アクティブなCURLハンドルの数を保持する変数
52
53    // すべてのリクエストが完了するまでループを続けます。
54    do {
55        // curl_multi_exec: マルチハンドルを継続的に実行し、処理可能なCURLハンドルを処理します。
56        // $active には現在アクティブなハンドルの数が格納されます。
57        // この関数は非ブロックで、すぐに制御を返します。
58        $mrc = curl_multi_exec($mh, $active);
59
60        // curl_multi_exec がまだ処理すべきハンドルがあることを示している場合、再度実行します。
61        if ($mrc === CURLM_CALL_MULTI_PERFORM) {
62            continue;
63        }
64
65        // curl_multi_select: ソケットアクティビティを監視し、イベントが発生するまで待機します。
66        // データが利用可能になるか、タイムアウト(ここでは1秒)するまでブロックします。
67        // これにより、CPUを無駄に消費することなく、効率的に待機できます。
68        if ($active > 0) {
69            $select_result = curl_multi_select($mh, 1.0); // 1秒タイムアウトを設定
70
71            if ($select_result === -1) {
72                // selectコールにエラーがあった場合、CPUを占有しないように短いスリープを入れます。
73                // これはまれなケースで、ネットワークの問題やOSの制限が原因で発生することがあります。
74                usleep(100);
75            }
76        }
77
78        // 完了したハンドルがあるか確認し、その結果を取得します。
79        while ($info = curl_multi_info_read($mh)) {
80            $ch = $info['handle'];
81            $url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
82            $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
83            $error = curl_error($ch);
84            // エラーがない場合のみコンテンツを取得
85            $content = ($error === '') ? curl_multi_getcontent($ch) : null;
86
87            $results[$url] = [
88                'http_code' => $http_code,
89                'content'   => $content,
90                'error'     => $error,
91            ];
92
93            // 完了したハンドルをマルチハンドルから削除します。
94            curl_multi_remove_handle($mh, $ch);
95            curl_close($ch); // 個別のCURLハンドルをクローズします。
96        }
97
98    } while ($active > 0); // アクティブなハンドルがなくなるまでループを続けます。
99
100    // すべてのリクエストが完了したら、マルチハンドルをクローズします。
101    curl_multi_close($mh);
102
103    return $results;
104}
105
106// サンプル使用例
107$urlsToFetch = [
108    'https://www.google.com',
109    'https://www.bing.com',
110    'https://invalid.url.example.com' // 存在しないURLの例(エラーケースを示すため)
111];
112
113echo "Fetching URLs asynchronously...\n";
114$fetchedResults = fetchMultipleUrlsAsync($urlsToFetch);
115
116foreach ($fetchedResults as $url => $data) {
117    echo "--- URL: {$url} ---\n";
118    if (empty($data['error'])) {
119        echo "Status: SUCCESS\n";
120        echo "HTTP Code: {$data['http_code']}\n";
121        // 取得したコンテンツの一部を表示(長いコンテンツは省略)
122        // echo "Content Snippet: " . substr($data['content'], 0, 100) . "...\n";
123    } else {
124        echo "Status: FAILED\n";
125        echo "Error: {$data['error']}\n";
126        echo "HTTP Code: {$data['http_code']} (HTTPエラーの場合)\n";
127    }
128    echo "\n";
129}
130
131// CURLKHMATCH_MISMATCH 定数の値と型を確認(参考情報)
132echo "----------------------------------------\n";
133echo "Reference Information for CURLKHMATCH_MISMATCH constant:\n";
134echo "Type: " . gettype(CURLKHMATCH_MISMATCH) . "\n"; // 定数の型を表示
135echo "Value: " . CURLKHMATCH_MISMATCH . "\n";     // 定数の値を表示 (PHP 8では通常2)
136
137?>

このPHPサンプルコードは、curl_multi_init関数を用いて複数のHTTPリクエストを非同期に実行し、各URLから効率的にデータを取得する方法を示しています。まず、個々のURLに対してcurl_initでCURLハンドルを作成し、CURLOPT_RETURNTRANSFERなどの必要なオプションを設定します。これらの個別のCURLハンドルは、curl_multi_add_handleによりcurl_multi_initで作成されたマルチハンドルに追加され、同時に管理されます。

リクエストの実行はdo-whileループ内で行われ、curl_multi_execがリクエストの進行状況を管理し、現在アクティブなハンドル数を更新します。特に重要なのがcurl_multi_select関数です。これは、ソケットアクティビティを監視し、データが利用可能になるか指定されたタイムアウト(この例では1秒)が経過するまで、プログラムの実行を効率的に待機させます。これにより、CPUを無駄に消費することなく、ネットワークI/O処理の完了を待つことが可能です。curl_multi_selectは、監視対象のソケットで発生したイベントの数を整数で返し、エラー時には-1を返します。

完了したリクエストの結果はcurl_multi_info_readで取得され、その後にcurl_multi_remove_handleでマルチハンドルから、curl_closeで個々のCURLハンドルがクローズされます。

コード中に登場するCURLKHMATCH_MISMATCHは、PHPのCURL拡張機能に存在する定数で、引数を持たず整数型(int)の値を返します。これは、Secure Shell(SSH/SCP)プロトコルのホストキー検証時に、既知のキーとの不一致が発生したことを示す際に使用されます。このサンプルコードではHTTPリクエストを扱っているため直接使用されませんが、CURLライブラリが提供する幅広い機能と定数の一例として提示されています。

このような非同期処理は、大量のWebページ取得や複数のAPIコールを並行して行う際に、アプリケーションの応答性を高める上で非常に有効な技術です。

CURLKHMATCH_MISMATCHは、主にSSHプロトコルでのホストキー不一致を示す定数であり、今回のHTTPリクエスト処理では直接利用されません。CURL拡張機能には用途に応じた多数の定数があるため、文脈を理解して使い分けることが重要です。サンプルコードの核となるcurl_multi_selectは、複数のHTTPリクエストを非同期で効率良く処理するため、データが利用可能になるまで待機し、CPUの無駄な消費を防ぐ役割を担っています。curl_multi_execと連携させ、リクエストの進捗を継続的に確認しながら処理を進めるのが基本です。また、curl_initcurl_multi_initの初期化チェック、curl_errorによる通信エラーの確認、そしてcurl_multi_closecurl_closeによるリソースの確実な解放は、堅牢な非同期処理を実装する上で不可欠ですので、必ず実施するようにしてください。

関連コンテンツ

関連IT用語

関連プログラミング言語