Engine Exceptions
Thanks to reclassification and internal engine changes, many
previously fatal errors can now be handled within the user land code
and do not leave the runtime in an undefined state. To allow this,
PHP 7 uses a new type of exception. PHP 5 only had fatal or
recoverable fatal errors. To not interfere with existing application
behavior and to generally have a clear distinction from classic
exceptions the new engine exceptions do not extend the existing
Exception
base class. Instead, they extend a new base
class named Error
. This allows for a very explicit
distinction when catching and handling them:
try {
// ...
} catch (Error $error) {
// ...
} catch (Exception $exception) {
// ...
}
Both Exception
as well as Error
implement the new internal interface Throwable
, which
defines the same API as the existing Exception
class –
with the minor difference of the return type for the method
getPrevious()
now being Throwable
rather
than Exception
:
interface Throwable
{
public function getMessage(): string;
public function getCode(): int;
public function getFile(): string;
public function getLine(): int;
public function getTrace(): array;
public function getTraceAsString(): string;
public function getPrevious(): Throwable;
public function __toString(): string;
}
Thanks to this new hierarchy, both Exception
as well
as Error
can also conveniently be caught and handled
with one catch
block:
try {
// ...
} catch (Throwable $throwable) {
// ...
}
PHP 5 does not know about the Throwable
and
Error
types but will also not trigger any autoload for
them when they are used within a catch
block. That
means the non-matching lines will simply be ignored. This approach
can also be used if you want to update your code to PHP 7 while
maintaining compatibility to older versions.
If you want to implement your own error or exception classes keep
in mind that the Throwable
interface is limited to
internal use and userland code cannot directly implement it. While
this limitation may be removed in future versions of PHP – rumor has
it that this is already being discussed – at the time of this
writing all userland error or exception classes must extend from
either Error
or Exception
.