このトピックを書くというアイデアは、勇敢に2つの質問をしたときに生まれました。
- テンプレートの指定された場所への警告とエラー出力の傍受に関する質問
- スクリプトの実行を停止させる重大なエラーの捕捉に関する質問
私のカルマとお気に入りに追加することで、PHP habrasocietyにとって興味深いことがわかった。 このため、人々や検索エンジンが必要な情報を見つけやすくするために、これらの問題の解決策を記事の形で作成することにしました。
興味があるなら、カットの下の詳細...
使用理由
ユーザー/検索エンジンは、サーバーに問題があることを明確に答える必要があります。 特定の風水を使用しないと、これを達成するのは難しく、時には不可能です。 1週間前に何をすべきかわからなかったので、ここですべてを明らかにし、メモを残します。おそらく多くの新人もがっかりするでしょう。
機能説明
この機能は、エラーを処理し、出力を制御するためにPHPで使用できます。 ここに彼らの長所と短所の説明があります。 私はドキュメントを提供しません、私はそのページを参照して、私の意見を説明するだけです。 提供されるのはごく一部であり、記事の最後にドキュメントの関連セクションへのリンクを提供します。 だから私たちは会います:
-重大ではないエラーの制御:コメント、警告、ユーザーエラー。 一般に、解釈を異常に完了しないすべてのもの。
set_error_handler-ユーザー定義のエラーハンドラを定義します。
そのようなエラーをすべてログに書き込むために必要です。 設定されていない場合、これはログに書き込まれませんが、どの戦闘状況でコメントや警告を呼び出すことができるかを常に知りたいです。 つまり、ユーザーが製品を自動的にテストでき、ユーザーもそれに気付かないでしょう。
関数が指定されていない場合、PHPはデータを画面に表示しようとしているだけです。これが指定されていない場合、これらのタイプのエラーによる生命の兆候はありません。
-制御、例外:タイプE_ERRORのエラーです。
set_exception_handler-カスタム例外ハンドラーを定義する
さて、以下で説明されているものがあり、例外のようなエラーを処理しているだけで、なぜこれが考えられたのかわかりません。 それで、私はそれが単に存在することを知らせます。 重大なエラー「例外」をインターセプトし、それを使用して何かを実行できるようにします。 いずれにせよ、スクリプトは終了します。 デフォルトでは、彼女の仕事は個人的には十分です(ログに書き込み、画面に表示しようとします)。 それをまったく再定義しません。そうしないと、発生した例外についてログに書き込む必要があります。
-出力制御機能:ここでは、さまざまな理由で知られるべき3つの機能について説明します。 たとえば、 パフォーマンスの問題やヘッダー出力の問題の場合。 この場合、エラーヘッダーが必要です。
ob_start-出力バッファリングを有効にする
ob_flush-出力バッファをフラッシュ (送信)する
ob_end_clean-出力バッファーをクリア(消去)し、出力バッファーを無効にします
つまり、これらの関数を使用すると、エコー経由ですべてのデータ出力をバッファーに書き込むことができます。 この機能を使用すると、コードの任意の部分でヘッダーを送信したり、トピックがこの記事に関係のない他の多くのものを送信したりできます。 そして、突然災害が発生した場合。 バッファー全体とスタック全体をフラッシュし(この記事には記載されていません)、エラーヘッダーを記述し、ユーザーに通知を表示できます。
-発生した最後のエラーの取得:ここで説明する他のインターセプト関数と一緒に使用する必要があります。
error_get_last-発生した最後のエラーに関する情報を取得する
これを使用すると、最後のエラーを返すことができます。 彼女が重大なエラーをキャッチするとコードが最適になります(その場合は5.2.xから表示されます)。
-すべてが機能した後に開始する機能:ドラムロール。
register_shutdown_function-スクリプトの完了時に実行される関数を登録します。 完了は定期的でも緊急でも、違いはありません。
多くのプラスとマイナスなし:
- この関数は再定義されていませんが、追加で定義されており、何度でも定義できます
- 再定義されていないため、すべてのエラーはとにかくログにすでに書き込まれているため、再定義する必要はありません。
- ドキュメントで説明されているように、この関数はまだコンテンツを送信しません。したがって、バッファリング関数を使用できます
多くのオブジェクト指向の人々が喜ぶ
上記のすべての関数は、クラスメソッドでも、おそらく静的クラスメソッドでも同じ方法で登録できます。 確かに、この方法は通常の非PHPプログラマーの目にはあまり明らかではありません。
ハンドラパラメータは、「クラス名|オブジェクト」、「オブジェクトメソッド」という要素を持つ配列を介して設定する必要があります。 インストールされたメソッドはパブリックでなければなりません。 set_error_handler関数の例:
<?php class BaseErrorCatcher { public function __construct() { set_error_handler(array($this, 'ErrorCatcher')); echo ", \n"; $errorVarArray['real index'] = true; echo $errorVarArray['error index']; } public function ErrorCatcher($errno, $errstr) { echo ", - : $errstr\n"; } } error_reporting(E_ALL | E_STRICT); // ini_set('display_errors','On'); // new BaseErrorCatcher(); // ?>
結果:
私が作った友達 友人、はい、おそらくあなたはこれのどこかで台無しにした:未定義のインデックス:エラーインデックス
実施例
作業例、汎用的かつ完全なエラー制御のためのクラスアーキテクチャ。 私はこの質問を非常に徹底的に調査し、 私が尋ねた質問への回答からハイブリッド法をまとめました。
条件
最初に起動されるコードを含むファイルがあります。そうしないと、コードの前にエラーが表示され、このファイルとそれ以前のすべてのファイルが100%デバッグされ、エラーは発生しません。 上記の機能のすべての登録が完了するまで、エラーのない、より単純な条件を次に示します。 このファイルには、複合施設内のエラー制御技術のデータが記述されています。 エラーの場合、バッファーが制御され、バッファーがフラッシュされ、エラーが表示されます。
コメント付きのコード
コードはテストされていないことを自分から付け加えます。これは、コード内にあるものの簡略化されたスキームであるため、コメントを受け付けています
<?php class ErrorSupervisor { public function __construct() { // set_error_handler(array($this, 'OtherErrorCatcher')); // register_shutdown_function(array($this, 'FatalErrorCatcher')); // ob_start(); } public function OtherErrorCatcher($errno, $errstr) { // : // - return false; } public function FatalErrorCatcher() { $error = error_get_last(); if (isset($error)) if($error['type'] == E_ERROR || $error['type'] == E_PARSE || $error['type'] == E_COMPILE_ERROR || $error['type'] == E_CORE_ERROR) { ob_end_clean(); // , // : // - // - 500 // - } else { ob_end_flush(); // , } else { ob_end_flush(); // , } } } // $errorController = new ErrorSupervisor(); // // , echo " "; // ( , ) include 'null'; // OtherErrorCatcher // require 'null'; // FatalErrorCatcher // require 'foobar.php'; // ?>
参照資料
ドキュメントセクション
その他の有用な情報
- PHPエコー関数は1秒以上実行できます
- 事前定義された定数 -エラーのタイプでもあります
ご清聴ありがとうございました。
UPD:コメントからのアドバイスに基づき、ErrorSupervisorクラスに新しい機能を追加し、いくつかのエラーを修正し、トピックに関する興味深い情報を追加し、コードを少しデバッグしました
UPD2注意:PHPの知識を持つ友人が、この記事のトピックに間に合うようにPHPのビット操作に関する良い記事を書いたので 、読むことをお勧めします。 この知識により、コードをよりエレガントに書くことができます。 意味を維持するために、この記事のテキストを変更し始めませんでした。