php - 尝试,捕获并重试

use*_*692 32 php try-catch

有时我的代码会破坏,而且不受我的控制

我该怎么做?

try {
//do my stuff
}
catch {
//sleep and try again
}
Run Code Online (Sandbox Code Playgroud)

代码不是那么多,所以它只是一个函数,所以我不想制作并调用另一个函数,如果我不需要

noa*_*hnu 59

你可以尝试这样的事情:

function exception_error_handler($errno, $errstr, $errfile, $errline ) {
    throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}
set_error_handler("exception_error_handler");

$NUM_OF_ATTEMPTS = 5;
$attempts = 0;

do {

    try
    {
        executeCode();
    } catch (Exception $e) {
        $attempts++;
        sleep(1);
        continue;
    }

    break;

} while($attempts < $NUM_OF_ATTEMPTS);

function executeCode(){
    echo "Hello world!";
}
Run Code Online (Sandbox Code Playgroud)

在这里,我们执行一个do...while循环,以便代码至少执行一次.如果executeCode()函数遇到错误,就会抛出Exceptiontry...catch块将捕获.catch然后该块将变量递增$attempt1并调用continue以测试while下一次迭代的条件.如果已经有五次尝试,则循环将退出并且脚本可以继续.如果没有错误,即没有执行continue来自catch块的语句,则循环将break完成脚本.

请注意使用此处set_error_handler功能.我们这样做是为了捕获函数中的所有错误,即使我们不自己手动抛出错误.executeCode()

如果您认为您的代码可能会多次失败,则该sleep()功能在continue声明之前可能会有所帮助.'减慢'可能无限循环将有助于降低你的CPU Usage.

让脚本无限运行直到成功是不是一个好主意,因为在循环的前100次迭代中出现的错误不太可能被解决,从而导致脚本"冻结".更重要的是,最好重新评估您希望在出现错误时多次运行的代码,并改进它以正确处理任何错误.

  • 很好的例子(这个线程中最好的),但我不认为`set_error_handler()`调用是绝对必要的,除非你特别想要除了*通常的异常之外还要捕获每个PHP通知,警告和语法错误*.常规的try/catch仍将捕获PHP内部函数以及您自己抛出的异常抛出的异常. (2认同)

Ami*_*ati 9

这是一个简单的算法:

$trys = 5;
do {
    try {
        // YOUR CODE
        // YOUR CODE
        // YOUR CODE
        // YOUR CODE
        // YOUR CODE

        break;
    }
    catch(Exception $e) {
        $trys--;
    }
} while($trys > 0);
Run Code Online (Sandbox Code Playgroud)

另外,为了无限次尝试,请删除该$trys--行:)


Rei*_*.85 5

简单地:

function doSomething($params, $try = 1){
    try{
        //do something
        return true;
    }
    catch(Exception $e){
        if($try <5)
             sleep(10);
             //optionnaly log or send notice mail with $e and $try
             doSomething($params, $try++);
        else 
             return false;
    }
}
Run Code Online (Sandbox Code Playgroud)