Forum Moderators: coopster

Message Too Old, No Replies

Simple parse errors in PHP cause 500:Internal Server Errors!?

Only on this server (Apache/2.2.3 PHP/5.2.5) - php.ini, Apache setting?

         

penders

2:57 pm on May 8, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



On a particular server I'm developing on, what seem to be 'simple' parse errors in the source return a blank page to the client/browser with a status code of 500 - Internal Server Error. This is really not very helpful when trying to debug the script!

Can anyone think of anything server-side which could cause this?

Same (buggy) script on another server produces a standard parse error with line number etc. - as expected - good.

Example of 'simple' syntax errors/typos which cause this:

public $start_time = 0;; // Too many semicolons

if (($report_type == self::REPORT_HTML_COMMENT) { // Parenthesis mismatch

Setting the following makes no difference:

error_reporting(E_ALL); 
ini_set('display_errors',"1");

Thanks.

Receptional Andy

10:32 pm on May 8, 2008 (gmt 0)



If you can get hold of a server error log, it will likely tell you the cause (which may not be specifically to do with PHP). Unfortunately a 500 error (an "unexpected condition") is very vague, and so without the error log is not much use. Presumably you can run PHP scripts that don't contain errors (e.g. phpinfo)?

The suggestion is that it's a server config thing so it could be that PHP is set to run as CGI as opposed to a module, or perhaps a permissions problem of some sort.

penders

11:09 am on May 9, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



If you can get hold of a server error log, it will likely tell you the cause (which may not be specifically to do with PHP).

The server error log contains just the actual PHP error, which I would have expected to be returned to the browser. In the case of too many opening parenthesis on the 'if' statement, this is:

[Fri May 09 11:07:33 2008] [error] [client xx.xx.xx.xx] PHP Parse error: syntax error, unexpected '{' in /var/www/vhosts/example.com/httpdocs/test_parse_error.php on line 18

But the browser just gets the vague 500 error and no output. This particular case is a short isolated test page.

Presumably you can run PHP scripts that don't contain errors (e.g. phpinfo)?

Yes, no problem.

...it could be that PHP is set to run as CGI as opposed to a module

phpinfo states "Server API: Apache 2.0 Handler" so I guess this is a module (as opposed to CGI).

Yeah, I'm tending towards a 'server config thing' (although no clue as to what or what permission problem it could be?) - I've glanced over the output from phpinfo() and it looks ok to me?

Any other suggestions or where to look next?

Receptional Andy

11:18 am on May 9, 2008 (gmt 0)



Interesting. I couldn't claim to have a definite idea as to what's going wrong, but my guess would be that the problem is with PHP displaying errors rather than in execution, which seems OK.

I'm thinking that there is another error log entry somewhere - the entry posted does not explain the 'unexpected condition' the server encountered.

Just a bit of guesswork: do you have display_errors on in php.ini (you can see this via phpinfo)?

Added: there may be some clues in this PHP bug report [bugs.php.net]

[edited by: Receptional_Andy at 11:21 am (utc) on May 9, 2008]

penders

8:12 pm on May 9, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



...my guess would be that the problem is with PHP displaying errors rather than in execution

This is what I was thinking at first... display_errors is Off by default in php.ini (which I don't have access to). But despite setting the following in my script:

ini_set('log_errors','Off'); // 'On' in php.ini 
ini_set('display_errors','On');
error_reporting(E_ALL);

...still no meaningful parse errors are output. Are there any other error-enabling settings? But I kinda think that even if the displaying of errors were suppressed in some way, this shouldn't result in a 500 error - that's even worse!

Apart from the error log entry above, the only other log entry that I can find is in the access log:

xx.xx.xx.xx - - [09/May/2008:16:22:59 +0100] "GET /test_parse_error.php HTTP/1.1" 500 194 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.12) Gecko/20070508 Firefox/1.5.0.12"

Note the 500 code. The 194 (bytes) returned is literally a blank HTML page which is only viewable if I view-soure in IE (for some reason I don't see this in Firefox or Opera; there appears to be NO source - literally a blank page?!)

Added: there may be some clues in this PHP bug report

Yes, that does sound exactly right - a bug(?) related to output_buffering. And output_buffering is, by default, set to 4096 in php.ini. That bug report states that turning off output_buffering corrects the sympton. HOWEVER, if I try to turn this off with the following directive in .htaccess it does nothing to sort the problem:

php_value output_buffering 0

If I check this in my script with ini_get() it shows the value as 0 (this is 'off' I presume?)

----
Hhhmmm, come to think of it I'm pretty sure I've encountered this same problem before with PHP5/Apache installed locally on a demo machine. The web app had originally been written for PHP4, there were parse errors and these resulted in a confusing blank screen. We were, however, able to sort these with a bit of guess work and all was dandy.

However, this current issue with a development server is with a very well known hosting company.

Receptional Andy

9:23 pm on May 9, 2008 (gmt 0)



Thinking out loud:

ini_set is not reliable on third party servers: any security-conscious sysadmin will have blocked access to anything interesting ;)

The part of the bug report that I found most relevant was:


HTTP 500 redirect should only occur when there is absolutely no
actual output from any of the display errors/error reporting settings

It's badly worded, but suggests that a 500 error may be what PHP outputs when no error is returned to the browser (I don't have a testing environment for PHP5 on-hand at the moment, so I can't confirm this).

In which case, it could be that display_errors is off, you are not able to switch it back on via ini_set, and so error_reporting has no effect. PHP5 returns a server error to the user (which is not unreasonable).

penders

11:28 am on May 10, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



...suggests that a 500 error may be what PHP outputs when no error is returned to the browser...

Yes, I would agree. Except it appears to be getting this wrong (hence bug#42722), as there should be output (the parse error), but because of a possible mix up with output_buffering it doesn't get output...?

Yes. Turning off output buffering in php.ini/.htaccess (it is on by
default when using php.ini-recommended settings) corrects the symptom.

That would indicate that when a script terminates in the error handling
processing, that the output buffer is not flushed in the same way it is
when the script reaches the normal end of file processing.

...it could be that display_errors is off, you are not able to switch it back on via ini_set, and so error_reporting has no effect.

ini_set('display_errors','On');
I think is working OK as I can output E_NOTICE (Warning) messages only after having called ini_set()

To be honest, Bug#42722 [bugs.php.net] does appear to describe the issue exactly. Except in my case turning off output_buffering does not resolve the issue - unless I'm not actually turning it off!? (NB: output_buffering cannot be turned off using ini_set(), only in php.ini, httpd.conf or .htaccess)

Receptional Andy

12:34 pm on May 10, 2008 (gmt 0)



Did you try php_flag output_buffering Off in htaccess?

penders

6:35 pm on May 10, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Did you try php_flag output_buffering Off in htaccess?

Yep, tried that as well. This seems to do the same thing as

php_value output_buffering 0
. If you read the value back using ini_get() the value is 0 by either directive. But it doesn't resolve the issue.

Thanks for your perseverance btw, I'm sure there's an answer somewhere!

Just to note, from the PHP change log [uk.php.net]:

Version 5.2.4
30-August-2007
- Changed error handler to send HTTP 500 instead of blank page on PHP errors.

Receptional Andy

7:26 pm on May 10, 2008 (gmt 0)



I did some testing on a server with PHP 5.2.5 and I could only trigger a 500 response if display_errors was set to off and a fatal error occurred.

Pure speculation, but this behaviour would occur if the check for output relied on the php.ini setting for display_errors without checking user output. The same thing is suggested in the bug report.

That said, it seems like some kind of server setting might be affecting this, if I can't recreate with the same PHP version. I think I'm out of ideas though, I'm afraid.

penders

11:17 am on May 11, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I did some testing on a server with PHP 5.2.5 and I could only trigger a 500 response if display_errors was set to off and a fatal error occurred.

Yes, on another PHP 5.2.5 (although CGI) server I've tried, parse errors are reported normally as well.

I have come across several other cases (in other forums) which seem to describe this same issue but they all seem to take this as expected behaviour (I can't help but feel this is a bit naive perhaps?) and the solutions have all been to resolve the specific problem with the script, not how the errors are being reported?!

Thanks for your help, I'll post back if I find out anymore.

chorny

3:15 pm on May 11, 2008 (gmt 0)

10+ Year Member



Use tests for you code (I hope your code is modular)

penders

9:35 pm on May 11, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Use tests for you code...

Can you explain?

I don't actually have a problem with the code as such, it's just the fact that parse errors in general are not being output to the browser when all settings seem to suggest they should be. Instead the server returns a 500 - Internal Server Error. The parse error is, however, logged in the servers error log. But for a development server it would be far more helpful if the error was simply output to the browser window in this instance (as it does on other servers!).

penders

10:53 pm on May 11, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Additional...

This particular case is a short isolated test page.

I have been concentrating my efforts on this small test page - usually the best thing to do.

However, I have since noticed that I can display parse errors... but only if the parse error occurs within an included file. The included file can be included anywhere within the main file (including before any output), it doesn't matter, the parse error will be output. However, if the parse error occurs anywhere within the main file (ie. the file referenced by the URL) then a 500 - Internal Server error is returned (no parse error output).

Just to clarify...

If I navigate to test_parse_error.php (which contains a parse error) I get an HTTP Status Code of 500 - Internal Server error and no output.

However, if I navigate to test_ok.php which includes test_parse_error.inc (which contains a parse error) I get the parse error output!

So, it's not as general as I first thought, it's not simply all parse errors.