I’ve been using Comb, my experimental PHP framework, for a couple of super-secret projects over the past few months (on those sporadic occasions when I actually write code), and it’s been evolving pretty dramatically. So much so that very little of the original code still exists. I’m still calling it “Comb” though, because the underlying idea is still the same. It’s too time consuming to describe the reasons why I changed each part, so suffice it to say the changes are essentially organizational. Instead I’ll just jump into explaining it from the ground up as it exists now.
To begin with, here’s the now-simplified Apache VirtualHost container that I’m using:
<VirtualHost *:80> ServerName example.com DocumentRoot /vhosts/example.com/www ErrorDocument 404 /404.php <Directory "/vhosts/example.com/www"> AllowOverride All php_value include_path ".:/vhosts/example.com/www/lib" php_value auto_prepend_file /vhosts/example.com/www/comb.php </Directory> </VirtualHost>
The first four lines should be pretty self-explanatory, but for the rest:
- Allow the full use of .htaccess files, e.g., for rewrite rules, etc
- Set PHP’s include_path to the current working dir (when parsing templates), the application’s lib dir (for app-specific classes), and the system lib dir (for shared classes)
- Prepend comb.php in the document root to every requested PHP script.
This Apache configuration ensures that every requested script will first run the site’s comb.php script, which is a very simple, application-agnostic bootstrap script, meaning it’s basically the same for every app that I build. In fact I could just have one copy of it in a central directory and prepend it from there, but I’d lose some potential flexibility that way. Though that could probably be coded around. Anyway, here’s where things get interesting; comb.php looks like this:
<?php require '/www/include/load.php'; spl_autoload_register('load'); $comb = new util_comb(); $comb->run(); $comb->send();
My autoloader is pretty simplistic; it just converts “util_comb” into “util/comb.php” and tries to include it based on the include_path set in the vhost container.
The util_comb class encapsulates all the crucial routing and response rendering logic. The constructor parses the request URI into its segments and loops over them looking for any files called prepend.php and append.php. If they exist, they’re added into an array that I refer to as the inclusion list. To visualize this, imagine a request for /user/profile.php?name=drew. The vhost will start by running comb.php, and the following scripts will get added to the inclusion list if they exist:
/prepend.php /user/prepend.php /user/profile.php /user/append.php /append.php
in that order. The idea is to sort of mimic the way Apache finds and parses .htaccess files that are (possibly) in each subdirectory.
The next method that’s called, $comb->run(), simply loops over the inclusion list and include()s each one of them.
Finally, $comb->send() is called, in which the response is created and sent. This is where template rendering or redirecting takes place.
My next few blog entries will go into the details of the inclusion list, how I’ve set up template rendering, and how to get clean/friendly URLs working.