Symfoware

Symfowareについての考察blog

PHP 「@」でエラー抑止していても処理が途中で終了する

例えばこんなコード。


  1. <?php
  2. // とりあえずファイルを開こうとしてみる
  3. // 存在しない場合のエラーは「@」で抑止
  4. $file = @file_get_contents('dummy.txt');
  5. if ($file === false) {
  6.     echo 'ファイルが存在しません'.PHP_EOL;
  7.     
  8. } else {
  9.     echo $file.PHP_EOL;
  10. }



「@」でエラーを抑止し、とりあえずファイルを開いてみる。
戻り値がfalseだったらファイルが存在しないと判断。


$ php sample.php
ファイルが存在しません




このような処理が書いてあるプログラムで、ある環境ではうまく動くのですが、
別の環境ではファイルが存在しない時に処理が止まってしまい悩んでいました。

よくよく調べてみると、動かない環境では事前に読み込んでいるファイルで
「set_error_handler」が設定されており、ここでexitしています。


  1. <?php
  2. // -------------------------------------------
  3. // 事前に読み込まれるファイルで実行されている処理
  4. function _hook_exception_handler($severity, $message, $filepath, $line) {
  5.     echo $message.PHP_EOL;
  6.     exit();
  7. }
  8. set_error_handler('_hook_exception_handler');
  9. // -------------------------------------------
  10. // とりあえずファイルを開こうとしてみる
  11. // 存在しない場合のエラーは「@」で抑止
  12. $file = @file_get_contents('dummy.txt');
  13. if ($file === false) {
  14.     echo 'ファイルが存在しません'.PHP_EOL;
  15.     
  16. } else {
  17.     echo $file.PHP_EOL;
  18. }





$ php sample.php
file_get_contents(dummy.txt): failed to open stream: No such file or directory




なるほど、エラーを抑止しててもエラー発生時の処理でexitされたら
プログラムの実行は止まりますよね。


該当処理の直前で「set_error_handler(null)」とすることで問題を回避しました。


  1. <?php
  2. // -------------------------------------------
  3. // 事前に読み込まれるファイルで実行されている処理
  4. function _hook_exception_handler($severity, $message, $filepath, $line) {
  5.     echo $message.PHP_EOL;
  6.     exit();
  7. }
  8. set_error_handler('_hook_exception_handler');
  9. // -------------------------------------------
  10. // デフォルトのエラー設定を解除
  11. // 戻り値は変更前の設定無いようなので対比しておく
  12. $error_handlers = set_error_handler(null);
  13. // とりあえずファイルを開こうとしてみる
  14. // 存在しない場合のエラーは「@」で抑止
  15. $file = @file_get_contents('dummy.txt');
  16. if ($file === false) {
  17.     echo 'ファイルが存在しません'.PHP_EOL;
  18.     
  19. } else {
  20.     echo $file.PHP_EOL;
  21. }
  22. echo '初期値に復元'.PHP_EOL;
  23. // エラー設定を元に戻す
  24. set_error_handler($error_handlers);
  25. $file = @file_get_contents('dummy.txt');
  26. if ($file === false) {
  27.     echo 'ファイルが存在しません'.PHP_EOL;
  28.     
  29. } else {
  30.     echo $file.PHP_EOL;
  31. }




狙い通り、最初の処理だけ_hook_exception_handlerが実行されないようになりました。


$ php sample.php
ファイルが存在しません
初期値に復元
file_get_contents(dummy.txt): failed to open stream: No such file or directory




これ、半日ぐらいはまりましたよ...



【参考URL】

set_error_handler


関連記事

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2016/12/04(日) 16:55:56|
  2. PHP
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
前のページ