php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #41810 Unable to catch Parse Errors
Submitted: 2007-06-26 10:46 UTC Modified: 2012-10-05 21:05 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:0 of 0 (0.0%)
From: d dot albano at gmail dot com Assigned:
Status: Not a bug Package: *General Issues
PHP Version: 5.2.3 OS: Linux
Private report: No CVE-ID: None
 [2007-06-26 10:46 UTC] d dot albano at gmail dot com
Description:
------------
Hi,

i've seen that set_error_handler doesn't let to the code to catch Parse Errors. I know that set_error_handler documentation page on php manual says that this error can't be catched, so this isin't a true bug: it is something like a logical bug because using strange tricks you can catch parse errors for included files.

So, instead to force php developers to do strange tricks to catch parse errors why don't try to send parse errors throught user defined error handler, if it is setted? I know that this isin't so simply but it is becoming necessary: in an advanced system is vitally catch any kind of error that can cause problem to page execution and this comprises catching every kind of errors that can be generated by third party module or every included file.

I understand that there isin't an easy way to do but a point of start can be define it through htaccess/php_value or simply use it only with included files after that set_error_handler is setted

Reproduce code:
---------------
# main.php:

<?php
function error_handler($errno, $errstr, $errfile, $errline)
{
    echo 'error catched!';
}

set_error_handler('error_handler');

require_once('file_with_parse_error.php');
?>

# file_with_parse_error.php:

<?php
--- this is a voluntary php parse error ---
?>


Expected result:
----------------
Browser should show:
error catched!

Actual result:
--------------
Browser output:
Parse error: syntax error, ....

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-06-26 11:21 UTC] tony2001@php.net
>it is something like a logical bug

It's something like a logical bug to catch parse errors using an error handler defined in the same script, cause the parse error may happen in the handler itself.
The parse error happens BEFORE execution starts, at the compilation stage, so it's just phisically impossible to call something that does not exist at that moment.
 [2007-06-26 11:30 UTC] d dot albano at gmail dot com
As i've said:

> I understand that there isin't an easy way to do but a point of start
> can be define it through htaccess/php_value or simply use it only with
> included files after that set_error_handler is setted

Exactly for that reason: a file that is parsed can't rely on any error_handler but if a file is included by another script that initialize the error handler the stuff change becase the code is executed normally and the file is included at runtime

Infact the code that i written refer exactly to this: check parse errors on included files not on the main file.

It is normal that isn't possible to catch errors in main.php
 [2007-06-26 11:49 UTC] tony2001@php.net
After parse error the parser/compiler and whole engine may be in unstable state, hence it's impossible to catch it as well as any other fatal errors.
They are fatal errors just because of that.
 [2007-06-26 12:31 UTC] d dot albano at gmail dot com
If there is a parse error, this error stop parsing of scripting engine, and this is ok, but where is the problem? And why it should remain in an unstable state? This doesn't make sense: it's parsing php code ... it isin't executing it

If it remains in a unstable state there is serious problem somewhere :\
 [2007-06-26 12:34 UTC] d dot albano at gmail dot com
if parser, before to compile and execute, check the code to see if the syntax is right how can remain the engine in an unstable state?
 [2007-06-26 12:43 UTC] tony2001@php.net
>If it remains in a unstable state there is serious problem somewhere :\
I don't think so, but you're encouraged to help us, the sources are open after all.

I'm sure nobody is going to rewrite the engine from scratch using some other tools just because you want to catch parse errors.
So there is no sense to keep this feature request open.
 [2007-06-26 13:07 UTC] d dot albano at gmail dot com
When i said:
> If it remains in a unstable state there is serious problem somewhere

i answered to your phrase:
> After parse error the parser/compiler and whole engine may be in
unstable state

If parsing a file may put the entire engine in an unstable state there is a problem: never heard that a parser can do this

The problem can be that the engine is written to shutdown after a parser error and this is can cause troubles i think, but the problem is that i'm not zend/php developer :)

However i don't think that is necessary to rewrite the engine from the scracth, a feature like this, at logic level, must follow rules followed by other errors

This afternoon i'll take a look to the parser and to the zend engine to understand how errors are passed

Thanks a lot
Bye
 [2007-07-03 16:29 UTC] d dot albano at gmail dot com
Looking to the code looks simply to do the modification, naturally, as you said, the problem is testing.

However i founded an eval behaviour to support my feature request: if there is a parse error execution continues

Can be that this is a bug or an unwanted behaviour, however nothing start to work strange after that a parse error was outputted.

So, if all works with eval why it shouldn't work correctly with normal parse errors?

Here there is some example code:
<?php

echo "BEGIN";

eval('echo "{$SYNTAX-ERROR"');

echo "END";

?>

It output
BEGIN
Parse error: syntax error, unexpected '-', expecting '}' in C:\web\htdocs\test.php(5) : eval()'d code on line 1
END
 [2007-07-03 16:36 UTC] tony2001@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php


 [2010-07-02 12:34 UTC] sneak at datavibe dot net
This classification is not bogus at all.  Consider the following:

== main.php ==

<?php

$filename = sprintf("%s.php", 'myfile' );
include_once($filename);

?>

== myfile.php ==

<?php

syntax errors here !@#$%^&*()_

?>



The parsing of myfile.php must necessarily happen at main.php's RUNTIME, because 
the filename is not available until sprintf() is called.

This is a bug.
 [2010-07-02 13:41 UTC] pajoye@php.net
-Package: Feature/Change Request +Package: *General Issues
 [2010-07-02 13:41 UTC] pajoye@php.net
It is not, please double read the manual about require/include_once.
 [2012-09-15 20:53 UTC] james dot dobb at gmail dot com
I agree that this, perhaps not a bug but a missing feature needs to be addressed,  
There should be a secure way of including scripts from another script and be able 
to continue the calling script if an error occurs, the lack of functionality here 
is causing me a major headache.....
 [2012-09-15 21:45 UTC] rasmus@php.net
This can't be done safely within the same parser instance as your main script. 
You will need to create a separate instance, as in system("php -l $script"); to 
do that check. I would suggest you do this once when these scripts are created 
and move them into a "checked" directory or something so you don't do it on every 
include.
 [2012-10-05 20:52 UTC] airetamstrm at gmail dot com
Contrary to what others have said here, require/include_once do NOT (always) 
happen at compile time. 
Otherwise, it would be impossible to do this:
<?php
foreach(glob('/path/to/php/includes/*') as $match) {
 if (is_dir($match)) {  
  foreach (glob($directory.'/*.php') as $filename) {
   require_once(($filename);
  }
 } else if (is_file($match)) {
  foreach (glob($directory.'/*.php') as $filename) {
   require_once(($filename);
  }
 }
}
?>

I've found the best way to work around this problem is to use eval, which is a 
poor 
solution at best. There really should be a way to catch this, considering PHP is 
an 
interpreted / templating language. Regardless of the intended functionality /doc 
of 
require/include_once there absolutely should be some mechanism to do this. See 
below for an 
example on how to at least silence parse errors:

function safeInclude($filename) {
 $fc = file_get_contents($filename);
 eval('?>'.$fc);
}

However, in the defense of the developers, if you're checking code for errors 
before 
including it, you're one or more of the following:
1) Building convenience code to help with rapid development
2) Pulling in code that you don't fully trust from others that may be buggy
3) Doing silly, inexcusable things with production
4) Templating and thus #2 

Fixing this bug likely be the most help to #1 and #4. If you're doing #4 you 
need to fire 
someone, if you're doing #3 you need to fire yourself. At the very least, if 
you're trying 
to do this you should review WHY you're trying to do this, and see if perhaps 
there's 
something else terribly wrong with your design approach.

I'm a #4 and would like it if someone could look at fixing this.
 [2012-10-05 21:05 UTC] rasmus@php.net
Even in the templating case there really is no excuse for pushing templates with 
parse errors to production. Running "php -l" as part of your pre-push testing is 
the expected bare minimum and hopefully you have actual tests you run with decent 
code coverage as well. You could also run it in your pre-commit hook in your VCS. 
Addressing this in PHP itself is extremely low-priority which means it will 
likely never happen.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Dec 22 23:01:29 2024 UTC