php 有没有一种方法可以在不创建变量的情况下捕获异常?

lg40wkob  于 2023-01-16  发布在  PHP
关注(0)|答案(6)|浏览(394)

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

try {
    ...
} catch (Exception $e) {
    // Nothing, this is a test that an exception is thrown.
}

对于这种代码,我最终得到的变量$e是空的(大量资源),PHP_MD(PHP Mess Detector)会因为一个未使用的变量而创建一个警告。

hzbexzde

hzbexzde1#

从PHP 8开始,可以使用非捕获catch。
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");
}

这样,对于异常细节不相关并且异常类型已经提供了所有必要的上下文的一些边缘情况,将有可能捕获异常而无需创建新变量。

k0pti3hp

k0pti3hp2#

You can with PHP 8 @see
PHP 5,7语言
不,但你可以取消设置。

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

如果是PHPMD导致此问题,则可以抑制警告。
PHPMD suppress-warnings

class Bar {
    /**
     * This will suppress UnusedLocalVariable
     * warnings in this method
     *
     * @SuppressWarnings(PHPMD.UnusedLocalVariable)
     */
    public function foo() {

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

我假设你捕获异常只是因为你需要,而不是因为你想。在PHP 5,7中,如果你想使用try,你必须使用catch,如果你使用catch,你必须声明一个变量。

uttx8gqw

uttx8gqw3#

这就是异常的关键所在--你可以有多个不同的catch块来捕捉你想要处理的任何异常。异常的数据必须被赋值到某个地方,因此变量也必须被赋值。如果你真的不想看到那些警告,你可以在catch块中做一些类似unset($e)的事情......或者禁用警告(通常是个坏主意)。

vs3odd8k

vs3odd8k4#

我从根本上不同意Marc B和Artefact的回答。在某些情况下,省略catch更好,甚至是唯一的选择。特别是在使用外部库(在那里你无法控制抛出什么异常)和/或异步操作时。

    • 例如:**

我只想创建一个不存在的文件,我正在使用一个外部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检查。
1.很可能库本身已经执行了!File::exists($fileName)检查,因此您浪费了一个已经执行的调用。
注意,如果File::create抛出其他可能意外的异常,最好捕获这些异常。

    • 结论**

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

pftdvrlh

pftdvrlh5#

没有。
在任何情况下,捕获异常而不做任何事情通常都不是一个好主意;异常的存在正是为了迫使您处理异常情况(否则执行将被中止),因此可以理解,该语言不支持这样的用例。

qyzbxkaa

qyzbxkaa6#

PHP 8.0开始,它可以不带变量输入,但是现在每个Exception的一般情况是Throwable。类Exception实现了Throwable

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

相关问题