Upload
yandod
View
9.526
Download
8
Embed Size (px)
Citation preview
Shimokita.php / Yusuke Ando (@yando)Shimokita.php / Yusuke Ando (@yando)
PHPエラーの教室90分間濃縮
Shimokita.php / Yusuke Ando (@yando)Shimokita.php / Yusuke Ando (@yando)
Shimokita.php / Yusuke Ando (@yando)
福岡でのボランティア急募!
Shimokita.php / Yusuke Ando (@yando)
こんな経験はありませんか?
Shimokita.php / Yusuke Ando (@yando)
画面が真っ白に
Shimokita.php / Yusuke Ando (@yando)
画面にお経みたいなものがでる
Shimokita.php / Yusuke Ando (@yando)
サーバのログがゴミ溜めになっている
Shimokita.php / Yusuke Ando (@yando)
エラー正しく扱えていますか?
Shimokita.php / Yusuke Ando (@yando)
Shimokita.php / Yusuke Ando (@yando)
Shimokita.php / Yusuke Ando (@yando)
PHPのエラーと例外に関する取り扱い方法を見ていきます
Shimokita.php / Yusuke Ando (@yando)
エラーのイロハ
•何故エラーが起きるのか•エラー関連の設定•エラーハンドリング•例外処理
地味だけれど重要な知識
Shimokita.php / Yusuke Ando (@yando)
何故エラーが起きるのか
Shimokita.php / Yusuke Ando (@yando)
エラーとは
•PHPのスクリプトを実行する際の各段階で発生•構文解析時の問題•処理の実行中に発生する問題•拡張モジュールなどの外部プログラム内•ネットワーク処理など通信が発生した場合
状況に応じて正しい対処が異なる
Shimokita.php / Yusuke Ando (@yando)
エラーの種類
重大度に応じてレベルが存在
種類 内容
E_ERROR / Fatal 実行不可能:処理は停止、白画面
E_WARNING / Warning 警告:実行時に問題発生、処理は継続
E_PARSE / Parse 解析不能:処理は始まらない、白画面
E_NOTICE / Notice 通知:問題になりうる状況、処理は継続
E_STRICT / E_DEPRECATED バージョン間の互換性に関するエラー
Shimokita.php / Yusuke Ando (@yando)
何も出ないか、壊れた画面かの分かれ目
FATAL / PARSE
NOTICE / WARNING etc
Shimokita.php / Yusuke Ando (@yando)
E_PARSE / Parse
シンプルな構文エラー
echo echo;
echo date()echo time()
•トークンの出現位置が不正•セミコロン忘れ、ブレースの対応関係•全角スペース混入
Shimokita.php / Yusuke Ando (@yando)
E_ERROR / FATAL
コードが実行された時の状態が問題
$obj = 1;if ($obj === null) { $obj = getObject();}$obj->myFunc();
•構文は合っていたが、実行しようとした処理が失敗•関数名間違い、オブジェクトの取り違い•外部モジュールのエラー
Shimokita.php / Yusuke Ando (@yando)
E_WARNING
エラーを検知してふさわしい処理が必要
$body = file_get_contents(‘hoge.txt’);echo “Hello”;
•処理は実行できたが、失敗してしまった場合•ファイルやネットワークの処理など•正常に処理を継続する事はおそらく難しい
Shimokita.php / Yusuke Ando (@yando)
E_NOTICE
動いていたとしても危険性あり
if ($data == null) { echo ‘Hello’; echo HOGE;}
•未定義の変数、定数を使った場合•関数への引数が正しくない•考慮の足りないコードで発生しやすい
Shimokita.php / Yusuke Ando (@yando)
E_STRICT / E_DEPRECATED
古い遺産で発生しやすく、不可避な場合も
class Sample{ function foo() { echo "Hi"; }}Sample::foo();
•PHP4の文法をPHP5で利用した場合•将来廃止される予定の機能を使った場合
Shimokita.php / Yusuke Ando (@yando)
Segmentation Fault
•ログには”Segmentation Fault”とだけ記録される
サーバのアップデートなどが必要になる
Shimokita.php / Yusuke Ando (@yando)
エラー関連の設定
Shimokita.php / Yusuke Ando (@yando)
エラーが画面に出ない?
•発生したエラーを表示するかは設定次第•php.ini または htaccessなどの設定•実行時に設定を強制的に変更する事も可能•ini_set() error_reporting() display_errors()•エラーをログに記録するかどうかは別の設定
開発時は表示、運用時は記録が正しい
Shimokita.php / Yusuke Ando (@yando)
正しい設定error_reporting = E_ALLdisplay_errors = Ondisplay_startup_errors = Onlog_errors = Onerror_log = /path/to/error.log
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICTdisplay_errors = Offdisplay_startup_errors = Offlog_errors = Onerror_log = /path/to/error.log
互換性エラーは無視
全てを検知、表示
表示はしない
Shimokita.php / Yusuke Ando (@yando)
運用中のエラーを隠す理由
DB情報などが入る場合も
不具合の発生時に警告が出る場合
表示が崩れるかも
Shimokita.php / Yusuke Ando (@yando)
こういうのは...
Shimokita.php / Yusuke Ando (@yando)
これもダメ
<?php@trigger_error("Hi");echo "World";
強制的に無視
これを多用すると障害発生時に手がかり0
Shimokita.php / Yusuke Ando (@yando)
エラーハンドリング
Shimokita.php / Yusuke Ando (@yando)
エラーハンドリング
•エラーが発生した後に行う処理•発生したエラーのレベルに応じて処理が可能•標準のエラーハンドラはphp.iniの設定に応じた処理•任意の処理を登録する事も可能•エラーハンドラから元の処理にも戻れる•任意のエラーを起こす事も可能
フレームワークなどでも利用されている
Shimokita.php / Yusuke Ando (@yando)
エラーハンドリングの例
標準の処理以外の対応が可能
function handler($no, $str){ echo "Error $str\n"; return true;}
set_error_handler('handler');echo $a;trigger_error('My Error');
•エラーの情報を引数で受け取る•returnで元の場所へ復帰する
Shimokita.php / Yusuke Ando (@yando)
エラーハンドリングの例2
Shimokita.php / Yusuke Ando (@yando)
エラーハンドリングの後
ハードな運用を耐えているかの試金石
•処理が継続するWarningやNoticeの後には適切な処理•不足すると空っぽのリスト、崩れた画面などに繋がる
$body = file_get_contents(‘hoge.txt’);if ($body === false) { my_error(); exit;}echo “Hello”;
Shimokita.php / Yusuke Ando (@yando)
重要なんです!
さすがPHP、エラー時の返り値がバラバ(ry
Shimokita.php / Yusuke Ando (@yando)
例外処理
Shimokita.php / Yusuke Ando (@yando)
例外処理
•PHP5から利用できるエラー処理•Javaなどの言語でも実績がある機構•誤った利用方法により有害無益になっている例多数•正しく使えばエラー処理がすごく楽になる•間違って使うと無駄にコードが多くなって、挙動も崩壊
これからは例外を使って行きたい
Shimokita.php / Yusuke Ando (@yando)
例外処理の例
例外オブジェクトをthrowするとcatchに入る
function hoge(){ if (true) { throw new Exception('Error!'); }}try { hoge();} catch (Exception $e) { echo $e->getMessage(); exit;}
Shimokita.php / Yusuke Ando (@yando)
例外オブジェクト•オブジェクトからエラー情報が取得可能•Exceptionをnewする時にセットされた情報を取得•getMessage getCode getFile getLine getTrace
Shimokita.php / Yusuke Ando (@yando)
例外処理の失敗例
例外オブジェクトをreturn...
function hoge(){ if (true) { return new Exception('Error!'); }}try { hoge();} catch (Exception $e) { echo $e->getMessage(); exit;}
Shimokita.php / Yusuke Ando (@yando)
例外処理の失敗例2
catchする例外の型が合っていない
function hoge(){ if (true) { throw new Exception('Error!'); }}try { hoge();} catch (Excepton $e) { echo $e->getMessage(); exit;}
Shimokita.php / Yusuke Ando (@yando)
例外処理の失敗例3
catchしてもなにもしていない...
function hoge(){ if (true) { throw new Exception('Error!'); }}try { hoge();} catch (Exception $e) {
}
Shimokita.php / Yusuke Ando (@yando)
例外処理に関する誤解
•try catchをたくさん書くのが正しいコード→きちんと書けば巨大なコードでもcatchは一箇所でよい•入力エラーなどでも例外処理を使うべき→通常発生しうるものは例外ではない•catchすればとりあえずはOK→catchするのはどうしても必要な場合のみ
正しく例外を扱うプロジェクトの稀な事
Shimokita.php / Yusuke Ando (@yando)
例外処理の自動化
•catchされなかった例外が最終的に指定した関数へ到達
function handler($exception) { echo $exception->getMessage();}set_exception_handler(“handler”);
Shimokita.php / Yusuke Ando (@yando)
まとめ
no more error_reporting(0);no more @hoge();
•「画面が白くなりました」は無意味•エラーの内容を確認しなければ対応は不可能•Noticeが多いからエラーを消すは本末転倒•通常稼働中はエラーが発生しないのが理想•ライブラリやプラグインがNoticeやWarningを垂れ流すのは非常に害が大きく、廃れる原因
Shimokita.php / Yusuke Ando (@yando)
質問?