45
Shimokita.php / Yusuke Ando (@yando) Shimokita.php / Yusuke Ando (@yando) PHPエラーの教室 90分間濃縮

90分間濃縮 PHPエラーの教室

  • Upload
    yandod

  • View
    9.526

  • Download
    8

Embed Size (px)

Citation preview

Page 1: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)Shimokita.php / Yusuke Ando (@yando)

PHPエラーの教室90分間濃縮

Page 2: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)Shimokita.php / Yusuke Ando (@yando)

Page 3: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

福岡でのボランティア急募!

Page 4: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

こんな経験はありませんか?

Page 5: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

画面が真っ白に

Page 6: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

画面にお経みたいなものがでる

Page 7: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

サーバのログがゴミ溜めになっている

Page 8: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

エラー正しく扱えていますか?

Page 9: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

Page 10: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

Page 11: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

PHPのエラーと例外に関する取り扱い方法を見ていきます

Page 12: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

エラーのイロハ

•何故エラーが起きるのか•エラー関連の設定•エラーハンドリング•例外処理

地味だけれど重要な知識

Page 13: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

何故エラーが起きるのか

Page 14: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

エラーとは

•PHPのスクリプトを実行する際の各段階で発生•構文解析時の問題•処理の実行中に発生する問題•拡張モジュールなどの外部プログラム内•ネットワーク処理など通信が発生した場合

状況に応じて正しい対処が異なる

Page 15: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

エラーの種類

重大度に応じてレベルが存在

種類 内容

E_ERROR / Fatal 実行不可能:処理は停止、白画面

E_WARNING / Warning 警告:実行時に問題発生、処理は継続

E_PARSE / Parse 解析不能:処理は始まらない、白画面

E_NOTICE / Notice 通知:問題になりうる状況、処理は継続

E_STRICT / E_DEPRECATED バージョン間の互換性に関するエラー

Page 16: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

何も出ないか、壊れた画面かの分かれ目

FATAL / PARSE

NOTICE / WARNING etc

Page 17: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

E_PARSE / Parse

シンプルな構文エラー

echo echo;

echo date()echo time()

•トークンの出現位置が不正•セミコロン忘れ、ブレースの対応関係•全角スペース混入

Page 18: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

E_ERROR / FATAL

コードが実行された時の状態が問題

$obj = 1;if ($obj === null) { $obj = getObject();}$obj->myFunc();

•構文は合っていたが、実行しようとした処理が失敗•関数名間違い、オブジェクトの取り違い•外部モジュールのエラー

Page 19: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

E_WARNING

エラーを検知してふさわしい処理が必要

$body = file_get_contents(‘hoge.txt’);echo “Hello”;

•処理は実行できたが、失敗してしまった場合•ファイルやネットワークの処理など•正常に処理を継続する事はおそらく難しい

Page 20: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

E_NOTICE

動いていたとしても危険性あり

if ($data == null) { echo ‘Hello’; echo HOGE;}

•未定義の変数、定数を使った場合•関数への引数が正しくない•考慮の足りないコードで発生しやすい

Page 21: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

E_STRICT / E_DEPRECATED

古い遺産で発生しやすく、不可避な場合も

class Sample{ function foo() { echo "Hi"; }}Sample::foo();

•PHP4の文法をPHP5で利用した場合•将来廃止される予定の機能を使った場合

Page 22: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

Segmentation Fault

•ログには”Segmentation Fault”とだけ記録される

サーバのアップデートなどが必要になる

Page 23: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

エラー関連の設定

Page 24: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

エラーが画面に出ない?

•発生したエラーを表示するかは設定次第•php.ini または htaccessなどの設定•実行時に設定を強制的に変更する事も可能•ini_set() error_reporting() display_errors()•エラーをログに記録するかどうかは別の設定

開発時は表示、運用時は記録が正しい

Page 25: 90分間濃縮 PHPエラーの教室

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

互換性エラーは無視

全てを検知、表示

表示はしない

Page 26: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

運用中のエラーを隠す理由

DB情報などが入る場合も

不具合の発生時に警告が出る場合

表示が崩れるかも

Page 27: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

こういうのは...

Page 28: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

これもダメ

<?php@trigger_error("Hi");echo "World";

強制的に無視

これを多用すると障害発生時に手がかり0

Page 29: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

エラーハンドリング

Page 30: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

エラーハンドリング

•エラーが発生した後に行う処理•発生したエラーのレベルに応じて処理が可能•標準のエラーハンドラはphp.iniの設定に応じた処理•任意の処理を登録する事も可能•エラーハンドラから元の処理にも戻れる•任意のエラーを起こす事も可能

フレームワークなどでも利用されている

Page 31: 90分間濃縮 PHPエラーの教室

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で元の場所へ復帰する

Page 32: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

エラーハンドリングの例2

Page 33: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

エラーハンドリングの後

ハードな運用を耐えているかの試金石

•処理が継続するWarningやNoticeの後には適切な処理•不足すると空っぽのリスト、崩れた画面などに繋がる

$body = file_get_contents(‘hoge.txt’);if ($body === false) { my_error(); exit;}echo “Hello”;

Page 34: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

重要なんです!

さすがPHP、エラー時の返り値がバラバ(ry

Page 35: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

例外処理

Page 36: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

例外処理

•PHP5から利用できるエラー処理•Javaなどの言語でも実績がある機構•誤った利用方法により有害無益になっている例多数•正しく使えばエラー処理がすごく楽になる•間違って使うと無駄にコードが多くなって、挙動も崩壊

これからは例外を使って行きたい

Page 37: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

例外処理の例

例外オブジェクトをthrowするとcatchに入る

function hoge(){ if (true) { throw new Exception('Error!'); }}try { hoge();} catch (Exception $e) { echo $e->getMessage(); exit;}

Page 38: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

例外オブジェクト•オブジェクトからエラー情報が取得可能•Exceptionをnewする時にセットされた情報を取得•getMessage getCode getFile getLine getTrace

Page 39: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

例外処理の失敗例

例外オブジェクトをreturn...

function hoge(){ if (true) { return new Exception('Error!'); }}try { hoge();} catch (Exception $e) { echo $e->getMessage(); exit;}

Page 40: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

例外処理の失敗例2

catchする例外の型が合っていない

function hoge(){ if (true) { throw new Exception('Error!'); }}try { hoge();} catch (Excepton $e) { echo $e->getMessage(); exit;}

Page 41: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

例外処理の失敗例3

catchしてもなにもしていない...

function hoge(){ if (true) { throw new Exception('Error!'); }}try { hoge();} catch (Exception $e) {

}

Page 42: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

例外処理に関する誤解

•try catchをたくさん書くのが正しいコード→きちんと書けば巨大なコードでもcatchは一箇所でよい•入力エラーなどでも例外処理を使うべき→通常発生しうるものは例外ではない•catchすればとりあえずはOK→catchするのはどうしても必要な場合のみ

正しく例外を扱うプロジェクトの稀な事

Page 43: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

例外処理の自動化

•catchされなかった例外が最終的に指定した関数へ到達

function handler($exception) { echo $exception->getMessage();}set_exception_handler(“handler”);

Page 44: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

まとめ

no more error_reporting(0);no more @hoge();

•「画面が白くなりました」は無意味•エラーの内容を確認しなければ対応は不可能•Noticeが多いからエラーを消すは本末転倒•通常稼働中はエラーが発生しないのが理想•ライブラリやプラグインがNoticeやWarningを垂れ流すのは非常に害が大きく、廃れる原因

Page 45: 90分間濃縮 PHPエラーの教室

Shimokita.php / Yusuke Ando (@yando)

質問?