在很久以前(也沒多久,我學PHP不到兩年)我就知道 PHP5 有例外處理,但是當時覺得PHP Exception 很腦殘,因為 PHP 函數庫不會拋出 Exception ....Orz,或許有人會想 PHP 函數又不像 JAVA 都是類別,但是也別忘了 PHP 是弱型別的。
以下先來看一下我覺得腦殘的範例....
try{ $handle = fopen("/tmp/inputfile.txt", "r"); //<-找不倒檔案! fclose($handle); mysql_connect('nobody','nodoby','nodoby'); //<-連線失敗! mysql_query('select * from notablae;') //<-沒有資料表! } catch(Exception $e){ echo $e->getMessage(); }
注意到了嗎,上面的例子是不會拋出任何例外的,尤其是最近看到一篇文章 腦殘 PHP: Codeigniter是萬靈丹? 才發覺這其實是 PHP 根本性的問題了。為什麼事根本性問題?翻開坊間上 PHP 的書,不外乎會像下面這樣寫,就連官方 PHP 也是。
if(isset($_REQUEST['age'])){ $age = $_REQUEST['age']; $link = mysql_connect('localhost', 'mysql_user', 'mysql_password') or die('Could not connect: ' . mysql_error()); $result = mysql_query("SELECT * from table where age<{$age};"); if ($result) { while ($row = mysql_fetch_assoc($result)) { echo $row['firstname']; echo $row['lastname']; echo $row['address']; echo $row['age']; } } }
就算官方一直推 PDO 有推好像沒推一樣,另外 PDO 已經包含例外處理,非常好用,是值得大家去學習的。 最後實做把上面例子改寫一下。
//先建一個公用函數,來檢查 $_REQUEST 值。 function __GET($key=''){ if($key!='' && isset($_GET[$key])){ return $_GET[$key]; } throw new Exception("Input 錯誤"); return null; } //接下來我還需要建立一個例外處理 class MysqlException extends Exception {} try{ if(!$link = @mysql_connect('localhost', 'mysql_user', 'mysql_password')){ //用PHP的錯誤控制運算式不是一個很好的方法 //推薦方式用set_error_handler把所有錯誤訊息給隱藏掉 throw new MysqlException(mysql_error()); } $age = (int)__GET("age"); if (!$result = @mysql_query("SELECT * from table where age<{$age};")){ throw new MysqlException(mysql_error()); } //我記得某些情形直接用while會發生錯誤,比較保守的方法是取得資源的長度在用 for 列出來。 while ($row = mysql_fetch_assoc($result)) { echo $row['firstname']; echo $row['lastname']; echo $row['address']; echo $row['age']; } } catch(MysqlException $e){ //在這邊決定要不要列出資料庫錯誤訊息!! echo $e->getMessage(); } catch(Exception $e){ echo "你玩壞我的主機了!!"; echo $e->getMessage(); }
我的結論:
看起來異常處理好像寫了很多行,但是也不全然沒好處,如果今天在加上 html 樣式,用 die 寫的話自己可能也跟這死一半。然後另一方面最好能用 PDO 寫就用PDO 寫,然後像我現在沒辦法用 PDO 寫就把 Mysql 和 pgsql 包成類別在包含異常處理就可以減掉好幾行程式,然後異常處理可以分層級就像 MysqlException。
最近才在 Android 上學玩一輪 JAVA 再回來寫 PHP ,所以也發覺異常處理上的某些好處,反正 PHP 鳥也不是一天兩天的是,從鳥 PHP 上我也學不少東西,特別是 PHP 的鳥問題,讓我學完一輪非常基礎的程式設計,只是目前在 PHP 類別上還是很難找到突破點。或許明天計畫可以考慮把 Ruby on Rails 和 zend framework 加進來學習了。
0 意見:
張貼留言