【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を返すため、戻り値の型を厳密にチェックすることが安全なプログラム作成につながります。
PHP stream_get_lineでデータを行ごとに読み取る
1<?php 2 3/** 4 * Demonstrates the usage of stream_get_line function. 5 * 6 * This function reads a line from a stream resource, allowing specification 7 * of maximum length and a custom line ending delimiter. 8 */ 9function demonstrateStreamGetLine(): void 10{ 11 // Create a temporary in-memory stream for demonstration purposes. 12 // 'php://memory' is a transient read/write stream that exists only for the duration of the script. 13 $stream = fopen('php://memory', 'r+'); 14 15 if ($stream === false) { 16 echo "Error: Could not open a memory stream.\n"; 17 return; 18 } 19 20 // Write some sample data to the stream. 21 fwrite($stream, "This is the first line.\n"); 22 fwrite($stream, "This is the second line, which is longer than our max read length.\n"); 23 fwrite($stream, "This is the third line. Custom_Delimiter_Here\n"); 24 fwrite($stream, "Fourth line.\n"); 25 26 // Rewind the stream pointer to the beginning to start reading from the start. 27 fseek($stream, 0); 28 29 echo "--- Demonstrating stream_get_line ---\n\n"; 30 31 // Example 1: Read a line using default line endings (\n, \r, \r\n) 32 // The maximum length is set to 1024 bytes. 33 echo "1. Reading with default line ending (max 1024 bytes):\n"; 34 $line1 = stream_get_line($stream, 1024); 35 if ($line1 !== false) { 36 echo " Read: '" . $line1 . "'\n"; 37 } else { 38 echo " Failed to read the first line or EOF reached.\n"; 39 } 40 echo "\n"; 41 42 // Example 2: Read a line with a specified maximum length 43 // This will read only up to 20 bytes, even if the line is longer. 44 echo "2. Reading with a maximum length of 20 bytes:\n"; 45 $line2_part1 = stream_get_line($stream, 20); // Reads "This is the second li" 46 if ($line2_part1 !== false) { 47 echo " Read Part 1: '" . $line2_part1 . "'\n"; 48 // The remaining part of the second line is still in the stream buffer. 49 // Let's read the rest of it. 50 $line2_part2 = stream_get_line($stream, 1024); // Reads "ne, which is longer than our max read length." 51 if ($line2_part2 !== false) { 52 echo " Read Part 2 (remaining): '" . $line2_part2 . "'\n"; 53 } 54 } else { 55 echo " Failed to read the second line (part 1) or EOF reached.\n"; 56 } 57 echo "\n"; 58 59 // Example 3: Read a line with a custom ending delimiter 60 // The function will read until 'Custom_Delimiter_Here' is found, EOF, or max length. 61 // Note: The delimiter itself is NOT included in the returned string. 62 echo "3. Reading with a custom ending delimiter 'Custom_Delimiter_Here':\n"; 63 $line3 = stream_get_line($stream, 1024, 'Custom_Delimiter_Here'); 64 if ($line3 !== false) { 65 echo " Read: '" . $line3 . "'\n"; 66 } else { 67 echo " Failed to read the third line or EOF reached.\n"; 68 } 69 echo "\n"; 70 71 // Example 4: Attempt to read when EOF is reached 72 echo "4. Attempting to read after all data has been consumed:\n"; 73 $line4 = stream_get_line($stream, 1024); 74 if ($line4 === false) { 75 echo " No more data to read (EOF reached), returned false as expected.\n"; 76 } else { 77 echo " Unexpectedly read: '" . $line4 . "'\n"; 78 } 79 echo "\n"; 80 81 // Always close the stream resource when you are done with it to free up resources. 82 fclose($stream); 83} 84 85// Execute the demonstration function. 86demonstrateStreamGetLine(); 87 88?>
PHPのstream_get_line関数は、ファイルやネットワーク接続といった「ストリーム」と呼ばれるデータ源から、一行分のデータを読み込むために使用されます。この関数は、特にストリームから特定の区切り文字、または指定した最大バイト数で区切られたデータを効率的に取得したい場合に非常に有用です。
引数として、まず$streamにはfopen関数などで開かれたストリームリソースを渡します。次に$lengthは、一度に読み込むデータの最大バイト数を指定します。データがこのバイト数に達するか、改行コードまたは指定した区切り文字が見つかるまで読み込みが行われます。オプションの$ending引数には、行の終わりを示す任意のカスタム区切り文字列を指定でき、これを省略した場合はデフォルトの改行コード(\n, \r, \r\n)が行末として扱われます。戻り値は読み込んだ文字列ですが、読み込みに失敗した場合やストリームの終端(EOF)に達した場合はfalseを返します。指定したカスタム区切り文字は、戻り値の文字列には含まれない点に注意が必要です。
このサンプルコードでは、実用的な例として、php://memoryという一時的なメモリ上のストリームを作成し、複数のデータ行を書き込んでからstream_get_lineの挙動を実演しています。まずストリームポインタをfseek(0)で先頭に戻し、データの読み込みを準備します。そして、デフォルトの改行で読み込む例、最大バイト数を指定して一行の途中で読み込みを分割する例、特定の文字列をカスタム区切り文字として利用する例を通して、各引数がどのように機能するかを具体的に示しています。特に、$lengthによる読み込みの中断や、カスタム区切り文字が戻り値に含まれないことを確認できます。最後に、すべてのデータを読み終えた後にfalseが返されることも確認し、処理の完了後にはfcloseでストリームリソースを適切に解放する重要性も示されています。
PHPのstream_get_line関数は、ファイルやネットワークストリームからデータを効率的に読み込む際に使用します。サンプルコードは一時的なメモリ上のストリームで動作を示していますが、実際のファイルでも同様に利用できます。
この関数を使う上で特に重要なのは、戻り値の確認です。データを読み込めなかったり、ストリーム終端に達したりした場合にfalseを返すため、必ずその後の処理を考慮しエラーハンドリングを行うようにしてください。
また、$length引数は読み込む最大バイト数を指定します。これを超えると行が途中でも読み込みが中断されるため、想定通りのデータを取得できない場合があります。カスタムの区切り文字$endingは、読み取られた文字列には含まれない点も覚えておきましょう。ストリームは処理が完了したら、必ずfcloseで閉じてリソースを解放することが大切です。