开发者

Is there a way to catch an Exception without having to create a variable?

开发者 https://www.devze.com 2023-02-07 06:39 出处:网络
In PHP, I sometimes catch some exceptions with try/catch : try { ... } catch (Exception $e) { // Nothing, this is a test that an exception is thrown.

In PHP, I sometimes catch some exceptions with try/catch :

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

With tha开发者_开发问答t kind of code, I end up with the variable $e that is created for nothing (lots of resources), and PHP_MD (PHP Mess Detector) creates a warning because of an unused variable.


Starting with PHP 8, it is possible to use a non-capturing catch.

This is the relevant RFC, which was voted favourably 48-1.

Now it will be possible to do something like this:

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");
}

With this, for some edge cases where the exception details are not relevant and exception type already provides all the necessary context, it will be possible to catch the exception without creating a new variable.


You can with PHP 8 @see

PHP 5,7

No, but you can unset it.

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

If it is PHPMD causing this issue then you can suppress the warning.

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);
        }
    }
}

I'm assuming you are only catching the exception because you need to not because you want to. With PHP 5,7 you have to use a catch if you want to use try and if you use a catch you have to declare a variable.


That's the whole point of exceptions - you can have multiple different catch blocks to catch any exceptions you'd want to handle. The exception's data has to be assigned somewhere, hence the variable. You could just do something like unset($e) inside the catch block if you really don't want to see those warnings... or disable the warnings (generally a bad idea).


I disagree fundamentally with Marc B's and Artefacto's answers. There are cases where ommitting the catch is better or even the only option. Especially when using external libraries (where you have no control over what exceptions are thrown) and/or async operations.

For example:

I want to create a file only if it doesn't exist yet. I'm using an external I/O library. Imagine it has File::exists($fileName) and File::create($fileName) methods.

Option 1 (if ommitting the catch was possible):

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

Option 2 (without try/catch):

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

Here, option 1 is perfectly valid, since option 2 has two important issues:

  1. If multiple threads are running and going through this code section at the same time, it could be that thread A first checks if the file exists. Next, thread B checks if the file exists. They both find that it doesn't exist. Thread A creates the file. Thread B then attempts to create it again and throws an exception even though you're using the if check.
  2. It's very likely that the library itself already performs the !File::exists($fileName) check. Therefore you're wasting a call that is already made.

Note that if File::create throws other exceptions that might be unexpected it would be good to catch those.

Conclusion

Stating that something is never a good idea, is almost never a good idea. There are always exceptions (hehe) to the rule. Like any convention or design pattern, it's just a rule of thumb meant to help less experienced developers make the right decision.


No.

In any case, it's generally a bad idea to catch an exception and do nothing; exceptions exist precisely to force you to handle the exceptional circumstance (otherwise execution is aborted), so it's comprehensible the language doesn't facilitate such a use case.


As of PHP 8.0 it may be typed without variables, but the general case for each Exception is now Throwable. Class Exception implements Throwable.

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

精彩评论

暂无评论...
验证码 换一张
取 消