【PHP8.x】lineプロパティの使い方

lineプロパティの使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

lineプロパティは、RequestParseBodyExceptionクラスに属し、例外が発生したソースコードの行番号を保持するプロパティです。

RequestParseBodyExceptionは、PHPの内部処理がHTTPリクエストのボディ(本体)を解析する際に、例えばリクエストのデータ形式が不正であるなど、何らかの問題が発生した場合にスローされる例外です。この例外は、通常、開発者が直接記述したPHPスクリプト内で発生するエラーではなく、PHPエンジンのコア部分でリクエストデータを処理している最中に問題が見つかったことを示します。

このlineプロパティが保持する行番号は、一般的なPHPの例外が示す、開発者が記述したPHPスクリプト内のエラー発生箇所とは異なります。代わりに、PHP自体のC言語で書かれた内部ソースコード内でエラーが発生した箇所の行番号を示します。これは、リクエストの解析処理というPHPの低レベルな内部動作中に例外が発生したことを意味します。

したがって、このプロパティは、リクエストボディの解析に関連するPHPの内部的な問題や、PHP本体のバグを調査・特定する際に役立つ情報を提供します。システムエンジニアが自身のPHPスクリプトのエラー箇所を直接特定するために参照することは稀ですが、より深いレベルでのトラブルシューティングや、PHP本体へのバグ報告を行う際に、問題の発生源を特定するための重要な手掛かりとなります。このプロパティは整数値(int型)を保持しており、例外が発生した時点の内部コードの正確な行番号を示します。

構文(syntax)

1<?php
2
3try {
4    // RequestParseBodyException は通常、PHPエンジン内部でリクエストボディの解析に失敗した際にスローされます。
5    // ここでは構文を示すために、直接例外をスローする例を示します。
6    throw new RequestParseBodyException('Failed to parse request body.', 0, null, __FILE__, __LINE__);
7} catch (RequestParseBodyException $e) {
8    // 例外が発生したソースコードの行番号を取得します。
9    echo $e->line;
10}

引数(parameters)

戻り値(return)

int

このプロパティは、リクエストボディの解析中にエラーが発生した行番号を整数値で返します。

サンプルコード

PHP LINE で行番号を取得する

1<?php
2
3/**
4 * __LINE__ マジック定数の使用例を示すためのクラスです。
5 * __LINE__ は、この定数が記述されているファイル内の現在の行番号を返します。
6 */
7class LineNumberExample
8{
9    /**
10     * プログラムの異なる場所で現在の行番号を表示します。
11     *
12     * @return void
13     */
14    public function showLineInfo(): void
15    {
16        // この echo 文が記述されている行の番号が出力されます。
17        echo 'クラスメソッド内の行番号: ' . __LINE__ . PHP_EOL;
18
19        // 変数に代入する時点での行番号が格納されます。
20        $currentLine = __LINE__;
21        echo '変数代入後の行番号: ' . $currentLine . PHP_EOL;
22    }
23}
24
25// この echo 文が記述されている行の番号が出力されます。
26echo 'スクリプトのトップレベルでの行番号: ' . __LINE__ . PHP_EOL;
27
28// LineNumberExample クラスのインスタンスを生成します。
29$example = new LineNumberExample();
30
31// メソッドを呼び出します。メソッド内の __LINE__ が評価されます。
32$example->showLineInfo();
33
34// この echo 文が記述されている行の番号が出力されます。
35echo 'スクリプトの最後での行番号: ' . __LINE__ . PHP_EOL;
36

PHPの__LINE__は、コードが記述されているファイル内の現在の行番号を返す「マジック定数」です。マジック定数とは、使われる場所によってその値が変化する、あらかじめ定義された特別な定数のことです。

この定数は引数を取らず、戻り値として行番号を整数(int)型で返します。プログラムのデバッグ時に、コードのどの部分が実行されたかを正確に特定するのに役立ちます。

サンプルコードでは、__LINE__がスクリプト内の様々な場所で使われています。スクリプトの先頭、クラスのメソッド内、そしてスクリプトの末尾でecho文と共に使用することで、それぞれの__LINE__が記述された箇所の行番号が正確に出力されることがわかります。また、変数に__LINE__を代入すると、その代入が行われた行の番号が変数に格納され、後からその値を利用することもできます。このように__LINE__は、それが記述されたその場所の行番号を動的に取得するための便利な機能です。

__LINE__は、それが記述されたファイル内の行番号を返す特殊な定数です。実行中に値が変わる変数とは異なり、コードが書かれた場所で値が確定する点に注意してください。そのため、コードを別の行にコピー&ペーストすると、__LINE__が示す行番号も変わります。この定数は主にデバッグ目的で利用され、ログに処理が通過した正確なコード上の位置を記録するのに役立ちます。空行やコメントも行として数えられるため、コードの整形によって値が変動する可能性があります。includeされたファイル内で使った場合は、その読み込まれたファイル内での行番号が返されます。

PHP RequestParseBodyException の line を取得する

1<?php
2
3/**
4 * RequestParseBodyException を捕捉し、エラーが発生した行番号を取得するサンプルコード
5 *
6 * この例外は、クライアントからサーバーへ "送信" されたリクエストボディの
7 * 解析に失敗した際にスローされます。
8 *
9 * 通常の try-catch では捕捉できない致命的なエラーとして扱われるため、
10 * register_shutdown_function() を使ってエラー情報を取得します。
11 */
12
13// スクリプトの実行が終了する際に呼び出される関数を登録します。
14// これにより、致命的なエラーが発生した場合でも情報を捕捉できます。
15register_shutdown_function(function () {
16    // 最後に発生したエラー情報を取得します。
17    $error = error_get_last();
18
19    // エラーが存在し、それが RequestParseBodyException に関連するものかを確認します。
20    if ($error && str_contains($error['message'], 'RequestParseBodyException')) {
21        // エラーメッセージから、プロパティ 'line' に相当する行番号を正規表現で抽出します。
22        // メッセージ例: "Request body parsing failed ... at line 5"
23        if (preg_match('/at line (\d+)/', $error['message'], $matches)) {
24            // 抽出した行番号 (プロパティ `line` の値に相当)
25            $line = (int)$matches[1];
26
27            // エラーレスポンスとして、エラーが発生した行番号とメッセージを出力します。
28            header('Content-Type: text/plain; charset=UTF-8', true, 500);
29            echo "リクエストボディの解析に失敗しました。\n";
30            echo "エラー発生行 (RequestParseBodyException->line): " . $line . "\n";
31            echo "エラー詳細: " . $error['message'] . "\n";
32            exit;
33        }
34    }
35});
36
37// このスクリプト自体には、エラーを発生させる処理はありません。
38// エラーは、このスクリプトが実行される前のリクエスト解析フェーズで発生します。
39// 以下のメッセージは、リクエストの解析が成功した場合にのみ表示されます。
40header('Content-Type: text/plain; charset=UTF-8');
41echo "リクエストボディの解析に成功しました。\n";
42
43/*
44--- このコードの動作を確認する方法 ---
45
461. このファイルをWebサーバーの公開ディレクトリに `test.php` として保存します。
472. ターミナルから以下のcurlコマンドを実行し、不正なPOSTリクエストを "送信" します。
48   (最後のバウンダリの末尾に '--' がなく、不正なデータ形式になっています)
49
50curl -X POST \
51  -H "Content-Type: multipart/form-data; boundary=boundary_string" \
52  --data-binary $'--boundary_string\r\nContent-Disposition: form-data; name="field1"\r\n\r\nvalue1\r\n--boundary_string\r\n' \
53  http://localhost/test.php
54
553. 実行結果として、上記で echo しているエラーメッセージと行番号が表示されます。
56*/

RequestParseBodyException->lineは、クライアントからサーバーへ送信されたHTTPリクエストボディの解析に失敗した際に、エラーが発生したリクエストボディ内の行番号を格納するプロパティです。この例外は、PHPスクリプトが本格的に実行される前の段階で発生することが多く、通常のtry-catch構文では捕捉できない致命的なエラーとして扱われます。

サンプルコードでは、この特性に対応するためにregister_shutdown_function関数を使用しています。この関数は、スクリプトの実行が終了する際に呼び出される処理を登録するもので、致命的なエラーが発生した後でもエラー情報を取得できます。登録された関数内でerror_get_lastを呼び出して最後に発生したエラー情報を取得し、そのエラーメッセージの文字列から正規表現を使って「at line X」という形式で記述された行番号を抽出します。この抽出された数値が、lineプロパティが示す値に相当します。

このプロパティは引数を取らず、戻り値としてエラーが発生した行番号を整数(int)で返します。これにより、開発者はクライアントから送信された不正な形式のデータについて、どの行で問題が起きているかを正確に特定できます。

この例外は、通常のtry-catchでは捕捉できない点に注意が必要です。PHPのプログラムが実行される前の、リクエストデータを解析する段階で発生する致命的なエラーだからです。そのため、スクリプト終了時に動作するregister_shutdown_functionerror_get_lastを組み合わせてエラー情報を取得します。サンプルコードでは、例外オブジェクトのプロパティに直接アクセスできないため、エラーメッセージの文字列から正規表現を使って行番号を抽出しています。このエラーの原因はコードの誤りではなく、クライアントから送信された不正なデータ形式にあります。本番環境では、エラー詳細をそのまま利用者に表示せず、ログに記録するようにしましょう。