プログラミング PHP

【PHP入門】エラーと例外処理

本記事では、PHPのエラーと例外について紹介します。

PHPのエラー

エラーが発生したときの挙動

PHPでは実行中にエラーが発生しても、基本的には処理を続けようとします。
ただし、続行できないFatal error(致命的なエラー)が発生した場合は処理を停止します。

例えば、次の例では「Warning(警告)」と「Fatal error(致命的なエラー)」を発生させています。

[エラーの例]

<?php
 // 警告のエラーを発生させる(存在しないファイルを指定)
 $fd = fopen("c:/temp/abc.txt","r");
 echo "処理が継続されます";
 // 致命的なエラーを発生させる(存在しない関数を呼び出す)
 test( );
 echo "継続処理";
?>

[実行結果]

Warning: fopen(c:/temp/abc.txt): Failed to open stream: No such file or directory in C:\xampp\htdocs\phpSample\lesson22\errorHandlerSample.php on line ***
処理が継続されます
Fatal error: Uncaught Error: Call to undefined function test( ) in C:\xampp\htdocs\phpSample\lesson22\errorHandlerSample.php:9 Stack trace: #0 {main} thrown in C:\xampp\htdocs\phpSample\lesson22\errorHandlerSample.php on line ***

Warning(警告)の場合は、エラーメッセージを表示し処理を継続していますが、Fatal error(致命的なエラー)の場合は、継続処理を行わず処理を停止しています。

このエラーの発生を感知して、何らかの処理を行うことをエラーハンドリングといいます。
エラーハンドリングを行うには「set_error_handler()」関数を使用します。(ただし、Fatal errorはハンドリングしない)

set_error_handler関数の使い方

「set_error_handler()」関数を使用することで、エラーハンドリングを行うことができます。

[set_error_handler関数の使用例]

<?php
 // エラー時の処理を登録
 set_error_handler(function($errno, $errstr, $errfile, $errline) {
  print "エラーが発生しました。$errno, $errstr <br />";
 });
 // 警告のエラーを発生させる(存在しないファイルを指定)
 $fd = fopen("c:/temp/abc.txt","r");
?>

[実行結果]

エラーが発生しました。2, fopen(c:/temp/abc.txt): Failed to open stream: No such file or directory

PHPの例外

プログラム実行中に発生する予期せぬエラーのことを例外(Exception)といいます。

例外処理の流れ

例外が発生しそうな処理には、try文、catch文、finally文を使います。

try {
 (例外が発生しそうな処理)
}catch ( Exception $e ) {
 (例外が発生した時に行う処理){
}finally {
 (例外の発生有無にかかわらず最終的に行う処理)

try{ }内に例外が発生しそうな処理を記述します。

catch{ }内には例外が発生した時に行う処理を記述します。
try{ }内で例外が発生した場合、catch{ }内の処理が動作し、catchでは例外クラスのオブジェクトを受け取ります。
例外クラスのオブジェクトには、どんな例外がどこで発生したのかの情報が格納されています。

finally{ }内の処理は例外発生の有無に関わらず行う処理を記述します。
finally文は省略可能なので、必要がなければ記述しなくても問題ありません。

正常時の流れ
try内の処理を実行

finally内の処理を実行(finallyは省略可能なのでfinallyが存在する場合のみ実行)

例外発生時の流れ
try内の処理を実行

例外発生(例外が発生した時点でtry内の処理は中断しcatch文へ)

catch内の処理を実行

finally内の処理を実行(finallyは省略可能なのでfinallyが存在する場合のみ実行)

try-catchの実装例

try-catch の使用例を紹介します。

PHPでは ただのエラーはcatch できなく、throw された例外(Exception)しか catch できません。

<?php
 try {
  // 警告のエラーを発生させる(存在しないファイルを指定)
  $fd = fopen("c:/temp/abc.txt","r");
 } catch (Exception $e) {
  echo "例外が発生しました。".$e->getMessage();
 }
?>

[実行結果]

Warning: fopen(c:/temp/abc.txt): Failed to open stream: No such file or directory in C:\xampp\htdocs\phpSample\lesson22\tryCatchSample.php on line ***

エラーをcatchするには set_error_handler() 関数を使用します。

例外ではない ただのエラー(構文エラーなど)をcatchするためには、「set_error_handler()」関数を使用します。
エラーを「set_error_handler()」関数でハンドリングし、「set_error_handler()」関数内で例外を発生させます。

[try-catchの実装例]

<?php
 // エラー時に例外をスローするように登録します
 set_error_handler(function($errno, $errstr, $errfile, $errline) {
  if (!(error_reporting() & $errno)) {
   return
  }
  throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
 });
 try {
  // 警告のエラーを発生させます(存在しないファイルを指定)
  $fd = fopen("c:/temp/test.txt","r");
 } catch (Exception $e) {
  echo "例外が発生しました。".$e->getMessage( );
 }
?>

[実行結果]

例外が発生しました。fopen(c:/temp/test.txt): Failed to open stream: No such file or directory

エラー発生時の流れ
try内の処理が実行されます

エラー発生(エラーが発生したのでset_error_handler()で登録した関数へ)

set_error_handler() で登録した関数の処理が実行されます(関数内で例外を発生させる。例外が発生したのでcatch文へ)

catch内の処理が実行されます

finally内の処理が実行されます(finallyは省略可能なのでfinallyが存在する場合のみ実行)

set_error_handler( )関数内で例外を発生させることで、catchできるようになります

PHPのエラーと例外について説明しました。PHPの学習をされている方のお力になれれば幸いです。

PHP学習書の紹介

Webアプリケーションの定番言語であるPHPの基礎から実践までを、上下巻のフルボリュームで集大成。

「この目的を実現するためには、どの文法テクニックが適合しやすいだろう?」
「このプログラムをより読みやすくするために、どんなアプローチができるだろう?」

といったことを思考しつつ、「とりあえずは動く」だけで終わらない、現場に求められる品質を形にするための知識とテクニックを解説します。

-プログラミング, PHP