在 try-catch 块中继续当前迭代 | PHP

Continue with current iteration in a try-catch block | PHP

在我的脚本中有时会出现服务器、连接、配置或 API 问题,因此我实现了一个 try-catch 块来正确捕获异常并跳过它们。

...但是我的问题没有用这个解决方案解决,因为元素(引发问题)本身不是问题。 所以基本上我的问题是是否有任何方法可以捕获错误并从您离开的地方继续:不是跳过错误并转到下一个元素,而是在foreach 循环。

显然,continuebreak 不起作用!

foreach($xx as $x) {
    try {
        //main code
    } catch (Exception $e) {
        echo 'Caught exception: ', $e->getMessage(), "\n";
        sleep(10);
    }
}

... 并且当 catch 部分捕获错误时,代码应该使用当前 $x 重复 try 循环(它最初捕获错误/抛出错误)然后继续列表元素。

您可以 运行 for 循环而不是 foreach 循环,并且可以管理 catch 块内的递增计数器,方法是递减它以获得当前的 $x(它最初捕获错误/抛出错误)并再次重试相同的元素。这可能会导致无限循环,因此请保留任何重试阈值。

将 try 块放入它自己的 while (true) 循环中,您可以 break 成功:

while (true) {
    try {
        ...
        break;
    } catch (...) {
        ...
    }
}

这会重试相同的操作,直到没有异常被抛出。为了避免永远不会成功的无限循环,您可以添加一个计数器,例如:

$tries = 0;
while ($tries < 10) {
    $tries++;
    try { ... }
}

一旦异常被抛出并被捕获,就无法返回到抛出异常的代码块。不幸的是,没有技术上的可能性,你只有一个 try catch 块,你可以在其中捕获所有异常,然后决定它们是否重要(并停止执行脚本)或者异常不是真正的问题,你希望你的脚本表现得像如果没有例外的话。

我能给你的唯一解决方案是:

foreach($xx as $x) {
    try {
        //main code

        try {
            //first code that can cause an exception
            //you just want to continue after
        } catch (Exception $e) {
            echo "Nothing wrong, just an exception " . $e->getMessage(), "\n";
        }

        try {
            //second code that can cause an exception
            //a serious problem, you don't want to continue
        } catch (Exception $e) {
            echo "This is a real problem " . $e->getMessage(), "\n";
            throw $e; //re-trowing exception
        }

        //third code that can cause an exception

    } catch (Exception $e) {
        //will catch exception from code 2 and 3 but not 1.

        echo 'Caught exception: ', $e->getMessage(), "\n";
        sleep(10);
    }
}

顺便说一句。您要求的不是通过使用异常来完成,而是在出现错误的情况下。如果发出错误信号,并且它是可恢复的,您可以为错误编写一个全局处理程序,并在该错误句柄中决定错误是否是您要关闭脚本的问题,或者只是记录它并 return 到脚本执行就好像完全没有错误一样。但这是关于错误,而不是例外。