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

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

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

作成日: 更新日:

基本的な使い方

CURLOPT_PROGRESSFUNCTION定数は、PHPのcURL拡張機能において、ネットワークを通じたデータ転送の進捗状況をリアルタイムで監視するためのコールバック関数を設定するために使用される定数です。この定数を利用することで、HTTPリクエストなどによるファイルダウンロードやアップロードといった、時間のかかる通信処理中に、現在の転送状況を把握し、それに応じた動作をプログラムに組み込むことが可能になります。

具体的には、curl_setopt()関数を用いてこの定数を設定し、その値として、転送中に定期的に呼び出されるコールバック関数を指定します。このコールバック関数には、転送される予定の合計ダウンロードバイト数、現時点でダウンロード済みのバイト数、転送される予定の合計アップロードバイト数、現時点でアップロード済みのバイト数といった情報が引数として渡されます。これらの情報を用いることで、アプリケーションにプログレスバーを表示してユーザーに進行状況を伝えたり、転送速度に基づいて処理を最適化したりすることができます。

また、設定したコールバック関数がゼロ以外の値を返した場合、cURLによる現在のデータ転送は即座に中断されます。この機能は、ユーザーが転送をキャンセルしたい場合や、特定の条件が満たされたときに自動的に転送を停止させたい場合など、柔軟なエラーハンドリングやユーザー操作による制御を実装する上で非常に有用です。この定数は、長時間のネットワーク通信を伴うアプリケーションにおいて、ユーザーエクスペリエンスを向上させるための重要なツールとなります。

構文(syntax)

1<?php
2
3$ch = curl_init('http://example.com/some_file.zip');
4
5$progressCallback = function (
6    $curlHandle,
7    $totalDownloadExpectedBytes,
8    $downloadedBytes,
9    $totalUploadExpectedBytes,
10    $uploadedBytes
11) {
12    return 0;
13};
14
15curl_setopt($ch, CURLOPT_NOPROGRESS, false);
16curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, $progressCallback);
17
18curl_exec($ch);
19curl_close($ch);
20
21?>

引数(parameters)

引数なし

引数はありません

戻り値(return)

戻り値なし

戻り値はありません

サンプルコード

PHP cURLによるダウンロード進捗表示

1<?php
2
3/**
4 * 指定されたURLからファイルをダウンロードし、進行状況をリアルタイムで表示します。
5 *
6 * @param string $url ダウンロードするファイルのURL。
7 * @return bool ダウンロードが成功した場合は true、失敗した場合は false。
8 */
9function downloadFileWithProgress(string $url): bool
10{
11    // cURLセッションを初期化します。
12    $ch = curl_init();
13
14    if ($ch === false) {
15        echo "エラー: cURLセッションの初期化に失敗しました。\n";
16        return false;
17    }
18
19    // ダウンロードするファイルのURLを設定します。
20    curl_setopt($ch, CURLOPT_URL, $url);
21
22    // CURLOPT_NOPROGRESS を false に設定すると、cURLは進行状況コールバック関数を呼び出します。
23    // true の場合、コールバック関数は呼ばれません。
24    curl_setopt($ch, CURLOPT_NOPROGRESS, false);
25
26    /**
27     * CURLOPT_PROGRESSFUNCTION で設定するコールバック関数。
28     * この関数は、データ転送中にcURLによって定期的に呼び出され、
29     * 進行状況の情報をアプリケーションに提供します。
30     *
31     * @param resource $ch         cURLハンドル
32     * @param int      $downloadSize ダウンロードされる合計サイズ(バイト)
33     * @param int      $downloaded   現在までにダウンロードされたバイト数
34     * @param int      $uploadSize   アップロードされる合計サイズ(バイト)
35     * @param int      $uploaded     現在までにアップロードされたバイト数
36     * @return int 0を返すと転送を続行し、0以外の値を返すと転送を中断します。
37     */
38    curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, function (
39        $ch,
40        int $downloadSize,
41        int $downloaded,
42        int $uploadSize,
43        int $uploaded
44    ) {
45        // ダウンロードサイズが0の場合(例えば、ヘッダー情報のみの転送など)、
46        // 進捗率を計算できないため、ここでは何もしません。
47        if ($downloadSize > 0) {
48            $percentage = ($downloaded / $downloadSize) * 100;
49            // 現在の行を上書きするために "\r" (キャリッジリターン) を使用します。
50            // これにより、ダウンロードの進捗が同じ行で更新され続けます。
51            printf(
52                "ダウンロード中: %.2f%% (%.2fMB / %.2fMB)\r",
53                $percentage,
54                $downloaded / (1024 * 1024), // バイトをメガバイトに変換
55                $downloadSize / (1024 * 1024) // バイトをメガバイトに変換
56            );
57            // バッファをフラッシュして、すぐに画面に出力します。
58            ob_flush();
59            flush();
60        }
61        // 転送を継続するために 0 を返します。
62        return 0;
63    });
64
65    // ダウンロードしたデータをどこに書き込むかを設定します。
66    // 今回は進行状況の表示が主な目的のため、
67    // ダウンロードされたデータをディスクに保存せず、破棄します。
68    // Linux/macOS では '/dev/null'、Windows では 'nul' を使用します。
69    $nullDevice = (PHP_OS_FAMILY === 'Windows') ? 'nul' : '/dev/null';
70    $fp = fopen($nullDevice, 'w');
71
72    if ($fp === false) {
73        echo "エラー: 一時ファイル(またはヌルデバイス)を開けませんでした。\n";
74        curl_close($ch);
75        return false;
76    }
77    // CURLOPT_FILE を設定して、ダウンロードデータを指定したファイルポインタに書き込みます。
78    curl_setopt($ch, CURLOPT_FILE, $fp);
79
80    // cURLセッションを実行し、ファイルダウンロードを開始します。
81    $success = curl_exec($ch);
82
83    // ファイルポインタを閉じます。
84    fclose($fp);
85
86    // エラーが発生した場合はメッセージを表示します。
87    if ($success === false) {
88        echo "\nエラー: ダウンロード中に問題が発生しました: " . curl_error($ch) . "\n";
89    } else {
90        echo "\nダウンロード完了。\n"; // 進捗表示の後に改行して完了メッセージを表示
91    }
92
93    // cURLセッションを閉じ、リソースを解放します。
94    curl_close($ch);
95
96    return (bool)$success;
97}
98
99// 使用例: PHPの配布ファイル(約12MBのtarball)をダウンロードします。
100$targetUrl = 'https://www.php.net/distributions/php-8.0.0.tar.gz';
101echo "ファイルダウンロードを開始します: " . $targetUrl . "\n";
102
103downloadFileWithProgress($targetUrl);
104
105?>

CURLOPT_PROGRESSFUNCTIONは、PHPでcURLを使用してデータ転送を行う際に、その進行状況をリアルタイムでアプリケーションに通知するためのコールバック関数を設定する定数です。この定数に設定された関数は、データが転送されるたびにcURLによって定期的に呼び出されます。

サンプルコードでは、指定されたURLからファイルをダウンロードする際の進行状況をコンソールに表示するために利用されています。まず、curl_init()でcURLセッションを開始し、CURLOPT_URLでダウンロード対象のURLを設定します。CURLOPT_NOPROGRESSfalseに設定することで、この進行状況コールバック関数が有効になり、cURLが転送中に設定された関数を呼び出すようになります。

CURLOPT_PROGRESSFUNCTIONに渡すコールバック関数は、cURLハンドル、ダウンロードされる合計サイズ(バイト)、現在までにダウンロードされたバイト数、アップロードされる合計サイズ、現在までにアップロードされたバイト数という5つの引数を受け取ります。これにより、現在のダウンロード進捗率などを計算できます。サンプルでは、これらの情報を使って「ダウンロード中: XX.XX% (X.XXMB / Y.YYMB)」のような形式で進捗を表示し、\r(キャリッジリターン)とob_flush(), flush()を用いて同じ行で表示を更新し続けています。

このコールバック関数は、転送を継続する場合は0を返し、転送を中断したい場合は0以外の値を返します。ダウンロードされたファイルデータ自体は、CURLOPT_FILEオプションで/dev/null(またはWindowsのnul)に書き込むことで破棄されており、純粋に進行状況の表示に特化した例となっています。これにより、ユーザーは長時間のデータ転送処理中でも、現在の状況を正確に把握できるようになります。

CURLOPT_PROGRESSFUNCTIONを利用する際は、必ずCURLOPT_NOPROGRESSfalseに設定してください。これを忘れると進捗コールバック関数が呼び出されません。コールバック関数は、転送を継続するために必ず0を返す必要があります。0以外の値を返すと転送が中断されますので注意が必要です。サンプルコードの進行状況表示はコマンドライン環境に特化したものであり、Webブラウザで同様にリアルタイム表示を行うには異なる技術が必要です。また、ダウンロードデータを実際に保存する場合は、CURLOPT_FILEに適切なファイルポインタを設定してください。エラー処理やリソースの解放は重要ですので、実運用ではより詳細なログ記録や例外処理の実装を検討してください。

関連コンテンツ