PHP アドバンス

PHP 例外

1. PHP 例外(Exceptions)とは何か?

例外(Exception)とは、PHPスクリプトの実行中に発生する、予期しないイベントや望ましくない事象のことです。

例外は、多くのPHP関数やクラスによって「スロー(投げられる)」されます(不正なデータなど、予期せぬ状況が発生した場合)。例外がスローされると、適切なエラーハンドリングを行うコードブロック(通常は try...catch ブロック)によって「キャッチ(捕捉)」することができます。
もし例外がキャッチされない場合、デフォルトの例外ハンドラーによって処理されますが、多くの場合**フェイタルエラー(致命的なエラー)**となり、スクリプトの実行が強制終了してしまいます。

PHPでは、例外処理のために以下のキーワードを使用します。

  • throw - 例外をスローするために使用します。
  • try - try...catch または try...catch...finally ステートメントを作成するために使用します。
  • catch - 直前の try ブロック内のコードによってスローされた例外をハンドル(処理)するために使用します。
  • finally - 例外が発生したかどうかにかかわらず、特定のコードブロックを実行するために使用します。

2. PHP throw キーワード

throw キーワードは、例外を意図的に発生させるために使用されます。
例外がキャッチ(捕捉)されない場合、「Uncaught Exception」というメッセージと共にフェイタルエラーが発生し、スクリプトは停止します。

以下の例では、例外をキャッチせずにスローしています。

2.1 実装例

<?php
function divide($x, $y) {
  if($y == 0) {
    // ゼロ除算の場合に例外をスロー
    throw new Exception("ゼロによる除算はできません。");
  }
  return $x / $y;
}

echo divide(5, 0); // 例外をスローする可能性のあるコード
echo 'Hello';      // この行は実行されません
?>

実行結果は以下のようになります:

Fatal error: Uncaught Exception: ゼロによる除算はできません。 in C:\webfolder\test.php:4
Stack trace: #0 ...

3. PHP try...catch キーワード

上記の例で発生した例外をキャッチし、スクリプトの実行を継続させるために try...catch を使用します。

3.1 構文

try {
  // 例外をスローする可能性のあるコード
} catch(Exception $e) {
  // 例外がキャッチされたときに実行されるコード
}

3.2 実装例

例外がスローされたときにメッセージを表示し、スクリプトを継続させます。

<?php
function divide($x, $y) {
  if($y == 0) {
    throw new Exception("ゼロによる除算はできません。");
  }
  return $x / $y;
}

try {
  echo divide(5, 0);  // 例外をスローする可能性があります
} catch(Exception $e) {
  // エラー内容を表示
  echo 'エラー: ' . $e->getMessage();
}

echo '<br>Hello'; // スクリプトは継続して実行されます
?>

catch ブロックでは、キャッチすべき例外の型(クラス名)と、その例外オブジェクトにアクセスするための変数名を指定します。上記の例では、型は Exception、変数名は $e です。

4. PHP try...catch...finally キーワード

try...catch...finally ステートメントを使用すると、例外の発生有無に関わらず実行したい処理を記述できます。
finally ブロック内のコードは、例外がキャッチされたかどうかに関係なく、常に実行されます。

4.1 構文

try {
  // 例外をスローする可能性のあるコード
} catch(Exception $e) {
  // 例外がキャッチされたときに実行されるコード
} finally {
  // 例外の有無にかかわらず常に実行されるコード
}

4.2 実装例

例外がスローされた場合にメッセージを表示し、最後にプロセスが完了したことを示します。

<?php
function divide($x, $y) {
  if($y == 0) {
    throw new Exception("ゼロによる除算はできません。");
  }
  return $x / $y;
}

try {
  echo divide(5, 0); // 例外をスローする可能性があります
} catch(Exception $e) {
  echo 'エラー: ' . $e->getMessage();
} finally {
  echo '<br>処理が完了しました。';
}
?>

5. PHP 例外オブジェクト (Exception Object)

例外オブジェクト(Exception Object)には、関数が遭遇した予期せぬ動作に関する詳細な情報が含まれています。

5.1 構文

new Exception(message, code, previous)

5.2 パラメータ値

パラメータ説明
message任意。例外がスローされた理由を説明する文字列。
code任意。同じ型の例外を識別するために使用できる整数値。
previous任意。別の例外の catch ブロック内でこの例外がスローされた場合、その元の例外を指定することが推奨されます。

5.3 メソッド

例外をキャッチした際、以下のメソッドを使用して情報を取得できます。

メソッド説明
getMessage()例外がスローされた理由を示す文字列を返します。
getPrevious()他の例外によって引き起こされた場合、前の例外オブジェクトを返します。
getCode()例外を識別するための整数コードを返します。
getFile()例外が発生したファイルの絶対パスを返します。
getLine()例外をスローしたコードの行番号を返します。

5.4 応用例

複数の例外メソッドを使用して、発生した例外のより詳細な情報を出力します。

<?php
function divide($x, $y) {
  if($y == 0) {
    throw new Exception("ゼロによる除算はできません。", 404);
  }
  return $x / $y;
}

try {
  echo divide(5, 0);
} catch(Exception $e) {
  $file = $e->getFile();
  $line = $e->getLine();
  $code = $e->getCode();
  $message = $e->getMessage();
  
  // 詳細なエラー情報を出力
  echo "例外が投げられました。ファイル: $file (行: $line): [コード: $code] $message";
}
?>