捕获异常而不在catch中执行任何操作

时间:2011-01-27 18:18:35

标签: php exception try-catch

在PHP中,我有时会在try / catch中遇到一些例外:

try {
    ...
} catch (Exception $e) {
    // Nothing, this is normal
}

使用这种代码,我最终得到的是没有创建的变量 $ e (大量资源),并且PHP_MD(PHP Mess Detector)因未使用的变量而创建警告

有没有办法在不必创建变量的情况下捕获异常?

由于

7 个答案:

答案 0 :(得分:12)

从2020年11月发布的PHP 8开始,将有可能使用非捕获的渔获。

This is the relevant RFC,以48-1得票。

现在可以执行以下操作:

try {
    readFile($file);
} catch (FileDoesNotExist) {
    echo "File does not exist";
} catch (UnauthorizedAccess) {
    echo "User does not have the appropriate permissions to access the file";
    log("User attempted to access $file");
}

这样,对于某些异常情况不相关且异常类型已经提供了所有必要上下文的极端情况,就有可能在不创建新变量的情况下捕获异常。

答案 1 :(得分:6)

这就是异常的全部要点 - 你可以有多个不同的catch块来捕获你想要处理的任何异常。异常的数据必须在某处分配,因此变量。如果你真的不想看到这些警告,你可以在catch块中执行类似unset($e)的操作......或者禁用警告(通常是个坏主意)。

答案 2 :(得分:6)

没有

无论如何,捕获异常并且什么都不做通常是个坏主意;异常存在正是为了迫使你处理异常情况(否则执行被中止),所以可以理解的是语言不利于这样的用例。

答案 3 :(得分:5)

不,但你可以解开它。

try {
    ...
} catch (Exception $e) {
    unset($e);
}

我假设你只是捕捉异常,因为你不得不因为你想要。 如果要使用catch,则必须使用try。因此,人们对于捕捉异常是否一个坏主意的看法是无关紧要的。 应该努力在不使用try/catch的情况下实现所需的结果。 据我所知,别无选择。

我使用这样的东西作为我的模板引擎。

//array of templates ordered by version new to old.
for($templates as $tpl){
    try {
        $output = render($tpl,$data);
        //it worked
        break;
    } catch(ErrorException $e){
        unset($e);
    }
}
if(!empty($output)){
    return $output;
}

答案 4 :(得分:1)

我从根本上不同意Marc B和Artefacto的回答。在某些情况下,省略渔获量甚至是唯一的选择。尤其是在使用外部库(您无法控制引发什么异常)和/或异步操作时。

例如:

我只想创建一个尚不存在的文件。我正在使用外部I / O库。假设它有File::exists($fileName)File::create($fileName)方法。

选项1(如果可以忽略渔获):

try {
    File::create($fileName);
}
// Go on with the rest of the code.

选项2(无try / catch):

if (!File::exists($fileName))
    File::create($fileName);

在这里,选项1完全有效,因为选项2有两个重要问题:

  1. 如果多个线程正在同时运行并同时通过此代码节,则可能是线程A首先检查文件是否存在。接下来,线程B检查文件是否存在。他们俩都发现它不存在。线程A创建文件。然后,线程B尝试再次创建它,即使您正在使用if检查,也会引发异常。
  2. 很可能库本身已经执行了!File::exists($fileName)检查。因此,您浪费的是已经打过的电话。

结论

声明某事永远是一个好主意,几乎从不是个好主意。规则总是有例外(呵呵)。像任何惯例或设计模式一样,这只是一条经验法则,旨在帮助经验不足的开发人员做出正确的决定。

答案 5 :(得分:0)

是的,您可以从 PHP 8.0 开始使用。如果您想捕获所有异常,可以使用Throwable

try {
    ...
} catch (Exception) {
    // Exception
} catch (Throwable) {
    //All other classes implementing Throwable interface
}

答案 6 :(得分:-2)

例外不仅用于特殊情况。

此方案实际上使用例外来确保用户已注销。在脚本的这一点上,确定应该修剪哪些数据是非常昂贵的,因此实际上更快地修剪它并捕获异常。

        try {
        GDS::$DB->exec('DELETE FROM sessions WHERE session_id = ' . session_id());
        GDS::$DB->exec('DELETE FROM sessions WHERE user_id = ' . $this->data['user_id']);
    } catch(PDOException $ex) {}
    session_regenerate_id(true);
    setcookie('bis_[user_id]', 0, time() - 1, null, null, false, true);
    setcookie('bis_[session_start]', 0, time() - 1, null, null, false, true);
    setcookie('bis_[session_time]', 0, time() - 1, null, null, false, true);