ILi*_*cos 75 php exception-handling try-catch
我一直在我的PHP代码中使用try..catch块,但我不确定我是否一直在正确使用它们.
例如,我的一些代码如下所示:
try {
$tableAresults = $dbHandler->doSomethingWithTableA();
$tableBresults = $dbHandler->doSomethingElseWithTableB();
} catch (Exception $e) {
return $e;
}
Run Code Online (Sandbox Code Playgroud)
所以我在同一个try/catch块中对多个数据库操作进行分组,因为如果在任何事务中发生任何异常,我将能够处理它.
我这样做是因为我认为它比以下更具可读性和效率:
try {
$tableAresults = $dbHandler->doSomethingWithTableA();
} catch (Exception $e) {
return $e;
}
try {
$tableBresults = $dbHandler->doSomethingWithTableB();
} catch (Exception $e) {
return $e;
}
Run Code Online (Sandbox Code Playgroud)
虽然,我不确定我所做的是一种好的做法,还是一种懒惰的方法来捕捉异常.
我的假设是,只有异常需要特殊处理时,它才应该有自己的try/catch块,否则将它们分组到同一个try/catch中应该没问题.
所以我的问题是:
每个数据库事务使用try/catch块有什么好处吗?或者我仍然可以在同一个try/catch块中对多个数据库事务进行分组而没有任何问题?
嵌套try/catch块可以吗?谢谢!
编辑
return语句主要仅用于演示目的,但我也使用了返回,catch()
因为我正在向该方法发出AJAX请求,而Javascript期待一个JSON对象,然后如果发生异常,我返回一个空的JSON编码数组.我只是认为在我的示例中放置特定代码不会增加任何值.
Jon*_*Jon 89
重要的提示
下面的讨论假定我们正在讨论如上例所示的代码结构:无论选择哪种替代方案,异常都会导致该方法在逻辑上停止执行它在中间的任何操作.
只要你打算做同样的事情,无论try
块中的哪个语句抛出异常,那么使用单个try
/ 当然更好catch
.例如:
function createCar()
{
try {
install_engine();
install_brakes();
} catch (Exception $e) {
die("I could not create a car");
}
}
Run Code Online (Sandbox Code Playgroud)
如果您可以并且打算以特定于其确切原因的方式处理故障,则多个try
/ catch
块是有用的.
function makeCocktail()
{
try {
pour_ingredients();
stir();
} catch (Exception $e) {
die("I could not make you a cocktail");
}
try {
put_decorative_umbrella();
} catch (Exception $e) {
echo "We 're out of umbrellas, but the drink itself is fine"
}
}
Run Code Online (Sandbox Code Playgroud)
小智 21
为了后人的缘故,答案可能为时已晚.您应该检查变量的返回值并抛出异常.在这种情况下,您可以确保程序将从引发异常的位置跳转到catch块.在下面找到.
try{
$tableAresults = $dbHandler->doSomethingWithTableA();
if (!tableAresults)
throw new Exception('Problem with tableAresults');
$tableBresults = $dbHandler->doSomethingElseWithTableB();
if (!tableBresults)
throw new Exception('Problem with tableBresults');
} catch (Exception $e) {
echo $e->getMessage();
}
Run Code Online (Sandbox Code Playgroud)
小智 9
单个try catch块更具可读性.如果它的重要标识出一种错误,我建议您自定义您的例外.
try {
$tableAresults = $dbHandler->doSomethingWithTableA();
$tableBresults = $dbHandler->doSomethingElseWithTableB();
} catch (TableAException $e){
throw $e;
} catch (Exception $e) {
throw $e;
}
Run Code Online (Sandbox Code Playgroud)
没有理由不使用单个块进行多个操作,因为任何抛出的异常都会阻止在失败的操作之后执行进一步的操作.至少只要你可以从捕获的异常中得出结论哪个操作失败了.只要没有处理某些操作就可以了.
但是我会说返回异常只会有限.函数的返回值应该是某个操作的预期结果,而不是异常.如果你需要对调用范围中的异常作出反应,那么要么不在函数内部捕获异常,而是在调用范围内,或者在完成一些调试日志记录之后重新抛出异常以便稍后处理.
抛出异常时,立即停止执行并继续执行该catch{}
块.这意味着,如果将数据库调用放在同一个try{}
块中并$tableAresults = $dbHandler->doSomethingWithTableA();
抛出异常,$tableBresults = $dbHandler->doSomethingElseWithTableB();
则不会发生.使用第二个选项时,$tableBresults = $dbHandler->doSomethingElseWithTableB();
仍然会发生,因为它在catch{}
块之后,执行已恢复.
每种情况都没有理想的选择; 如果您希望第二个操作继续,则必须使用两个块.如果没有发生第二次操作是可接受的(或者是可取的),那么你应该只使用一次.