1

EDIT: It turned out that what I stated in this question was totally wrong. The code was actually turning off error reporting explicitly prior to autoloading, in places where I hadn't found it.
So this question is basically useless. The accepted answer is correct.


In my current configuration, whenever some PHP file has fatal errors such as syntax errors or calling a function that does not exist, I usually get an error message such like:

Parse error: syntax error, unexpected <whatever> in /path/to/file.php on line XXX

or

Fatal error: Call to undefined function whatever() in /path/to/file.php on line YYY

or the like in the very output.

However, I am using third-party libraries which use a third-party autoloader. Whenever there's a fatal error in any of the autoloaded classes (including parse errors or calling unexisting functions - actually not completely sure about the latter but definitely of the parse error case), I just get a blank page, and not only that: no error is even logged in Apache's error_log file, where usually PHP fatal errors would be logged. So debugging becomes impossible.

I can't stress this enough: this only happens when the fatal error is in some autoloaded file. In every other case (including of course errors in files included via require(), include() and the like), the same errors do show up in the output and in the error_log.

I didn't write the autoloader code, but it's basically like this:

    // no idea why this line, but I don't think it's relevant:
    ini_set('unserialize_callback_func', 'spl_autoload_call');
    
    spl_autoload_register(array('My_Autoloader', 'autoload'), true);

    class My_Autoloader {
        static function autoload($classname) {
            $filename = //.... computes $filename from $classname
            require_once($filename);
        }
    }

There must be a way to have the autoloader throw errors the same way they would be thrown (and handled) if the errors were not in an autoloaded file, right?

How do I get that?

matteo
  • 2,934
  • 7
  • 44
  • 59

3 Answers3

0

Syntax Error Check only on Command Line

With php -l somefile.php from PHP shell_exec('php -l /fullpath/to/somefile.php')

but you have to analyse the respone string for errors.

Normal response No syntax errors detected in somefile.php

In PHP <= 5.0.4 there was php.net/manual/en/function.php-check-syntax.php

Here a fatal error catch that works:

register_shutdown_function(function(){
    $err=error_get_last();
    if($err['type']===1){
       /*you got an fatal error do something, write it to an file*/
       #file_put_contents(var_export($err,true),'myfatalerror.log');
    }
});

Hope that helps:)

JustOnUnderMillions
  • 3,741
  • 9
  • 12
  • @matteo Have a look! – JustOnUnderMillions Oct 14 '16 at 15:36
  • This doesn't check the syntax of files include()d from the main file you call it on, does it? – matteo Oct 14 '16 at 15:53
  • 1
    the problem is that the file with the supposed syntax error or fatal error is one of a bazillion files dynamically loaded by an autoloader, so manually checking each of them is not quite viable... – matteo Oct 14 '16 at 15:56
  • Nope you have to test it by yourself, and that is possible in the autoloader before include a file. I have to ask: Why does your application have files with syntax errors at all? Why not check them now all with `php -l somefile.php` and fix the files, then you get rid of the syntax errors and can go on fixing the other errors. As Note: syntax errors are detected before compling the php files, all other errors are at runtime – JustOnUnderMillions Oct 14 '16 at 15:56
  • bazillion files with an 50% of syntax errors, hopefully behind that code is no company. I would kick the CEO. Or who has let this happen? – JustOnUnderMillions Oct 14 '16 at 16:00
  • I don't know from where you get that 50%. It's ONE file that has the error, only it could be any of them. Yes the files used to work, then I modified a bunch of them, introduced a bug somewhere in one (or a few) of them. If they had been included in any way other than by registering an autoloader, I would get an error message and immediately know where the error is. If there is really no way of having the same error handling with autoload that you would get with a normal include, to me that's a PHP bug. – matteo Oct 14 '16 at 23:48
  • Regarding "As Note: syntax errors are detected before compling the php files, all other errors are at runtime": however, fatal errors, or at least some subset of fatal errors, no matter how "run time" they are (with JIT the concept of runtime is somewhat fuzzy) cannot be caught in realtime in any way, meaning you can't set an error handler for them - that's at least on 5.x, I hope they have fixed that in later versions. I think calling an undefined function is among those cases. – matteo Oct 14 '16 at 23:52
  • And by the way, I can now confirm that the issue I observe (i.e. no fatal error being displayed nor logged) DOES happen with calling undefined functions as well as with syntax errors, so "php -l" wouldn't help in that case. – matteo Oct 14 '16 at 23:54
  • If you are positive that there's no way of having PHP 5.x throw (this kind of) fatal errors in autoloaded file the same way it would with other included files (i.e. log them and, if display_errors is on and depending on error_reporting, display them), please add that to your answer and I will accept it, since if that is the case, then the answer to my question is basically "you can't do that" and you provide a partial workaround which appears to be as far as one can go (assuming the premise is true) – matteo Oct 15 '16 at 00:02
0

The only way that the code would behave as you suggest is if the third party code is overriding the error reporting. (EDIT by OP: Yep, it turns out it actually was.) That is usually considered good practice for production systems, but it should be logging the error.

That your third party code is causing such errors gives me pause to wonder about its quality, but we'll ignore that for now.

PHP's built in mechanisms will handle the reporting (to the browser) and the logging (to file). Non fatal errors can be managed by your own code after calling set_error_handler() however fatal errors are not handed off via this route. It is possible to trap and handle fatal errors in your own code using register_shutdown_function(). But start by checking your log files.

If, as you say, both error logging and error reporting are disabled, then stop using this third party code - it is toxic.

matteo
  • 2,934
  • 7
  • 44
  • 59
symcbean
  • 47,736
  • 6
  • 59
  • 94
-2

Use php exception so you can call your file into

function inverse($x) {
    if (!$x) {
        throw new Exception('Division par zéro.');
    }
    return 1/$x;
}

try {
    echo inverse(5) . "\n";
    echo inverse(0) . "\n";
} catch (Exception $e) {
    echo 'Exception reçue : ',  $e->getMessage(), "\n";
}
G. Mansour
  • 696
  • 6
  • 15
  • I don't think this has anything to do with my question. I'm talking about fatal errors such as syntax errors, not exceptions. – matteo Oct 14 '16 at 15:52