今回は、実行時においてエラーが起きた時に、その旨を通知したり、ユーザーに対し一時的にメンテナンスページにリダイレクトさせたりする際に便利な方法をご紹介します。

Webアプリケーション開発においてはテストサーバ上で作成し、各種動作確認をし、その後に本番サーバに移して最終確認後、運用をするという方式を取っている方も多いと思います。

また各種テストをするために、テストサーバ上では表示するようにしているエラーも、本番サーバではもしものエラー発生時に内部の情報を垣間見られてしまうので、display_errorsをOFFにしていたりすると思います。この時に困るのは、エラーが発生しているにも関わらずそれを表示しないようにしている為、エラーに気がつきにくいという事です。

画面が真っ白になる、などの大きな規模のエラーでしたら簡単に気がつく事も多いでしょうが、スクリプトが中断されないE_WARNINGレベルのエラーはなかなか気がつかない事も多いと思います。

PHPではそのようなエラーが起きた時に、エラーの種類に応じて設定しておいた処理を行わす事が出来る、set_error_handlerという関数が用意されています。

http://jp.php.net/manual/ja/function.set-error-handler.php

使い方は簡単。

まずテスト的に以下のようなコードを記述しておきます。

function errorHandler ($errno, $errstr, $errfile, $errline) {
  if ($errno == 1 || $errno == 2 || $errno == 4) {
    // E_ERROR, E_WARNING, E_PARSEエラー発生時の処理
  }
}
set_error_handler("errorHandler");

これはエラーが発生した際に、

Warning: ~~ in /file/to/path/test.php on line 10

などといったエラーメッセージを出力される代わりに、引数で設定したユーザ関数を実行します。

ユーザ関数の引数に受け取る値の詳しい情報はマニュアルを読んでいただきたいのですが、上の例ですと

$errno  : 発生したエラーのレベル 詳しくはこちら
$errstr : エラーのメッセージ
$errfile : エラーが発生したファイル名
$errline : エラーが発生した行番号

となります。

試しにエラーを発生させてみましょう、以下のようなファイルを作りました。厳密にE_NOTICEエラーも出すため、error_reportingをE_ALLで設定してあります。

<?php
  error_reporting
(E_ALL);
  foreach(
$data as $value) {
    print 
$value "<br />\n";
  }
?>

実行すると、以下のような表示が出ました。(パスのみ書き換えてあります)

Notice: Undefined variable: data in /file/to/path/test.php on line 3
Warning: Invalid argument supplied for foreach() in
/file/to/path/test.php on line 3

最初のNoticeエラーは$dataが未定義なため、Warningは$dataが配列でないため発生しています。

次にset_error_handlerを追加して、スクリプトをこのように書き直してみます。

<?php
  error_reporting
(E_ALL);
  function 
errorHandler ($errno$errstr$errfile$errline){
    switch (
$errno) {
      case 
:
        print 
"E_ERRORエラー";
    break;
    case 
:
    print 
"E_WARNINGエラー";
    break;
    case 
:
    print 
"E_PARSEエラー";
    break;
    case 
8:
    print 
"E_NOTICEエラー";
    break;
    default:
    print 
"その他のエラー";
    }
    print 
" ファイル名:" $errfile " 行番号:" $errline ."<br/>\n";
  }
  
set_error_handler("errorHandler");

  foreach(
$data as $value){
    print 
$value "<br />\n";
  }
?>

出力結果は以下のようになりました

E_NOTICEエラー ファイル名:/file/to/path/test.php 行番号:24
E_WARNINGエラー ファイル名:/file/to/path/test.php 行番号:24

このように、エラーのレベルや発生したファイルなどを条件として使い、様々な処理を書いておく事で、もしもの時に対応ができます。

今回の紹介ではただ単純に引数の値を出力しただけですが、実際にはエラーの出たファイルや行番号を本文として、エラー通知メールを管理者に送ったり、ユーザー側には即座に臨時ページにリダイレクトさせる、等の方法を取ったりする事ができるでしょう。

エラーを出さないようにコーディングする事ももちろん大事ですが、エラーが起きた時に迅速にその存在を察知し、対応するための情報を得る事も大切です。