So I'm sitting there, one warm
afternoon, thinking up ways to improve upon the software I've been
developing over the last year or so. Of course, speed improvements
are always sought after, as well as improved simplicity of design.
When those go hand in hand, you are golden.
With PHP it is possible to accomplish both in many
ways. One method I have used to great success is to createC modules
to expand the core functionality of PHP. Convert a couple of those
frustratingly slow, but critical, routines into C and you will very
likely see a major performance boost, not to mention a pat on the
back from your boss, accolades from PHP development groups, and
serious respect from your fellow developers. This of course is
assuming you don't bomb the compilation of PHP and shut down 30 of
your e-commerce sites while you scramble to undo the mess on the
server. That usually gets you a completely different reaction from
you boss.
The solution my friends, is
to not work on the same PHP build that is currently interpreting the
myriad of websites requiring immediate services. "I know that!", you
say, "But how can you run multiple builds of PHP on the same server
and have some sites be served by one of the PHP builds, while the
other (the test one) is served by another PHP build all while using
one instance of Apache?" Well my long-winded,
run-on-sentence-speaking friendĀ here is how you do it.
First, the context: I'm currently working with a
FreeBSD system, utilizing Apache 1.3 for web services, and PHP 4.2.2.
I haven't tested this out on Linux or Windows, but I do believe that
any Unix flavor should be fine. The main key is Apache, or rather
the configuration file: httpd.conf
Step One: Organization
For simplicity's sake, I'm
going to recommend that you organize you system in such a way that
each domain you are hosting has it's own PHP directory located below
the document root (like cgi-bin). This directory is going to contain
a link to the correct build of PHP for the site.
So here is the directory structure I am going to
use:
| /www/clients/myEcommerceSite | This is the root of the Ecommerce
site |
| /htdocs | The document root
directory |
| /php | The php compiler (and
source) directory |
| /images | The images directory
(obviously) |
Create the same
structure in your test site directory. I would also suggest thatyou
create a directory somewhere else on the server to contain the actual
PHPbuild. You could place the builds in the php folder for each
site, but it is muchmore efficient (should you want multiple sites
to use the same php build) to havea single location, and then simply
link to the correct build inside the php directory.
Step Two: Multiple PHP Builds
Now that you have the correct structure it is time to
create the different builds of PHP. The key here is to compile them
as a CGI version, not the Apache module. I know, I know, there are
some security risks, but the payoff far outweighs the risk. This
does mean, however, you should be much more conscious about your
code, and CGI data (but you all are anyway, so I'm wasting my
keystrokes as it were). For the moment, since you are going to be
using one PHP as a test point for your new module, just create two
identical (and functioning) PHP builds.
Don't
just copy the same PHP build. You should have two separate
directories of PHP source. Since you will be using one PHP source
for your new module additions, you will be making a lot of changes to
the folders in the directories. If you should accidentally overwrite
your stable PHP version in the future, you will wish you had an
untouched PHP directory set so that you could just compile another
one. Considering that reengagement time is crucial when anything
happens to a commercial webserver, the additional resource
expenditure is completely justified.
So now you
have two files called "php" on your drive. Move them to the
directory that you setup for the builds (you might consider renaming
the PHP's for identity purposesĀ something like "php.stable" and
"php.test" would work).
Now link the correct
binary to the correct domain by going into the php directory of each
domain and creating a link called "php" (ln /path/to/php/php.stable
php)
Step Three: Modifying
Apache
Here is where the magic comes in. This
took myself and a couple other guys (Thanks Brian and Jason!) weeks
to figure out. Unfortunately (until now) nothing was on the web
about how to do it (that we could find).
The
main configuration file for Apache is httpd.conf. It controls, among
other things, the configuration for each Virtual Host (that is, each
domain) you are serving, as well as the reaction Apache should take
towards any given filename extension. First we indicate that we are
considering .php files to be special by adding a Handler (this can be
added anywhere, but for organizational purposes it is best to include
them before the Virtual Host listings).
AddHandler php-script .php
Next we include the Action that Apache should take when
a php-script file is encountered.
Action php-script /php/php
This is the key point. This line tells Apache that it
should execute the binary at the relative location (as this is in
reference to the DocumentRoot setting in the VirtualHost section for
each domain) and feed in the requested PHP file.
Since Apache considers every request relative to the
DocumentRoot (which in our case is htdocs) we will need to add two
ScriptAliases to allow the process to proceed.
ScriptAlias /php/ /www/clients/myEcommerceSite/php/
ScriptAlias /php/
/www/clients/myEcommerceSite/php/*/
So the
result of it is when a client requests catalog.php from
myEcommerceSite, Apache accesses the file and sends it through the
binary (or link) called php located at:
/www/clients/myEcommerceSite/php/
Once the PHP
binary is finished with the page it is transmitted to the user, just
as it normally would be with an Apache module.
Restart the Apache server and you are ready to go. All
you need to do is change which PHP build any given site is linked to
and you can adjust which interpreter is used!
Now you can break PHP all day long!
< Michael >