Wednesday, August 18, 2010

Gotcha of the Day: Forcing PHP to Cough Up Syntax Error Information

I ran into an especially annoying problem with PHP this morning. I was working on a server that had display_errors set to false. That's good. But, the server gave me no way to view the HTTP error log. The result was that when I published a page with a syntax error, the browser screen was blank, leaving me no hint as to where the actual error was.

I tried forcing the display of errors, but that didn't work.

Next up, I thought I'd try ssh'ing to the server and manually running php there. Just running:

bash-3.2$ php foo.php

produced no output. This makes sense, as it's essentially what the web server was doing, and it wasn't generating output.

After running php -h, I learned there was a syntax checking mode (lint - whoo!) that I could use. I figured this would be perfect. Here's the output of that attempt:

bash-3.2$ php -l foo.php 
Errors parsing foo.php

This confirmed my hunch that syntax errors were causing the problem, though for the life of me, I couldn't get the -l flag to actually tell me the errors it found.

Finally I came up with this recipe:

bash-3.2$ php -d display_errors=Yes \
 -r "error_reporting(E_ALL); require('foo.php');"

Sure enough, PHP finally hollered back at me:

PHP Parse error: syntax error, unexpected T_VARIABLE in /var/www/vhosts/bar.net/httpdocs/foo.php on line 608

This was just enough info to let me fix the problem.

There's almost certainly an easier way to accomplish this. But still, it worked and that works for me.

Update: As soon as I hit the publish button on this post, an easier solution popped into my head. I realized, I could simulate the same command line as above using PHP files.

Suppose I suspect foo.php of having a syntax error. I can create another file, error-shell.php that reads:

<?
ini_set('display_errors', 1);
error_reporting(E_ALL);
require_once('foo.php');
?>

When I access error-shell.php it has a chance to correctly load up, set the correct verbose error settings and then do the include of foo.php. In a quick test I ran, it did show me the syntax error that was hidden if I attempted to access foo.php directly.

I suppose I could extend this further by looping through a list of .php files to syntax check a whole bunch of them at one time.

No comments:

Post a Comment