【PHP8.x】stream_get_line関数の使い方
stream_get_line関数の使い方について、初心者にもわかりやすく解説します。
基本的な使い方
stream_get_line関数は、ファイルやネットワーク通信など、連続したデータ源(ストリーム)から、指定された長さまで、または特定の区切り文字(デリミタ)が見つかるまでデータを読み込むための関数です。この関数は、大量のデータの中から特定の情報を効率的に抽出したい場合や、レコードごとに区切られたデータを処理する際に特に役立ちます。
例えば、ログファイルから特定の区切り文字で区切られたメッセージを一行ずつ読み込んだり、ネットワークからの受信データを行単位で処理したりする場面で利用されます。データの読み込みはストリームの現在の位置から開始され、指定された最大バイト数に達するか、あるいは終端文字が見つかるまでデータが取得されます。終端文字が見つかった場合、その文字自体は読み込んだ文字列には含まれませんが、ストリームのポインタは終端文字の次へと進みます。
関数は、読み込んだ文字列を返しますが、エラーが発生した場合やストリームの終端に達してこれ以上データが読み込めない場合にはブール値のfalseを返します。これにより、データの読み込み状況を正確に判断し、適切なエラーハンドリングを行うことが可能です。特定の区切り文字を指定できるため、標準的な改行コード以外の区切り文字で構成されるデータ形式にも柔軟に対応できる点が特徴です。
構文(syntax)
1<?php 2$stream = fopen("php://temp", "r+"); // 一時的なストリームリソースを開く 3fwrite($stream, "Sample line one.\nSample line two."); // ストリームにデータを書き込む 4rewind($stream); // ストリームポインタを先頭に戻す 5 6$max_bytes_to_read = 1024; // 読み込む最大バイト数 7$line_ending_delimiter = "\n"; // 行の終端文字 8 9// ストリームから最大バイト数まで、または終端文字までデータを読み込む 10$line_data = stream_get_line($stream, $max_bytes_to_read, $line_ending_delimiter); 11 12fclose($stream); // ストリームを閉じる 13?>
引数(parameters)
resource $stream, int $length, string $ending = ''
- resource $stream: 読み込み対象のストリームリソースを指定します。
- int $length: 読み込む最大バイト数を指定します。
- string $ending = '': 読み込みを終了する区切り文字を指定します。省略時は空文字列で、指定がない場合は指定されたバイト数まで読み込みます。
戻り値(return)
string|false
指定されたストリームから1行を読み込み、文字列として返します。読み込みに失敗した場合はfalseを返します。
サンプルコード
fgetsとstream_get_lineの違いを理解する
1<?php 2 3declare(strict_types=1); 4 5/** 6 * fgets() と stream_get_line() の動作の違いを比較するためのデモンストレーション関数。 7 * 8 * fgets() は一般的に「行末 (改行文字)」までを読み込みます。 9 * 一方、stream_get_line() は第3引数で指定した「任意の区切り文字列」までを読み込むことができます。 10 * この違いは、改行以外の特定のデリミタで区切られたデータをストリームから処理する際に重要です。 11 */ 12function compareStreamReadFunctions(): void 13{ 14 // 比較用のデータ。改行(\n)とカスタム区切り文字(||)が含まれています。 15 $data = "これは1行目です。\n2行目の一部||ここで区切ります。\n残りの部分"; 16 $delimiter = '||'; 17 $maxLength = 1024; // 読み込む最大バイト数 18 19 // メモリ上に読み書き可能なストリームを作成し、データを書き込みます。 20 // ファイルの代わりにメモリを使うことで、このサンプル単体で動作します。 21 $stream = fopen('php://memory', 'r+'); 22 fwrite($stream, $data); 23 24 // --- 1. fgets() の動作 --- 25 // ストリームのポインタを先頭に戻してから、fgets()で読み込みます。 26 rewind($stream); 27 echo '[fgets の場合]' . PHP_EOL; 28 // fgets() は改行文字 `\n` に到達した時点で読み込みを停止します。 29 $lineFromFgets = fgets($stream, $maxLength); 30 echo '読み込んだ文字列: ' . $lineFromFgets . PHP_EOL; // "これは1行目です。\n" が出力される 31 32 // --- 2. stream_get_line() の動作 --- 33 // 再度ストリームのポインタを先頭に戻してから、stream_get_line()で読み込みます。 34 rewind($stream); 35 echo '[stream_get_line の場合]' . PHP_EOL; 36 // stream_get_line() は指定した区切り文字 `||` に到達した時点で読み込みを停止します。 37 $lineFromStreamGetLine = stream_get_line($stream, $maxLength, $delimiter); 38 echo '読み込んだ文字列: ' . $lineFromStreamGetLine . PHP_EOL; // "これは1行目です。\n2行目の一部" が出力される 39 40 // ストリームリソースを解放します。 41 fclose($stream); 42} 43 44// 関数を実行して結果を表示します。 45compareStreamReadFunctions();
stream_get_line関数は、ファイルなどのストリームから、指定した区切り文字が現れるまでのデータを一行として読み込むための関数です。
第1引数$streamには、fopen関数などで開いたストリームリソースを指定します。第2引数$lengthには、読み込むデータの最大バイト数を指定します。そして、この関数の大きな特徴である第3引数$endingには、行の終わりを示す任意の区切り文字列を指定できます。戻り値は、読み込んだ文字列です。ただし、指定した区切り文字列自体は、返される文字列に含まれません。データの読み込みに失敗したり、ストリームの終端に達したりした場合はfalseを返します。
サンプルコードは、よく似たfgets関数との違いを示しています。fgets関数は主に改行文字を基準にデータを読み込むため、「これは1行目です。\n」までを取得します。一方、stream_get_line関数では第3引数に||という区切り文字を指定しているため、改行文字を越えて||が現れる直前までの文字列を一度に読み込みます。このように、改行以外の特定の文字列で区切られたデータを扱う場合に非常に便利な関数です。
stream_get_line関数は、改行だけでなく任意の文字列を区切りとしてデータを読み取れる点がfgetsとの大きな違いです。注意点として、fgetsが戻り値に改行文字を含むのに対し、stream_get_lineは指定した区切り文字列を戻り値に含みません。また、第2引数で指定した最大バイト数に達した場合も、区切り文字が見つからなくても読み込みは停止します。これはメモリの過剰な消費を防ぐために重要です。ファイルの終端に達した場合やエラー発生時にはfalseを返すため、戻り値の型を厳密にチェックすることが安全なプログラム作成につながります。