例外情報のキャプチャは、プログラミングテストにとって非常に重要です。ここでは、オブザーバーモードを組み合わせて、例外情報を処理する方法を検討します。
オブザーバー モードについてまだ知らない場合は、ブログ ガーデンに多くの優れたブロガーが詳しく説明しています。著者は、いわゆるオブザーバー パターンには 2 つの重要なコンポーネントが必要であると感じています。それは、サブジェクト オブジェクトと複数のオブザーバーです。これを使用する場合、オブザーバーをプラグのようにテーマ オブジェクトのソケットに接続し、テーマ オブジェクトを使用して対応する機能を実行できます。
オブザーバーはプラグとして使用されるため、同じソケットに接続するには統一された口径が必要です。そのため、最初にインターフェイスを定義します。Exception_Observer.php:
1 2 3 4 5 6 7 8 | <?<span>php
</span><span>
</span><span> interface </span><span> Exception_Observer{
</span><span> public </span><span> function </span> update(Observer_Exception <span> $e </span><span>);
}
</span>?>
|
ログイン後にコピー
多くのオブザーバーと比較して、最初に焦点を当てる必要があります。唯一のテーマ オブジェクト Observer_Exception.php:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <?<span>php
</span><span> class </span> Observer_exception <span> extends </span><span>Exception</span><span>{
</span><span> public </span><span> static </span><span> $_observers </span>=<span> array </span><span>();
</span><span> public </span><span> static </span><span> function </span> attach(Exception_Observer <span> $observer </span><span>){
self</span>::<span> $_observers </span>[]=<span> $observer </span><span>;
}
</span><span> public </span><span> function </span> __construct(<span> $message </span>=<span>null</span>,<span> $code </span>=0<span>){
parent</span>::__construct(<span> $message </span>,<span> $code </span><span>);
</span><span> $this </span>-><span>notify();
}
</span><span> public </span><span> function </span><span> notify(){
</span><span> foreach </span> (self::<span> $_observers </span><span> as </span><span> $observer </span><span>) {
</span><span> $observer </span>->update(<span> $this </span><span>);
}
}
}</span>
|
ログイン後にコピー
挿入されたオブザーバーを配置するために静的変数 $_observers が使用され、すべてのオブザーバー オブジェクトに通知するために notify() が使用されていることが明確にわかります。
ここで注意が必要なのは、$this内の$observer->update($this);の使い方です。 this「こんな使い方もできます。」 小さな質問:
$_observers 静的変数でなくても大丈夫ですか? この質問については後でお答えします。 2つのオブザーバーを定義し、原則としてインターフェースで定義された関数を実装します。
Email_Exception_Observer.php:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <span> class </span> Emailing_Exception_Observer <span> implements </span><span> Exception_Observer{
</span><span> protected </span><span> $_email </span>= "huanggbxjp@sohu.com" <span>;
</span><span> function </span> __construct(<span> $email </span>=<span>null</span><span>)
{
</span><span> if </span> (<span> $email </span>!==<span>null</span>&&filter_var(<span> $email </span>,<span>FILTER_VALIDATE_EMAIL)) {
</span><span> $this </span>->_email=<span> $email </span><span>;
}
}
</span><span> public </span><span> function </span> update(Observer_Exception <span> $e </span><span>){
</span><span> $message </span>= "时间" .<span> date </span>( "Y-m-d H:i:s" ).<span>PHP_EOL</span><span>;
</span><span> $message </span>.= "信息" .<span> $e </span>->getMessage().<span>PHP_EOL</span><span>;
</span><span> $message </span>.= "追踪信息" .<span> $e </span>->getTraceAsString().<span>PHP_EOL</span><span>;
</span><span> $message </span>.= "文件" .<span> $e </span>->getFile().<span>PHP_EOL</span><span>;
</span><span> $message </span>.= "行号" .<span> $e </span>->getLine().<span>PHP_EOL</span><span>;
</span><span> error_log </span>(<span> $message </span>,1,<span> $this </span>-><span>_email);
}
}</span>
|
ログイン後にコピー
Logging_Exception_Observer.php:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <?<span>php
</span><span> class </span> Logging_Exception_Observer <span> implements </span><span> Exception_Observer
{
</span><span> protected </span><span> $_filename </span>= "F:/logException.log" <span>;
</span><span> function </span> __construct(<span> $filename </span>=<span>null</span><span>)
{
</span><span> if </span> (<span> $filename </span>!==<span>null</span>&&<span> is_string </span>(<span> $filename </span><span>)) {
</span><span> $thvis </span>->_filename=<span> $filename </span><span>;
}
}
</span><span> public </span><span> function </span> update(Observer_Exception <span> $e </span><span>){
</span><span> $message </span>= "时间" .<span> date </span>( "Y-m-d H:i:s" ).<span>PHP_EOL</span><span>;
</span><span> $message </span>.= "信息" .<span> $e </span>->getMessage().<span>PHP_EOL</span><span>;
</span><span> $message </span>.= "追踪信息" .<span> $e </span>->getTraceAsString().<span>PHP_EOL</span><span>;
</span><span> $message </span>.= "文件" .<span> $e </span>->getFile().<span>PHP_EOL</span><span>;
</span><span> $message </span>.= "行号" .<span> $e </span>->getLine().<span>PHP_EOL</span><span>;
</span><span> error_log </span>(<span> $message </span>,3,<span> $this </span>-><span>_filename);
}
}</span>
|
ログイン後にコピー
すべての主要なオブジェクトとプラグインを設計した後、小さなテストを実行しましょう:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <?<span>php
</span><span> require </span> 'Exception_Observer.php' <span>;
</span><span> require </span> 'Observer_Exception.php' <span>;
</span><span> require </span> 'Logging_Exception_Observer.php' <span>;
</span><span> require </span> 'Emailing_Exception_Observer.php' <span>;
Observer_Exception</span>::attach(<span> new </span><span> Logging_Exception_Observer());
</span><span> class </span> MyException <span> extends </span><span> Observer_Exception{
</span><span> public </span><span> function </span><span> test(){
</span><span> echo </span> 'this is a test' <span>;
}
</span><span> public </span><span> function </span><span> test1(){
</span><span> echo </span> "我是自定义的方法处理这个异常" <span>;
}
}
</span><span> try </span><span> {
</span><span> throw </span><span> new </span> MyException( "出现异常,记录一下" <span>);
} </span><span> catch </span> (MyException <span> $e </span><span>) {
</span><span> echo </span><span> $e </span>-><span>getMessage();
</span><span> echo </span> "<ht/>" <span>;
}
</span>?>
|
ログイン後にコピー
この例では、最初にオブザベーションをロードします。その後、他の操作を実行します。上で挙げた質問に戻りますが、
$_observers は静的変数ではないでしょうか?答えはいいえだ。 $_observers が静的変数ではない場合、オブザーバーをロードする動作は後続の操作に影響を与えません。 static を使用すると、すべてのインスタンス メンバーが変数を共有できます。クラスの継承も同様に機能します。興味があれば、静電気の魔法の効果を引き続き探索してください。 この例は、出力が一般的な状況と変わらないことを示していますが、違いは、対応するログがカスタマイズされたファイルの下に生成されていることです。最終的な関数は単純ですが、多くの人はより少ないコードで簡単な方法で実装することもできます。ただし、より複雑なシステムを実装する場合、オブザーバー パターンは非常に便利です。
上記は、例外情報を処理するためのオブザーバー モードの使用方法を、内容の側面も含めて紹介しました。PHP チュートリアルに興味のある友人に役立つことを願っています。