質問
基本的なことのいくつかは理解していますが、さらに知りたいのは、特にライブ サイトや Web アプリで、PHP でエラー処理 (例外のスローを含む) をいつ、そしてなぜ使用する必要があるのかということです。それはオーバーユースの可能性のあるものですか?もしそうなら、オーバーユースとはどのようなものですか?使用してはいけないケースはありますか?また、エラー処理に関して一般的なセキュリティ上の懸念事項にはどのようなものがありますか?
解決
すでに述べたことに 1 つ付け加えておきたいのは、Web アプリケーションのエラーをログに記録することが最も重要であるということです。こうすることで、Jeff "Coding Horror" Atwood 氏が示唆しているように、ユーザーがアプリで問題に直面しているときに (「何が問題なのかを尋ねる」のではなく) 知ることができます。
これを行うには、次のタイプのインフラストラクチャをお勧めします。
- データベースに「クラッシュ」テーブルを作成し、エラーを報告するためのラッパー クラスのセットを作成します。クラッシュのカテゴリ(「ブロック」、「セキュリティ」、「PHP エラー/警告」(対例外)など)を設定することをお勧めします。
- すべてのエラー処理コードで、必ずエラーを記録してください。これを一貫して行うかどうかは、API (上記のステップ) をどの程度適切に構築したかによって異なります。 つまらない 正しく実行されればクラッシュを記録します。
追加クレジット:場合によっては、クラッシュがデータベース レベルのクラッシュになることがあります。つまりDBサーバーダウンなどその場合、エラー ログ インフラストラクチャ (上記) は失敗します (ログが DB に書き込もうとするため、クラッシュを DB に記録できません)。その場合、クラッシュ ラッパー クラスにフェイルオーバー ロジックを次のいずれかに書きます。
- 管理者にメールを送信する、および/または
- クラッシュの詳細をプレーンテキストファイルに記録する
これはすべてやりすぎのように聞こえますが、信じてください。これは、あなたのアプリケーションが「安定した」ものとして受け入れられるか、「不安定な」ものとして受け入れられるかに違いをもたらします。この違いは、すべてのアプリが常に不安定またはクラッシュして開始されるという事実から来ていますが、アプリのすべての問題を知っている開発者には、実際にそれを修正するチャンスがあります。
他のヒント
大まかに言えば、エラーは PHP の伝統であり、例外はエラーを処理する最新の方法です。最も簡単なのは、例外をスローするエラー ハンドラーを設定することです。そうすれば、すべてのエラーが例外に変換され、1 つのエラー処理スキームで簡単に対処できます。次のコードは、エラーを例外に変換します。
function exceptions_error_handler($severity, $message, $filename, $lineno) {
if (error_reporting() == 0) {
return;
}
if (error_reporting() & $severity) {
throw new ErrorException($message, 0, $severity, $filename, $lineno);
}
}
set_error_handler('exceptions_error_handler');
error_reporting(E_ALL ^ E_STRICT);
ただし、コードがエラーに対処するように特別に設計されているケースもいくつかあります。たとえば、 schemaValidate
の方法 DomDocument
ドキュメントを検証するときに警告が表示されます。エラーを例外に変換すると、最初の失敗後に検証が停止します。これが必要な場合もありますが、ドキュメントを検証する場合は、実際には次のようにする必要があるかもしれません。 全て 失敗。この場合、エラーを収集するエラー ハンドラーを一時的にインストールできます。以下はその目的のために使用した小さなスニペットです。
class errorhandler_LoggingCaller {
protected $errors = array();
function call($callback, $arguments = array()) {
set_error_handler(array($this, "onError"));
$orig_error_reporting = error_reporting(E_ALL);
try {
$result = call_user_func_array($callback, $arguments);
} catch (Exception $ex) {
restore_error_handler();
error_reporting($orig_error_reporting);
throw $ex;
}
restore_error_handler();
error_reporting($orig_error_reporting);
return $result;
}
function onError($severity, $message, $file = null, $line = null) {
$this->errors[] = $message;
}
function getErrors() {
return $this->errors;
}
function hasErrors() {
return count($this->errors) > 0;
}
}
そしてユースケース:
$doc = new DomDocument();
$doc->load($xml_filename);
$validation = new errorhandler_LoggingCaller();
$validation->call(
array($doc, 'schemaValidate'),
array($xsd_filename));
if ($validation->hasErrors()) {
var_dump($validation->getErrors());
}
アンハンド エラーはスクリプトを停止します。それだけでも、ハンドド エラーを処理する十分な理由になります。
一般に、Try-Catch ブロックを使用してエラーに対処できます。
try
{
// Code that may error
}
catch (Exception $e)
{
// Do other stuff if there's an error
}
ページに表示されるエラーまたは警告メッセージを停止したい場合は、呼び出しの前に @ 記号を付けることができます。
@mysql_query($query);
ただし、クエリの場合は、何が起こっているかをよりよく理解できるように、このようなことを行うことは一般に良い考えです。
@mysql_query($query)
or die('Invalid query: ' . mysql_error() . '<br />Line: ' . __LINE__ . '<br />File: ' . __FILE__ . '<br /><br />');
スクリプトが処理しているデータを明示的に制御できない場合は、エラー処理を使用する必要があります。たとえばフォーム検証などの場所で頻繁に使用する傾向があります。コード内のエラーが発生しやすい箇所を特定する方法を知るには、ある程度の練習が必要です。よくあるのは、値を返す関数呼び出しの後、またはデータベース クエリの結果を処理するときです。関数からの戻り値が期待どおりであるとは決して想定しないでください。必ず予測してコードを作成する必要があります。try/catch ブロックは便利ですが、必ずしも使用する必要はありません。多くの場合、単純な if/else チェックで対処できます。
スクリプトのクラッシュを引き起こすだけではない「エラー」が多数存在するため、エラー処理は安全なコーディングの実践と密接に関連しています。エラー処理自体について厳密に説明しているわけではありませんが、addedbytes には安全な PHP プログラミングの基本に関する優れた 4 つの記事シリーズがあります。 ここ. 。stackoverflow には他にも次のようなトピックに関する質問がたくさんあります。 mysql_real_escape_string そして 正規表現 これは、ユーザーが入力したデータの内容を確認するのに非常に強力です。
私のベストプラクティスは、次のアプローチを使用することです。1.エラー/例外ハンドラーを作成します2。アプリの起動時に起動します3。すべてのエラーを内部から処理します
<?php
クラスデバッグ {
public static setAsErrorHandler() {
set_error_handler(array(__CLASS__, '__error_handler'));
}
public static function __error_handler($errcode, $errmsg, $errfile, $errline) {
if (IN DEV) {
print on screen
}
else if (IN PRO) {
log and mail
}
}
}
Debug::setAsErrorHandler();
?>
mysql_error を出力するのではなく、ログに保存することもできます。そうすれば、エラーを追跡でき (ユーザーによる報告に依存しなくても済みます)、問題を解決することができます。
最良のエラー処理はユーザーに透過的なものであり、コードで問題を解決し、他のユーザーを関与させる必要はありません。
コード内でエラーをすぐに処理するだけでなく、以下を利用することもできます。
http://us.php.net/manual/en/function.set-Exception-handler.php
そして
http://us.php.net/manual/en/function.set-error-handler.php
独自の例外ハンドラーを設定するのは特に便利だと思います。例外が発生した場合、例外の種類に応じてさまざまな操作を実行できます。
元:いつ mysql_connet
コールリターン FALSE
私は投げます new DBConnectionException(mysql_error())
そしてそれを「特別な」方法で処理します。エラー、DB 接続情報 (ホスト、ユーザー名、パスワード) などをログに記録し、DB に実際に問題がある可能性があることを開発チームに電子メールで通知することもできます。
私はこれを標準のエラー処理を補完するために使用します。このアプローチを多用することはお勧めしません
@ によるエラー抑制は非常に遅いです。
また、Google フォームを使用すると、データベースや公的にアクセス可能なサーバーを維持することなく、例外をキャッチして分析することもできます。チュートリアルがあります ここ それはプロセスを説明します。