这更像是一个概念性问题。
是否可以使用try / catch来调用do / while循环?
例如:
<?php
function main() {
$failure = 0;
do {
$failure += foo();
$failure += bar();
...
if ($failure) { return $failure; }
}
while ($failure == 0);
}
function foo() {
try {
echo 'DO FOO STUFF<br />';
return 0;
}
catch (Exception $e) {
return 1;
}
}
function bar() {
try {
echo 'DO BAR STUFF<br />';
return 0;
}
catch (Exception $e) {
return 1;
}
}
?>
我问的原因是我在某处读到混合两者都是不好的做法。您应该创建自己的异常并“抛出”它们。但这不是一种矫枉过正吗?
编辑: 为了解释出现这个问题的场景,想象一下必须遵循一条线的机器人。每当他迈出一步并且将信息发送到服务器时,机器人计算其位置(X位置,Y位置,Z位置和“姿势”位置)。服务器双重检查此信息。如果发现任何异常,服务器会向机器人发送“停止”信号。机器人停止,重新计算其位置,重新发送信息并等待“开始”信号。
此循环示例基于从机器人接收的数据馈送。如果出现问题(如无线链路断开,障碍物或失误),机器人必须停下来以防止误入歧途,跌倒或任何事情。我们不知道出了什么问题,或者为什么出错了,只是它出错(或不出错)。 (这实际上是在代码的另一部分,而不是基于PHP的调试模块)。
编辑2: 像所有人一样指出,似乎正确的方法是正确地提出/处理异常。 既然每个人似乎都同意这一点,我不知道是谁给出了“正确答案”。 如果可以的话,我会等几天给更多选票的那个!
答案 0 :(得分:3)
没有理由避免try/catch
与do/while
混合。
但是,您提供的示例与do/while
的问题较少,而try/catch
块中的吞咽例外情况较多。
在任何语言,PHP或其他语言中捕获基本异常类型并吞下它是一种不好的做法。最好只捕获特定的异常类型,让剩下的部分通过catch块。
例如,如果您正在访问一个文件,并且捕获了FileNotFound
异常(如果在PHP中有这样的东西),那就没问题。
但是如果你捕获所有异常类型,那么你将会发现像OutOfMemoryException
这样的东西。如果你妥善处理它,那就没关系,并确保它不会再扔了。但在你的情况下,你可能不会为这种情况“做正确的事”,所以你应该让它落空。
您不想吃异常(不记录它们)的原因是,如果代码进入锁定的生产环境,您将无法调试代码。如果捕获到异常,那么用户将看到错误的行为,并且将无法提交错误报告,该报告为您提供足够的信息来调试它。他们可能会给你repro步骤,但这是非常不可靠的。对于一个间歇性的问题,这也毫无价值。
如果您吃掉了异常,那么您基本上就会丢弃最有用的数据进行调试。
使这不那么真实的事情:
答案 1 :(得分:1)
如果您想吞下异常并报告失败,那么这没关系。你必须做像
这样的事情 $failure &= bar();
但是,或者你将失去foo()的失败条件。
如果你希望能够在调用堆栈的后面进一步处理异常,那么你最好不要单独使用它,或者至少重新抛出它,这样你就可以把它捕获到你想要处理它的位置。
答案 2 :(得分:1)
没有一般的理由避免在do / while循环中调用的函数中使用try / catch。
根据您在循环中实际执行的操作,您可以选择在循环内捕获异常,并在返回错误条件时退出,或者将整个while循环包装在try / catch块中。
您应根据代码的例外含义决定如何在任何特定情况下执行此操作:
在您的示例中,即使bar()
生成错误,也会执行foo()
。这可能是也可能不是你想要的。捕获循环外的异常将不允许此选项。
此外,如果bar()
随后返回false
,foo()
返回true
,则循环不会终止 - 这可能是一个错误。捕获循环外的任何异常将意味着循环将在错误点终止。同样,根据您的申请,这可能是也可能不合适。
此外,可能需要以不同方式处理不同的异常。重要的是,如果您捕获基本异常类型,而不是更具体的派生类型,则您将无法执行此操作。捕获更具体的异常(包括自定义异常)将对您有所帮助: