為什麼要有例外處理?¶
原文在 2024-05-14 完成
假設 PHP 沒有例外機制,那會怎樣呢?
建立一個函式 sum1()
,會回傳兩個參數的總和。參數必須是可以加總的數字,所以 sum1()
的定義中,大部分的程式碼在檢查參數類型,實作功能的程式碼只有 return $x + $y;
而已。
<?php
$x = function() {
return 1;
};
$y = 2;
printf(sum1($x, $y));
function sum1($x, $y)
{
if( is_string($x) ) {
printf('$x is a string' . PHP_EOL);
exit;
} else if ( is_string($y) ) {
printf('$y is a string' . PHP_EOL);
exit;
}
if( is_callable($x) ) {
printf('$x is a callable object' . PHP_EOL);
exit;
} else if ( is_callable($y) ) {
printf('$y is a callable object' . PHP_EOL);
exit;
}
if( is_object($x) ) {
printf('$x is an object' . PHP_EOL);
exit;
} else if ( is_object($y) ) {
printf('$y is an object' . PHP_EOL);
exit;
}
return $x + $y;
}
即使有例外機制,也常常可以看到這樣的程式碼:
<?php
sum1($x, $y)
{
if( is_string($x) ) {
throw new Exception('$x is a string');
} else if ( is_string($y) ) {
throw new Exception('$y is a string');
}
if( is_callable($x) ) {
throw new Exception('$x is a callable object');
} else if ( is_callable($y) ) {
throw new Exception('$y is a callable object');
}
if( is_object($x) ) {
throw new Exception('$x is an object');
} else if ( is_object($y) ) {
throw new Exception('$y is an object');
}
return $x + $y;
}
這和一開始的範例並無區別,都是產生錯誤訊息,停止執行程式,增加大量的檢查。
如果有 sum2()
定義如下,只有實作功能的程式碼,不需要檢查參數:
<?php
function sum2($x, $y)
{
return $x + $y;
}
不應該認為使用者會照規矩呼叫程式,應該假設他們會丟各種奇怪的參數進來,必須事先做好防範,但是又要保持函式定義乾淨簡單,所以用例外機制,把錯誤往外丟,在其它地方處理:
<?php
try {
$x = function() {
return 2;
};
$y = 3;
sum2($x, $y);
} catch (Throwable $e) {
printf("something wrong happen! at line %s of file %s, and message is %s\n",
$e->getLine(),
$e->getFile(),
$e->getMessage()
);
}
PHP 還有 set_exception_handler()
和 set_error_handler()
,不用到處都是 try catch
,可以統一在這兩個函式處理所有例外事件。