A while back on Twitter I mentioned how I love that I can use ports to switch between different PHP environments with the flick of a switch. Demian Turner responded asking for more info on the subject spawning the creation of this post. That was 3 months ago and before it could collect too much dust Karl Tiedt provided the insistence inspiration to get off my ass and finish it, as he put it.
When I started working at OpenX my need to switch between various PHP environments arose. As it was required that I test all my code on multiple version of PHP since we supported a wide range of PHP versions. Basically I had it setup so I could test my code on 3 version (5.0.x, 5.1.x, & 5.2.x) of PHP 5 and 3 versions of PHP 4. The solution had to allow me to quickly switch environments with as little human interaction as possible. This is where MacPorts and a little shell scripting magic came into play. The nice thing about ports is you can compile the same application with different configurations and switch between them on the fly.
This is by no means a complete tutorial it’s a quick and dirty get started guide on how you can switch between PHP 4 and PHP 5 as quickly as possible using Apache 2 as the backend. This setup can also be extended to switch between various backends. For example switching between apache + mod_php5 and lighttpd + php5-fcgi. I won’t go into detail but by the end of this guide you’ll be able to figure it out.
Let’s get started by installing Apache 2
sudo port install apache2
Now that Apache 2 is installed we can move on to getting PHP 4 and PHP 5 compiled. Run the command below to use ports to install PHP 4 as a module for Apache 2 and PostgreSQL 8.3 since it’s a dependancey. Ports automates the installation of software. It downloads, configures, compiles and then installs PHP 4 including adding the necessary configuration lines to your Apache configuration.
sudo port install php4 +apache2 +macosx +pcntl +pear +postgresql83 +sockets +sqlite +t1lib +tidy
After it’s installed we need to deactivate PHP 4 otherwise the PHP 5 installation will error out since you can not have both the PHP 4 and PHP 5 ports activated at the same time.
sudo port deactivate php4
Next, we’ll install PHP 5
port install php5 +apache2 +macosx +pcntl +pear +postgresql83 +sockets +sqlite +t1lib +tidy
Note that the PHP 5 port installation will not modify your Apache httpd.conf file and you must do it manually. Once you have both ports installed it’s rather simple to switch between the two by running the two commands below
port deactivate php4
port activate php5
MacPorts will swap out the necessary files for you. However you must manually swap out the php.ini and your Apache httpd.conf file. This was definitely not going to cut it as I needed to be as effortless as possible so I whipped up a little shell script to get the job done.
#!/bin/sh
case “$1″ in
‘php4′)
/opt/local/apache2/bin/apachectl stop
/opt/local/bin/port deactivate php5
/opt/local/bin/port activate php4
cp /opt/local/etc/php4.ini /opt/local/etc/php.ini
cp /opt/local/apache2/conf/httpd.php4.conf /opt/local/apache2/conf/httpd.conf
/opt/local/apache2/bin/apachectl start
;;
‘php5′)
/opt/local/apache2/bin/apachectl stop
/opt/local/bin/port deactivate php4
/opt/local/bin/port activate php5
cp /opt/local/etc/php5.ini /opt/local/etc/php.ini
cp /opt/local/apache2/conf/httpd.php5.conf /opt/local/apache2/conf/httpd.conf
/opt/local/apache2/bin/apachectl start
;;
esac
Save the above script as php-switch in /opt/local/bin and make it executable. Then copy /opt/local/etc/php.ini to /opt/local/etc/ as php4.ini and php5.ini. Also do this for Apache’s /opt/local/apache2/conf/httpd.conf file to /opt/local/apache2/conf naming them httpd.php4.conf and httpd.php5.conf. Execute the script with either ‘php4′ or ‘php5′ as the parameter. The script will then shuts down Apache, deactivates the opposite PHP module, enables the specified PHP module, copies the necessary config files and then starts Apache.
Next lets install another version of PHP 5 that has the MySQL drivers instead of PostgreSQL
sudo port install php5 +apache2 +macosx +mysql5 +pcntl +pear +sockets +sqlite +t1lib +tidy
When switching between two versions of the same app that are compiled with different configurations you must explicitedly express the variants. For example to activate the PHP 5.2.5 port with PostgreSQL driver you’d run the following command
sudo port activate php5@5.2.6_1+apache2+macosx+pcntl+pear+postgresql83+sockets+sqlite+t1lib+tidy
Don’t worry if you forget the variants because if you try to activate a port without being explicted MacPorts will remind you.
root# port activate php5
—> Activating php5
—> The following versions of php5 are currently installed:
—> php5 @5.2.6_1+apache2+macosx+pcntl+pear+postgresql83+sockets+sqlite+t1lib+tidy (active)
—> php5 @5.2.6_1+apache2+macosx+mysql5+pcntl+pear+sockets+sqlite+t1lib+tidy (active)Error: port activate failed: Registry error: Please specify the full version as recorded in the port registry.
This should be enough to get you up. One thing that I don’t cover here that needs to be mentioned is PHP modules usually need to be compiled against different versions of PHP. For example if you use XDebug to debug your applications you’ll need a module compiled agains both PHP 4 and PHP 5. Use all code at your own risk.