【PHP8.x】stream_get_contents関数の使い方

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

作成日: 更新日:

基本的な使い方

stream_get_contents関数は、オープンされたストリーム(データ源)から残りのデータをすべて文字列として読み込む関数です。この関数は、ファイル、ネットワーク接続、またはその他のデータストリームといったさまざまなソースから、現在ストリームポインタが指す位置から終端までのデータを効率的に取得し、単一の文字列としてメモリに格納します。例えば、fopen()関数で開かれたファイルの内容を一度にすべて読み込んだり、ソケット接続から送られてきたデータ全体を受け取ったりする際に大変役立ちます。

第一引数には、読み込み元のストリームリソースを指定します。これはfopen()fsockopen()などの関数によって作成されたものです。オプションの第二引数で読み込む最大バイト数を指定でき、さらにオプションの第三引数で読み込みを開始するオフセット(ストリームの先頭からのバイト位置)を設定することも可能です。これらの引数を利用することで、データの読み込み範囲を細かく制御できます。

成功すると読み込んだデータを文字列として返し、エラーが発生した場合や読み込みが完了する前に問題があった場合はfalseを返します。特に大きなデータを扱う際には、メモリを大量に消費する可能性があるため注意が必要です。

構文(syntax)

1<?php
2
3$filePath = 'example.txt';
4file_put_contents($filePath, 'Hello, PHP Stream!');
5
6$stream = fopen($filePath, 'r');
7if ($stream) {
8    $contents = stream_get_contents($stream);
9    echo $contents;
10    fclose($stream);
11}
12
13unlink($filePath); // 例で作成したファイルを削除

引数(parameters)

resource $stream, int $length = -1, int $offset = -1

  • resource $stream: 読み込み対象のストリームリソース
  • int $length = -1: 読み込む最大バイト数。-1を指定すると、ストリームの終端まで読み込みます。
  • int $offset = -1: ストリームのどこから読み込みを開始するかを指定するオフセット。-1を指定すると、現在のストリーム位置から読み込みます。

戻り値(return)

string|false

ストリームから読み取った内容を文字列として返します。読み取りに失敗した場合は false を返します。

サンプルコード

PHP stream_get_contentsでタイムアウト制御して読み込む

1<?php
2
3/**
4 * ストリームから内容を読み込み、タイムアウトを設定する例
5 *
6 * @param resource $stream 読み込むストリームリソース
7 * @param int $timeout タイムアウト時間(秒)
8 * @return string|false 読み込んだ内容。失敗した場合は false。
9 */
10function readStreamWithTimeout($stream, int $timeout): string|false
11{
12    // ストリームのメタデータを取得
13    $meta = stream_get_meta_data($stream);
14
15    // ストリームがタイムアウトをサポートしているか確認
16    if ($meta['timed_out']) {
17        error_log("ストリームは既にタイムアウトしています。");
18        return false;
19    }
20
21    // ストリームを選択し、タイムアウトを監視
22    $read = [$stream];
23    $write = null;
24    $except = null;
25
26    // ストリームが読み込み可能になるか、タイムアウトになるまで待機
27    $num_streams = stream_select($read, $write, $except, $timeout);
28
29    // タイムアウトした場合
30    if ($num_streams === 0) {
31        error_log("タイムアウトしました。");
32        return false;
33    }
34
35    // エラーが発生した場合
36    if ($num_streams === false) {
37        error_log("ストリーム選択中にエラーが発生しました。");
38        return false;
39    }
40
41    // ストリームから内容を読み込む
42    $content = stream_get_contents($stream);
43
44    // 読み込みに失敗した場合
45    if ($content === false) {
46        error_log("ストリームから内容の読み込みに失敗しました。");
47        return false;
48    }
49
50    return $content;
51}
52
53// テスト用のストリームを作成 (例:ファイルから)
54$file_path = 'test.txt';
55$stream = fopen($file_path, 'r');
56
57// ファイルが存在しない場合は作成
58if (!file_exists($file_path)) {
59    file_put_contents($file_path, "This is a test file.\nThis is the second line.");
60}
61
62if ($stream) {
63    // タイムアウト時間を設定 (秒)
64    $timeout = 2;
65
66    // ストリームから内容を読み込む
67    $content = readStreamWithTimeout($stream, $timeout);
68
69    if ($content !== false) {
70        echo "ストリームから読み込んだ内容:\n";
71        echo $content;
72    } else {
73        echo "ストリームの読み込みに失敗しました。\n";
74    }
75
76    // ストリームを閉じる
77    fclose($stream);
78} else {
79    echo "ストリームを開けませんでした。\n";
80}
81

このサンプルコードは、stream_get_contents関数を使用してストリームから内容を読み込む際に、タイムアウト処理を組み込む方法を示しています。

readStreamWithTimeout関数は、指定されたストリームリソースからデータを読み込みます。引数としてストリームリソース $stream とタイムアウト時間 $timeout (秒単位の整数値)を受け取ります。

この関数内では、まず stream_get_meta_data 関数を用いてストリームのメタ情報を取得し、ストリームが既にタイムアウトしていないかを確認します。次に、stream_select 関数を使用して、ストリームが読み込み可能になるまで、指定されたタイムアウト時間だけ待機します。stream_select関数は、第一引数に監視対象の読み込み可能なストリームを配列で指定します。

タイムアウトが発生した場合、またはストリームの選択中にエラーが発生した場合は、falseを返します。正常に読み込み可能になった場合は、stream_get_contents 関数を用いてストリームから内容を読み込み、その結果を返します。stream_get_contents関数は、ストリームから残りのデータをすべて読み込み、文字列として返します。読み込みに失敗した場合は false を返します。

サンプルコードでは、テストとしてファイルからストリームを作成し、readStreamWithTimeout 関数を使用して内容を読み込んでいます。読み込んだ内容、またはエラーメッセージを画面に出力し、最後にストリームを閉じています。この例では、タイムアウト処理を実装することで、ストリームからの読み込みが長時間停止した場合でも、プログラムが応答しなくなるのを防ぐことができます。

stream_get_contents関数とタイムアウト処理のサンプルコードに関する注意点です。stream_select関数でタイムアウトを監視する前に、ストリームが既にタイムアウトしていないか確認することが重要です。タイムアウト値は、処理内容に応じて適切な値を設定してください。また、stream_select関数は、ストリームが読み込み可能になるまで待機するため、ブロッキング処理となる可能性があることに注意が必要です。エラー処理を丁寧に行い、stream_selectstream_get_contentsそれぞれの戻り値を適切に評価してください。最後に、ストリームを使い終わったら必ずfcloseで閉じるようにしましょう。リソースリークを防ぐために重要な処理です。

関連コンテンツ

【PHP8.x】stream_get_contents関数の使い方 | いっしー@Webエンジニア