php: try-catch not catching all exceptions

I'm trying to do the following:

try {
// just an example
$time      = 'wrong datatype';
$timestamp = date("Y-m-d H:i:s", $time);
} catch (Exception $e) {
return false;
}
// database activity here

In short: I initialize some variables to be put in the database. If the initialization fails for whatever reason - e.g. because $time is not the expected format - I want the method to return false and not input wrong data into the database.

However, errors like this are not caught by the 'catch'-statement, but by the global error handler. And then the script continues.

Is there a way around this? I just thought it would be cleaner to do it like this instead of manually typechecking every variable, which seems ineffective considering that in 99% of all cases nothing bad happens.

82260 次浏览

Solution #1

Use ErrorException to turn errors into exceptions to handle:

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

Solution #2

try {
// just an example
$time      = 'wrong datatype';
if (false === $timestamp = date("Y-m-d H:i:s", $time)) {
throw new Exception('date error');
}
} catch (Exception $e) {
return false;
}

The shorter that I have found:

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

Makes all errors becoming instance of catchable ErrorException

It is possible to use catch(Throwable $e) to catch all exceptions and errors like so:

catch ( Throwable $e){
$msg = $e->getMessage();
}
try {
// call a success/error/progress handler
} catch (\Throwable $e) { // For PHP 7
// handle $e
} catch (\Exception $e) { // For PHP 5
// handle $e
}

It's also possible to define multiple types for the $e parameter in catch:

try {
// just an example
$time      = 'wrong datatype';
$timestamp = date("Y-m-d H:i:s", $time);
} catch (Exception|TypeError $e) {
return false;
}