set_error_handler turns warnings into exceptions

A PHP warning does not stop execution. file_get_contents() on a missing file warns and returns false, and the code carries on with false where a string was expected — so the failure surfaces three functions later, somewhere unrelated.

set_error_handler(function ($severity, $message, $file, $line) {
    if (!(error_reporting() & $severity)) {
        return false;  // respect @ and the current level
    }

    throw new ErrorException($message, 0, $severity, $file, $line);
});

Now the failure throws at the point it happens, with a stack trace. The error_reporting() check matters: without it the handler also fires for suppressed operations, and every library that uses @ deliberately starts throwing. Do this in development first — a mature codebase usually turns out to be warning far more often than anyone thought.