PHP 5.2 and 5.3 side-by-side on Apache and Ubuntu 10.10

12

Posted on : 31-10-2010 | By : Brett | In : General, Linux, PHP

Painlessly run version 5.2.x and 5.3.x on the same apache port simultaneously.

Several persons have indicated that they could not get this working per my instructions below. For a more thorough explanation, see Chris Breidert’ s follow-up blog post. One of these days, when I get more time, I’ll go through a vanilla installation and add any additional instructions, etc.

I’d just upgraded to Ubuntu 10.10 on my PC. However, the default PHP package was version 5.3.x and I needed 5.2.x. Some projects needed the newest version, others would be crippled by it. While looking for a way to have two versions of PHP running simultaneously on Ubuntu 10.10, I struck success.

In this post, I’ll explain step-by-step how you too can  build a development platform where you can work on PHP 5.2.x and 5.3.x projects simultaneously–without ever having to restart Apache.

Why?

My primary development computer is a Macbook Pro, but sometimes I like to change things up and work from my PC installed with the latest version of Ubuntu (10.10 at the time of writing.) Ubuntu 10.10 (A.K.A Maverick Meerkat) comes with PHP 5.3.x (currently 5.3.3.)

While using version 5.3.x, I noticed that some of my development projects were broken (like my website that needs curl!) On the other hand, I have another development project that is “cutting-edge” and must run PHP 5.3.x. I couldn’t just downgrade to PHP 5.2.x (which seemed to be the bulk of solutions offered for my predicament.)

Switching versions is easy on my Mac, thanks to MAMP. I just swap versions through the MAMP control panel. However, I really wanted the same flexibility on Ubuntu. Not only did I find a solution, I found one that I prefer to MAMP because I can run either version simultaneously. Here’s how I did it.

Step 1: Get PHP source code.

Download the most current version of PHP 5.2.x (5.2.14 at the time of writing.)

http://us.php.net/downloads.php

You can download this to anywhere like ~/src or wherever. Extract it with tar xzvf php-file (for .tar.gz variant) or tar xjvf php-file  (for .tar.bz variant) depending on which version you downloaded. Change directories into the folder you just extracted.

Step 2: Install PHP development libraries.

sudo apt-get install libxml2-dev libmysqlclient-dev libcurl4-gnutls-dev libcurl4-openssl-dev libpng12-dev libjpeg62-dev

Credit to Dave Parrish for the dev packages and configure options, plus most of the other information here.

Step 3: Configure and make.

./configure --prefix=/opt/php5.2 \
--with-config-file-path=/opt/php5.2 \
--with-mysqli \
--with-mysql \
--with-curl \
--with-gd \
--with-jpeg \
--with-jpeg-dir \
--enable-cli \
--enable-fastcgi \
--enable-discard-path \
--enable-force-cgi-redirect
If everything works, go ahead and make the file.
make && sudo make install
You should end up with php files in /opt/php5.2 if everything went without errors.

Step 4: Setup fast-cgi.

Just install the Debian package.

sudo apt-get install libapache2-mod-fastcgi

To enable the module, run:

sudo a2enmod fastcgi

Restart Apache.

Step 5: Enable mod_actions.

mod_actions was already available for me to use. I simply had to enable it:

sudo a2enmod actions

Restart Apache.

Step 6: Setup php5-cgi wrapper.

Create a /usr/lib/cgi-bin/php5-cgi file:

#!/bin/sh
PHP_FCGI_CHILDREN=1
export PHP_FCGI_CHILDREN
PHP_FCGI_MAX_REQUESTS=5000
export PHP_FCGI_MAX_REQUESTS
exec /opt/php5.2/bin/php-cgi

Also ripped off from Dave Parrish.

Make your wrapper executable:

sudo chmod +x /usr/lib/cgi-bin/php5-cgi

Step 7: Make an Include file for VirtualHosts.

I made a simple include file under /etc/apache2/ called php52.conf:

#include for sites that still need to run at php 5.2.x
 
ScriptAlias /php5-cgi /usr/lib/cgi-bin/php5-cgi
 
Action application/x-httpd-php5 /php5-cgi
AddHandler application/x-httpd-php5 .php .php5 .php4 .php3 .phtml

Credit to jameso for this pearl.

Step 8: Include php52.conf in all VirtualHosts where PHP 5.2.x is needed.

<VirtualHost *.80>
 
# ...
 
#needs to run version 5.2.x of PHP
Include php52.conf
 
</VirtualHost>

That’s it! Now I can simply insert my Include directive for any websites that I’m developing that are not ready for PHP 5.3.

Important. I am using VirtualHost configurations. This allows me to leave PHP 5.3.x enabled globally via the Apache module and turn on PHP 5.2.x specifically for each vhost. If you develop in the typical way of accessing a website via http://localhost/someproject, consider using the Apache Directory directive instead. It should work, but I haven’t tested.

Comments

I went through this document with no error – but how do I check to make sure the proper PHP is being loaded? I dropped a phpinfo file into the web folder but it still shows 5.3.2

Hi Doug,

Thanks for commenting. It is most likely that something is not working as expected. On my setup, phpinfo() shows PHP 5.2.x as well as cgi mode. etc.

This seems like it might be the magic bullet. I’m curious (I’ve tried nothing at this point so this is a thought experiment) – if there’s already a handler for .php files in your config, don’t they conflict? Or is it more of a cascading thing with Apache, whereby since this is defined inside a it wins, because it’s deeper in the config?

Yes, essentially anything you define in a virtual host overrides the same global setting.

Notice in the include file we’re defining a new action for application/x-httpd-php5

Cheers!

Hi Brett,

I followed you howto without error. However, like in Dougs comment, when I call a php page with a phpinfo() PHP5.2 does not respond but PHP5.3. After I disabled the php module (sudo a2dismod php5) I get offered a download of the php page. The content of that download is the content of the /usr/lib/cgi-bin/php5-cgi file. So it seems that the file is not executed but the content is sent back instead. The file has execute permission for everybody, and executing it on the command line (/usr/lib/cgi-bin/php5-cgi < /var/www/testphp.php) outputs the correct html code.

I am a little lost here, do you have an idea what could be wrong?

Cheers, Chris

Hi Chris,

Thanks for commenting. Check to make sure you have the Apache modules enabled (particularly mod_actions.)

Basically, you’re re-routing the PHP parsing from the apache module to a CGI version running 5.2.x. If you still see PHP 5.3.x, your configuration isn’t properly setup or the modules aren’t running. It could be a number of things, so check it thoroughly.

You do not want to disable the apache module for PHP. If you don’t care to have PHP 5.3.x, just downgrade to PHP 5.2.x. If you google that, you’ll come up with numerous solutions.

Good luck!

Hi Brett,
thx for your response. I finally got php5.2 running, as you suspected, some modules were not enabeled correctly.

However, php5.2 only answers, when the apache module php5 is disabled. if the apache module php5 is enabled, php5.3 answers.

I also looked at Dave Parrish’s blog post, who saw the same behavior. Your post seems similar to hos. Which part of your solution solves this problem?

Thx,

Chris

Hi Chris,

Are you not using virtual hosts in your configuration? I think that’s one huge point I’m leaving out of my tutorial.

I actually update my hosts file with local alias. For example:

127.0.0.1 localhost nameofproject.home

Then I create a virtualhost file for that. For example:


DocumentRoot "/var/www/nameofproject"
ServerName nameofproject.home
#needs to run version 5.2.x of PHP
Include php52.conf

If you are trying to work off of localhost, you could try sticking this in a Directory directive perhaps (not tested here:)


#needs to run version 5.2.x of PHP
Include php52.conf

Then when you typed http://localhost/nameofproject, the Include file would “re-route” to the cgi version.

Not sure that’s the issue, but my best guess without your configs.

Note: Just noticed that WP cleared my apache tags. Imagine the VirtualHost directive wrapped around the “virtualhost” example and the Directory directive wrapped around the latter. :)

Hi Brett,

I am using name bases virtual hosts. In my test environment test.de points to 127.0.0.1.

Here is the config file (i stripped out the from the apache tags, so WP won’t remove them):

VirtualHost *:80
ServerAdmin webmaster@localhost
ServerName http://www.test.de
ServerAlias test.de

DocumentRoot /var/www
Directory /
Options FollowSymLinks
AllowOverride None
/Directory
Directory /var/www/
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
/Directory

#Include php5.2
Include php52.conf

ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
Directory “/usr/lib/cgi-bin”
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
/Directory

ErrorLog /var/log/apache2/error.log

# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn

CustomLog /var/log/apache2/access.log combined

/VirtualHost

I think that should pretty much be how you suggested it should be done?

Thx for the help,

Chris

[...] blog posts, about how this can be done. The earlier is from Dave Parrish, a bit later came Brett with a nice tutorial. However, in spite of these excellent posts I encountered some pitfalls and [...]

Hi Brett,

adding

FilesMatch “\.php”
SetHandler application/x-httpd-php5
/FilesMatch

to the include did the trick.

I wrote a little summing up of my findings and test in my blog at http://blog.breidert.net/php-5-2-and-php-5-3-for-drupal-applications-under-apache-on-ubuntu-10-04-lts/

Thx again for your help,

Chris

Hello,

Thanks a lot. Everything works fine. Do you have idea how to add pecl extensions to 5.2 config (fileinfo, lzf, rar)?

Post a comment