槽吐吐,最近在看一本叫《代碼簡潔之道》的書,書中講了如何讓自己的代碼變得容易讀懂,受益匪淺。有興趣的朋友可以看看。
PHPer很少使用異常,即時是公司裡的大牛,也不見得會使用異常。更多情況下,異常僅僅被當作error code的另外一個實現體而已。我記得我在前面的博客裡還說到過異常,貌似木有人支持啊。
想象一下:一個代碼裡出現了如下情況:
[php]
<?php
if(($retCode = fun1()) == 0){
$html = "Hello,world";
if(($retCode = fun2()) == 0){
if(($retCode = fun3()) == 0){
}else{
//出錯了
}
}else{
//出錯了
}
}else{
//出錯了
}
<?php
if(($retCode = fun1()) == 0){
$html = "Hello,world";
if(($retCode = fun2()) == 0){
if(($retCode = fun3()) == 0){
}else{
//出錯了
}
}else{
//出錯了
}
}else{
//出錯了
}
上面的代碼,熟悉麼?之前看discuz的源碼時,有一段代碼有類似的結構,這樣寫,代價確實很大,尤其是後面的人來讀這段代碼的時候。我們確實沒有重構的習慣,使用異常重構,可以很好解決這個問題
[php]
<?php
try{
fun1();
fun2();
fun3();
}catch(Exception_FUNC_1 $e){
//錯誤處理
}catch(Exception_FUNC_2 $e){
//錯誤處理
}catch(Exception_FUNC_3 $e){
//錯誤處理
}
<?php
try{
fun1();
fun2();
fun3();
}catch(Exception_FUNC_1 $e){
//錯誤處理
}catch(Exception_FUNC_2 $e){
//錯誤處理
}catch(Exception_FUNC_3 $e){
//錯誤處理
}
是不是好點?還可以再優化麼?
[php]
<?php
try{
fun1();
fun2();
fun3();
}catch(Exception $e){
echo $e->getMessage();
}
function fun1(){
throw new Exception("Your input is empty", 10001);
}
<?php
try{
fun1();
fun2();
fun3();
}catch(Exception $e){
echo $e->getMessage();
}
function fun1(){
throw new Exception("Your input is empty", 10001);
}
好處是什麼?
1. 你可以專注與正常的流程,而不用關心出錯了會怎麼辦
2. 將錯誤的部分統一處理,返回錯誤、日志、回溯
3. 隨意增加錯誤類型,因為本身是自定義,你不用維護一套error code
4. 代碼結構清晰,維護代價低
5. 特有的類維護自己的異常,如:smarty、phpunit,出錯了有自己的記錄方式,與所處的系統無耦合
看個人習慣,我個人極力推薦
有這麼一個需求:
我想將一個變量(可能為數組、字符串、數字),可以輸出到文件裡,使這個文件被別的php文件include後,使用這個變量,即:
[php]
<?php
$a = array(
0 => 'abc',
1 => array(
'abc' => '2345'
)
);
//輸出到文件的內容是:
{
return array(
0 => 'abc',
1 => array(
'abc' => '2345'
)
);
}
<?php
$a = array(
0 => 'abc',
1 => array(
'abc' => '2345'
)
);
//輸出到文件的內容是:
{
return array(
0 => 'abc',
1 => array(
'abc' => '2345'
)
);
}
然後,下一個文件include後是:
[php]
$a = include("file.php");
$a = include("file.php");
它就擁有了這個數據了。
具體什麼場合下用到,我們將內存中的數據放到硬盤中,除了serialize外,這也是一種方便的做法,因為不需要unserialize。不好的一點是:沒法對對象、句柄做操作。
我是這麼寫的:
[php]
<?php
class Code
{
/**
* 將變量轉化為字符串
*
* @param mixed $var 僅包含字符串、數字、數組的變量
* @param string $pfx 前綴,輸出的內容容易被讀
*
* @return string
*/
public function var2Str($var, $pfx = ''){
$str = '';
if(is_array($var)){
$str = "array(\n";
$pfx .= "\t";
foreach($var as $k => $v){
if(is_string($k)){
$k = "\"{$k}\"";
}
$str .= $pfx . "{$k} => " . $this->var2Str($v, $pfx) . ",\n";
}
$str .= $pfx . ")";
}elseif(is_int($var) || is_float($var)){
$str = "{$var}";
}elseif(is_string($var)){
$str = "\"{$var}\"";
}
return $str;
}
}
<?php
class Code
{
/**
* 將變量轉化為字符串
*
* @param mixed $var 僅包含字符串、數字、數組的變量
* @param string $pfx 前綴,輸出的內容容易被讀
*
* @return string
*/
public function var2Str($var, $pfx = ''){
$str = '';
if(is_array($var)){
$str = "array(\n";
$pfx .= "\t";
foreach($var as $k => $v){
if(is_string($k)){
$k = "\"{$k}\"";
}
$str .= $pfx . "{$k} => " . $this->var2Str($v, $pfx) . ",\n";
}
$str .= $pfx . ")";
}elseif(is_int($var) || is_float($var)){
$str = "{$var}";
}elseif(is_string($var)){
$str = "\"{$var}\"";
}
return $str;
}
}