是否可以捕获异常并继续执行脚本?
原文由 Kirzilla 发布,翻译遵循 CC BY-SA 4.0 许可协议
你可以,但我会警告:许多人认为这种方法非常邪恶。
// https://stackoverflow.com/a/66377817/578023
function is_same(&$a, &$b): bool {
$_ = [ &$a, &$b ];
return
\ReflectionReference::fromArrayElement($_, 0)->getId() ===
\ReflectionReference::fromArrayElement($_, 1)->getId();
}
function attempt_risky_action($collection){
$cursor=NULL;
$resuming = false;
resume:
try{
foreach($collection as $item){
if($resuming && !is_same($cursor,$item) ){
continue; // some things have better ways to skip ahead, especially an array index
}
else {
$resuming = false;
$cursor=&$item; // main concept is to remember where you are in the iteration
} // in some situation you may have to use references, &item
// your normal loop here
.
.
.
}
} catch( Exception $e){
$resuming = repair_something($e, $collection); // returns false if your repair ran out of ideas
if($resuming)
goto resume;
}
unset($cursor);
}
理想情况下,最好将 unset($cursor);
调用包装在 --- finally{}
块中,但坦率地说,我不确定如何使用 goto 副手。
如果它执行是因为 goto 中断了流程,那么您将需要一些条件逻辑,因此游标仍然存在。如果循环中有 return 语句,则 必须 使用 finally 块来调用 unset($cursor)
或导致内存泄漏。
再说一次,虽然不那么令人兴奋,但您可以通过将整个循环嵌套在 do{ try/catch } while($resuming)
中来实现同样的技巧。虽然这并没有从字面上扭转您的执行,但它的效果完全相同,而且不会冒 goto 的风险。
is_same()
来自 https://stackoverflow.com/a/66377817/578023
function attempt_risky_action($collection){
$cursor=NULL;
$resuming = false;
do{
try{
foreach($collection as $item){
if($resuming && !is_same($cursor,$item) ){
continue;
}
else {
$resuming = false;
$cursor=&$item;
}
// your loop here
}
} catch( Exception $e){
$resuming = repair_something($e, $collection); // returns false if your repair ran out of ideas
}
finally{
if(!$resuming){
unset($cursor);
}
}
} while($resuming);
}
最后一种方法,未图示; you can use PHP’s reset()
, prev()
, current()
, next()
, end()
faculties
这些将允许您简单地将您的 try/catch 块放在一个代码块中,该代码块作为循环进行迭代 - 然后在 catch 中使用 prev()
再次尝试。
原文由 That Realty Programmer Guy 发布,翻译遵循 CC BY-SA 4.0 许可协议
1 回答4k 阅读✓ 已解决
3 回答1.8k 阅读✓ 已解决
2 回答2.2k 阅读✓ 已解决
1 回答1.4k 阅读✓ 已解决
2 回答2.2k 阅读
1 回答565 阅读✓ 已解决
784 阅读
当然,只需捕获要继续执行的异常…
当然,这有一个问题是默默地丢弃可能是一个非常重要的错误。 SomeOperation() 可能会失败,从而导致其他微妙的、难以解决的问题,但你永远不会知道你是否默默地放弃了异常。