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

Mat*_*oli 30 php exception try-catch

在PHP中,我有时会在try/catch中捕获一些异常:

try {
    ...
} catch (Exception $e) {
    // Nothing, this is normal
}
Run Code Online (Sandbox Code Playgroud)

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

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

谢谢

yiv*_*ivi 17

从 PHP 8 开始,可以使用非捕获捕获。

这是相关的 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");
}

Run Code Online (Sandbox Code Playgroud)

这样,对于异常详细信息不相关且异常类型已经提供所有必要上下文的某些边缘情况,可以在不创建新变量的情况下捕获异常。

  • 我九年的疑问终于有了答案^^谢谢! (9认同)

Tar*_*nes 11

不,但你可以解开它.

try {
    ...
} catch (Exception $e) {
    unset($e);
}
Run Code Online (Sandbox Code Playgroud)

我假设你只是捕捉异常,因为你不得不因为你想要.如果要使用,catch则必须使用a 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;
}
Run Code Online (Sandbox Code Playgroud)


Mar*_*c B 7

这就是异常的全部要点 - 您可以使用多个不同的catch块来捕获您想要处理的任何异常.异常的数据必须在某处分配,因此变量.unset($e)如果你真的不想看到那些警告,你可以做一些像catch块里面的事情......或者禁用警告(通常是一个坏主意).


Art*_*cto 7

没有.

无论如何,捕捉异常并且什么都不做通常是一个坏主意; 异常存在以强制您处理异常情况(否则执行被中止),因此可以理解该语言不利于这种用例.

  • 同时,当您可能只需要状态代码时抛出异常通常是个坏主意.如果异常实际上是异常的,我们就不会看到这么多无用的try/catch块.特别是,许多网络实用程序会在出现网络问题时抛出异常,这会破坏封装并且对程序员没有帮助.当您是网络实用程序时,网络问题不应该例外,您应该能够在内部处理它. (4认同)

Wou*_*ijn 6

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

例如:

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

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

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

选项2(无尝试/捕获):

if (!File::exists($fileName))
    File::create($fileName);
Run Code Online (Sandbox Code Playgroud)

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

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

结论

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

  • @superrafal 在我的例子中根本不是这种情况。我确切地知道抛出了什么异常,并想忽略它并继续前进。为什么每次发生无害且可预测的事情时我都需要记录? (2认同)