本文實例講述了PHP使用觀察者模式處理異常信息的方法。分享給大家供大家參考,具體如下:
異常信息的捕獲對編程測試有著重要的意義,這里結合觀察者模式,探索如何處理異常信息。
關于觀察者模式,如果還沒有接觸過的話,博客園有很多優秀的博友做了詳細的 解釋。筆者覺得,所謂觀察者模式,必須有兩個重要組成部分:一個主題對象,多個觀察者。在使用的時候,我們可以將觀察者像插頭一樣插到主題對象這個插座上,利用主題對象完成相應功能。
既然觀察者要作為插頭,必須要有一個統一的口徑才能插到相同的插座上,因而先定義一個接口,Exception_Observer.php:
1
2
3
4
5
6
7
8
|
<?php /** * 定義的規范 */ interface Exception_Observer{ public function update(Observer_Exception $e ); } ?> |
相對于眾多觀察者,我們首先應該關注唯一的主題對象,Observer_Exception.php:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<?php class Observer_exception extends Exception{ public static $_observers = array (); public static function attach(Exception_Observer $observer ){ self:: $_observers []= $observer ; } public function __construct( $message =null, $code =0){ parent::__construct( $message , $code ); $this ->notify(); } public function notify(){ foreach (self:: $_observers as $observer ) { $observer ->update( $this ); } } } |
我們可以清楚地看到,靜態變量$_observers用來放置插入的觀察者,notify()用來通知所有觀察者對象。
這里需要注意 $observer->update($this);
里面 $this
的用法,很多初學者會感到“原來 $this
也可以這么用啊”。
一個小問題: $_observers
不是靜態變量可不可以? 這個問題我們后面回答。
定義兩個觀察者,原則上實現接口所定義的功能。
Email_Exception_Observer.php:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
class Emailing_Exception_Observer implements Exception_Observer{ protected $_email = "huanggbxjp@sohu.com" ; function __construct( $email =null) { if ( $email !==null&&filter_var( $email ,FILTER_VALIDATE_EMAIL)) { $this ->_email= $email ; } } public function update(Observer_Exception $e ){ $message = "時間" . date ( "Y-m-d H:i:s" ).PHP_EOL; $message .= "信息" . $e ->getMessage().PHP_EOL; $message .= "追蹤信息" . $e ->getTraceAsString().PHP_EOL; $message .= "文件" . $e ->getFile().PHP_EOL; $message .= "行號" . $e ->getLine().PHP_EOL; error_log ( $message ,1, $this ->_email); } } |
Logging_Exception_Observer.php:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<?php class Logging_Exception_Observer implements Exception_Observer { protected $_filename = "F:/logException.log" ; function __construct( $filename =null) { if ( $filename !==null&& is_string ( $filename )) { $thvis ->_filename= $filename ; } } public function update(Observer_Exception $e ){ $message = "時間" . date ( "Y-m-d H:i:s" ).PHP_EOL; $message .= "信息" . $e ->getMessage().PHP_EOL; $message .= "追蹤信息" . $e ->getTraceAsString().PHP_EOL; $message .= "文件" . $e ->getFile().PHP_EOL; $message .= "行號" . $e ->getLine().PHP_EOL; error_log ( $message ,3, $this ->_filename); } } |
設計完所有該有的主體對象和插件,我們做個小小的測試:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
<?php require 'Exception_Observer.php' ; require 'Observer_Exception.php' ; require 'Logging_Exception_Observer.php' ; require 'Emailing_Exception_Observer.php' ; Observer_Exception::attach( new Logging_Exception_Observer()); class MyException extends Observer_Exception{ public function test(){ echo 'this is a test' ; } public function test1(){ echo "我是自定義的方法處理這個異常" ; } } try { throw new MyException( "出現異常,記錄一下" ); } catch (MyException $e ) { echo $e ->getMessage(); echo "<ht/>" ; } ?> |
本實例首先先加載觀察者,其后進行其他操作。回到上面提出的問題, $_observers
可以不是靜態變量嗎?答案是不可以。如果 $_observers
不是靜態變量,加載觀察者的行為對后續操作沒有影響。static
讓所有實例成員共享某個變量。即便類繼承也同樣有效。有興趣的可以繼續探索下static的神奇作用吧。
本例顯示輸出與一般情況無異,但不同的是已在自定義的文件下生成了相應的日志。雖然最后實現的功能再簡單不過,很多人甚至可以用更少的代碼更簡單的方法實現,但是,在實現更加復雜系統的情況下,觀察者模式給我們帶來很大方便。
希望本文所述對大家PHP程序設計有所幫助。
原文鏈接:https://www.cnblogs.com/DeanChopper/p/4726773.html