error_get_last

Returns details of the most recent PHP error as an array, or null if none occurred.

Signature
error_get_last(): ?array
  • Added in PHP 5.2.0

Return value

?arrayAn associative array with the keys type, message, file and line describing the last error, or null if no error has been raised yet.

error_get_last() reads PHP's record of the last error that occurred, whether or not it was displayed. It sees errors that were silenced with @ and errors that error_reporting() excluded, which makes it the standard way to find out why an older function returned false.

Two main uses

First, diagnosing suppressed calls. Pair it with error_clear_last() so you know the record belongs to the call you just made:

error_clear_last();
$raw = @file_get_contents($path);
if ($raw === false) { echo error_get_last()['message']; }

Second, catching fatal errors. A fatal error cannot reach set_error_handler(), but a function registered with register_shutdown_function() still runs, and calling error_get_last() there tells you whether the script died from E_ERROR and where.

What it will not show you

If a custom error handler is installed and returns true, the error is considered handled and the last-error record is not updated. Exceptions never appear here at all — they are a separate mechanism, so a caught TypeError or a thrown RuntimeException leaves the record untouched. And because the record is global and never auto-cleared, a stale entry looks exactly like a fresh one.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Report why a @-suppressed file or stream call returned false
  • Log the details of a fatal error from inside a register_shutdown_function() callback
  • Turn a legacy warning-plus-false API into a clear exception message

Frequently asked questions

Does error_get_last catch exceptions?

No. Exceptions are a separate mechanism and never appear in the last-error record, so a thrown or caught Throwable leaves error_get_last() unchanged. Use try/catch or set_exception_handler() for those.

Why does error_get_last return null after an error?

Most often a custom error handler returned true, which marks the error handled and skips the record. It also returns null if the record was cleared with error_clear_last().

Can error_get_last see fatal errors?

Yes, but only from a shutdown function. Register one with register_shutdown_function() and check whether the type is E_ERROR, E_PARSE, E_CORE_ERROR or E_COMPILE_ERROR.

More examples

Turn a silent failure into a real message

The first read succeeds and prints the file contents. The second fails, and instead of a bare false the warning text captured by error_get_last() becomes the exception message, which tells you the path and the reason.

Example · php
<?php
function readOrFail(string $file): string {
    error_clear_last();
    $data = @file_get_contents($file);
    if ($data === false) {
        throw new RuntimeException(error_get_last()['message'] ?? 'unknown error');
    }
    return $data;
}

file_put_contents('demo.txt', "hello\n");
echo readOrFail('demo.txt');
try { readOrFail('nope.txt'); } catch (RuntimeException $e) { echo 'failed: ', $e->getMessage(), "\n"; }

Catch a fatal error at shutdown

The shutdown callback runs at the end of the script and inspects the last error. Here nothing fatal happened, so it prints "clean shutdown"; if the script had hit an E_ERROR, the same callback would print the fatal message that set_error_handler() can never see.

Example · php
<?php
register_shutdown_function(function (): void {
    $e = error_get_last();
    if ($e !== null && ($e['type'] & (E_ERROR | E_PARSE | E_CORE_ERROR))) {
        echo "FATAL: {$e['message']} at line {$e['line']}\n";
    } else {
        echo "clean shutdown\n";
    }
});

echo "working\n";

Decoding the type constant

The type key is an integer bitmask constant, not a label, so 16384 means E_USER_DEPRECATED. Mapping it back to a name is what you would do before writing the entry to a structured log.

Example · php
<?php
error_clear_last();
trigger_error('deprecated call path', E_USER_DEPRECATED);

$last = error_get_last();
$names = [E_WARNING => 'E_WARNING', E_NOTICE => 'E_NOTICE', E_USER_DEPRECATED => 'E_USER_DEPRECATED'];

echo $names[$last['type']] ?? 'other', ' (', $last['type'], ')', "\n";
echo $last['message'], "\n";

Discussion

  • Be the first to comment on this lesson.