PHP Syntax Highlighting with LightTPD

1 Comment

I recently said good-bye to good ol' Apache Webserver and jumped on the LightTPD-train. So far, I haven't regret that move. Everything I could do with Apache, I can do with Lighty as well.

However, after I set up PHP with it, I somehow missed the opportunity to have automatic syntax highlighting with .phps files. Google came up with this solution, which I found rather unstatisfying. Instead, I wanted something… cool.

So here's the Idea: Instead of opening another socket over fastcgi, let's invoke a small PHP-script via CGI which runs a given file through PHP's highlight_file function. First off, the script /usr/bin/php-source:

#!/usr/bin/php -n
$output = <<< EOT
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "">
    <title>Source of {$_SERVER['REQUEST_URI']}</title>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <h1>Source of {$_SERVER['REQUEST_URI']}</h1>
$output .= highlight_file($_SERVER['argv'][1], true);
$generated = @date('r', $_SERVER['REQUEST_TIME']);
$output .= <<< eot="" <hr="">
   <p align="center">
     Generated $generated. Almost certainly <a href="">valid HTML 4.01 Transitional</a>.
printf("Content-Type: text/html\r\nContent-Length: %u\r\n\r\n", strlen($output));
echo $output;

Looks complicated, doesn't it? Well, it really isn't. All this does is to invoke the PHP binary (the -n switch prevents PHP from parsing the php.ini, which speeds up things a bit), throws the response together with the help of the PHP heredoc syntax (which I think should be used more often). Last but not least, the HTTP headers Content-Type and Content-Length are set and returned along with the generated output.

Now the last thing left to do (safe for setting chmod a+x /usr/bin/php-source) is to let lighty recognize .phps files:
cgi.assign += ( ".phps" => "/usr/bin/php-source" )

Is all of this a bit overkill? Sure. Is it cool nonetheless? I think so. Of course, there are still some downsides to this approach:

  • There is no caching mechanism involved so far, thus the full script is rerun every time a .phps file is being pulled from the server (which is a rather minor problem, as this script doesn't take that many cpu cycles)
  • As lightie's cache doesn't catch the output, it isn't compressed either.

Both of these problems can be addressed within the script itself, which will be material for further blog posts ;)


Really awesome. Thank you and very much appreciate it. (((0)

2011-11-29 7:43 am