【PHP8.x】CURLOPT_INFILE定数の使い方
CURLOPT_INFILE定数の使い方について、初心者にもわかりやすく解説します。
基本的な使い方
CURLOPT_INFILE定数は、PHPのcURL拡張機能において、HTTPリクエストでサーバーへ送信するデータを、特定のファイルから読み込むように指示するためのオプションを表す定数です。この定数を利用することで、ファイルの内容をあらかじめPHPのメモリに全て読み込むことなく、直接ファイルポインタからデータを読み出し、ネットワークを通じて送信できます。
特に、大容量のファイルをアップロードする際に、システムのメモリ使用量を効果的に抑制し、効率的なデータ転送を実現するために非常に重要です。例えば、ユーザーがウェブサイト経由で大きな画像ファイルやドキュメントをアップロードする機能を実現する際に、PHPスクリプトのメモリが溢れることなく安定した運用が可能になります。
curl_setopt()関数でこのオプションを設定する際には、fopen()関数などによって開かれたファイルのファイルポインタ(リソース)を値として指定します。通常、cURLが送信するデータの正確なサイズを把握できるように、CURLOPT_INFILESIZEオプションと合わせて設定することが強く推奨されます。これにより、cURLは指定されたファイルから必要なバイト数だけを読み取り、サーバーへ送信する処理を行います。この機能はPHP 8のcURL拡張機能で利用可能です。
構文(syntax)
1<?php 2$ch = curl_init(); 3$fileHandle = fopen('path/to/local/file.txt', 'r'); 4 5curl_setopt($ch, CURLOPT_INFILE, $fileHandle); 6?>
引数(parameters)
引数なし
引数はありません
戻り値(return)
戻り値なし
戻り値はありません
サンプルコード
PHP cURLでHTTPSファイルアップロードと証明書検証
1<?php 2 3/** 4 * 安全なHTTPS経由でファイルをアップロードするCURLリクエストを実行します。 5 * 6 * この関数は、指定されたファイルをターゲットURLにアップロードします。 7 * HTTP PUTリクエストを想定しており、接続はHTTPSを使用します。 8 * SSL証明書の検証にはCURLOPT_CAINFOで指定されたCA証明書バンドルを使用します。 9 * 10 * @param string $targetUrl ファイルをアップロードするHTTPSエンドポイントのURL (例: "https://example.com/upload.php") 11 * @param string $filePathToUpload アップロードするファイルのローカルパス (例: "/path/to/my/local_file.txt") 12 * @param string $caBundlePath 信頼できるCA証明書バンドルファイルのパス (例: "/etc/ssl/certs/ca-certificates.crt" またはダウンロードした "cacert.pem") 13 * @return array|false 成功した場合はCURLの情報、ヘッダー、ボディを含む配列、失敗した場合はfalse 14 */ 15function uploadFileSecurely(string $targetUrl, string $filePathToUpload, string $caBundlePath): array|false 16{ 17 // アップロードするファイルの存在チェックとオープン 18 if (!file_exists($filePathToUpload) || !is_readable($filePathToUpload)) { 19 echo "エラー: アップロードするファイルが見つからないか、読み取れません: " . $filePathToUpload . PHP_EOL; 20 return false; 21 } 22 23 $fileHandle = fopen($filePathToUpload, 'r'); 24 if ($fileHandle === false) { 25 echo "エラー: ファイルをオープンできませんでした: " . $filePathToUpload . PHP_EOL; 26 return false; 27 } 28 29 // CA証明書バンドルファイルの存在チェック 30 if (!file_exists($caBundlePath) || !is_readable($caBundlePath)) { 31 echo "エラー: CA証明書バンドルファイルが見つからないか、読み取れません: " . $caBundlePath . PHP_EOL; 32 fclose($fileHandle); 33 return false; 34 } 35 36 $ch = curl_init(); 37 38 // cURLオプションの設定 39 curl_setopt($ch, CURLOPT_URL, $targetUrl); 40 // ファイルアップロードモードを有効にする (PUTリクエストをシミュレート) 41 curl_setopt($ch, CURLOPT_UPLOAD, true); 42 // アップロード元となるファイルポインタを指定 (CURLOPT_INFILE) 43 // cURLはこのファイルポインタからデータを読み込み、リモートサーバーに送信します。 44 curl_setopt($ch, CURLOPT_INFILE, $fileHandle); 45 // アップロードするファイルのサイズを指定 (必須ではありませんが推奨されます) 46 curl_setopt($ch, CURLOPT_INFILESIZE, filesize($filePathToUpload)); 47 // 戻り値としてレスポンスボディを受け取る 48 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 49 // HTTPヘッダーをレスポンスに含める 50 curl_setopt($ch, CURLOPT_HEADER, true); 51 52 // SSL証明書の検証を有効にする (HTTPS接続のセキュリティを確保するため) 53 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); 54 // CA証明書バンドルのパスを指定 (CURLOPT_CAINFO) 55 // これにより、サーバーから提示されたSSL証明書が、指定されたCAバンドル内の 56 // 信頼できる認証局によって署名されているかをcURLが検証します。 57 curl_setopt($ch, CURLOPT_CAINFO, $caBundlePath); 58 // ホスト名の検証を有効にする (サーバーのホスト名が証明書と一致するか確認) 59 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); 60 61 // cURLリクエストの実行 62 $response = curl_exec($ch); 63 64 // エラーチェック 65 if (curl_errno($ch)) { 66 $errorMsg = curl_error($ch); 67 echo "CURLエラー: " . $errorMsg . PHP_EOL; 68 // リソースのクリーンアップ 69 fclose($fileHandle); 70 curl_close($ch); 71 return false; 72 } 73 74 // レスポンスの解析 (HTTPヘッダーとボディを分離) 75 $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE); 76 $responseHeader = substr($response, 0, $headerSize); 77 $responseBody = substr($response, $headerSize); 78 79 // CURL情報を取得 80 $curlInfo = curl_getinfo($ch); 81 82 // リソースのクリーンアップ 83 fclose($fileHandle); 84 curl_close($ch); 85 86 // 結果を返す 87 return [ 88 'info' => $curlInfo, 89 'header' => $responseHeader, 90 'body' => $responseBody, 91 ]; 92} 93 94// -------------------------------------------------------------------------------- 95// サンプルコードの実行例 96// -------------------------------------------------------------------------------- 97 98// 1. アップロード用ダミーファイルの作成 99$uploadFileName = 'example_upload.txt'; 100file_put_contents($uploadFileName, 'This is a test file for upload via PHP cURL. Hello PHP!'); 101echo "アップロード用ダミーファイル '" . $uploadFileName . "' を作成しました。" . PHP_EOL; 102 103// 2. ダミーのCA証明書バンドルファイルを作成 104// 実際のシステムでは、信頼できるCAから提供される証明書バンドル (例: cacert.pem) を使用してください。 105// curl.se/docs/caextract.html から最新の cacert.pem をダウンロードできます。 106// または、OSが提供するCA証明書バンドルのパスを指定します。 107// (例: Linuxなら "/etc/ssl/certs/ca-certificates.crt", macOSなら "/etc/ssl/cert.pem") 108$caBundleFileName = 'dummy_cacert.pem'; 109// これはダミーの証明書データです。実際のSSL検証には有効ではありません。 110// ファイルが存在しない場合にエラーにならないよう、一時的に作成しています。 111file_put_contents($caBundleFileName, <<<EOD 112-----BEGIN CERTIFICATE----- 113MIIDrzCCApWgAwIBAgIQD2RzFz9N2f7h1z8F52F7ATANBgkqhkiG9w0BAQsFADBL 114MQswCQYDVQQGEwJVUzEiMCAGA1UEChMJU3RhcmZpZWxkMR0wGwYDVQQDExRTdGFy 115ZmllbGQgUm9vdCBDQTIwMDQwHhcNMjMwMzI3MTEyOTU2WhcNMzMwMzI3MTEyOTU2 116WjBLMQswCQYDVQQGEwJVUzEiMCAGA1UEChMJU3RhcmZpZWxkMR0wGwYDVQQDExRT 117dGFyZmllbGQgUm9vdCBDQTIwMDQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEC 118AoIBAQDQdJbW8eT6o8O6q1lYf8x5d8sF2S... 119-----END CERTIFICATE----- 120EOD); 121echo "ダミーCA証明書バンドルファイル '" . $caBundleFileName . "' を作成しました。実際のCA証明書を使用してください。" . PHP_EOL; 122 123// 3. ターゲットURLの設定 124// このURLは、ファイルをアップロードできる有効なHTTPSエンドポイントである必要があります。 125// 以下のURLは架空のものです。実際に動作させるには、有効なアップロードサーバーを用意してください。 126$targetUrl = 'https://httpbin.org/put'; // httpbin.org はPUTリクエストをテストできるサービス 127 128echo "ファイルを " . $targetUrl . " へ安全にアップロードを試行します..." . PHP_EOL; 129 130// 関数を実行 131$result = uploadFileSecurely($targetUrl, $uploadFileName, $caBundleFileName); 132 133if ($result) { 134 echo "ファイルアップロードリクエストを送信しました。" . PHP_EOL; 135 echo "HTTPステータスコード: " . $result['info']['http_code'] . PHP_EOL; 136 echo "レスポンスヘッダー:" . PHP_EOL . $result['header'] . PHP_EOL; 137 echo "レスポンスボディ:" . PHP_EOL . $result['body'] . PHP_EOL; 138} else { 139 echo "ファイルアップロードに失敗しました。" . PHP_EOL; 140 echo "上記のエラーメッセージを確認してください。" . PHP_EOL; 141} 142 143// 4. ダミーファイルのクリーンアップ 144if (file_exists($uploadFileName)) { 145 unlink($uploadFileName); 146 echo "アップロード用ダミーファイル '" . $uploadFileName . "' を削除しました。" . PHP_EOL; 147} 148if (file_exists($caBundleFileName)) { 149 unlink($caBundleFileName); 150 echo "ダミーCA証明書バンドルファイル '" . $caBundleFileName . "' を削除しました。" . PHP_EOL; 151}
このPHPサンプルコードは、cURLライブラリを用いてHTTPS経由でファイルを安全にアップロードする方法を提示しています。uploadFileSecurely関数は、指定されたファイルをHTTP PUTメソッドでターゲットURLへ送信します。
特に重要なのはCURLOPT_INFILEとCURLOPT_CAINFOです。
CURLOPT_INFILEは、アップロードするファイルの内容をcURLに提供するためのファイルポインタを指定するオプションです。cURLは、このファイルポインタからデータを読み込み、それをリモートサーバーへ送信することでファイルアップロードを実行します。ファイルサイズを明示するCURLOPT_INFILESIZEとの併用が推奨されます。
CURLOPT_CAINFOは、HTTPS通信におけるSSL証明書の検証に不可欠なオプションです。このオプションに信頼できるCA(認証局)証明書バンドルファイルのパスを指定することで、cURLはサーバーから提示されたSSL証明書が本物であるかを検証し、通信の信頼性と安全性を高めます。
また、CURLOPT_UPLOADでアップロードモードを有効化し、CURLOPT_SSL_VERIFYPEERやCURLOPT_SSL_VERIFYHOSTでSSL証明書とホスト名の厳格な検証を強制しています。
関数はアップロード元のファイルパス、ターゲットURL、CA証明書バンドルのパスを引数として受け取り、成功時にはCURL情報、ヘッダー、ボディを含む配列を、失敗時にはfalseを返します。このコードは、セキュアなファイルアップロード実装の基礎を示すものです。
このサンプルコードでは、ファイルをアップロードする際にCURLOPT_INFILEにfopenで開いたファイルハンドルを指定します。ファイルパスを直接渡すわけではない点に注意し、CURLOPT_INFILESIZEでファイルサイズも設定すると安定します。特に重要なのは、HTTPS接続のセキュリティを確保するためCURLOPT_CAINFOで信頼できるCA証明書バンドルのパスを正確に指定することです。サンプルコードのダミー証明書はテスト用であり、本番環境では絶対に使用しないでください。CURLOPT_SSL_VERIFYPEERとCURLOPT_SSL_VERIFYHOSTは必ず有効にし、脆弱性を避けてください。ファイルのオープン失敗やcURLのエラーは適切に処理し、使用後のリソース (fopenのハンドルやcURLリソース) は必ず解放しましょう。これらの点を守ることで、安全で堅牢なファイルアップロードが実現できます。