This is the second article in the Linux virtualization series. It assumes that you have installed an Ubuntu as a virtual machine on your computer, but it can also be used as a guide by anyone who have a Debian based OS (virtual or not). It can also be used for other Linux distributions, but of course, the packaging system and the packages used will be different and you will need to adjust them for your own configuration.
Summary
- Install Apache and all needed additional libraries
- Build PHP5.2
- Build PHP5.3
- Build PHP5.4
- Configure Apache to use the different versions
- Testing installations
Install Apache and all needed additional libraries
Most websites will show you how to install multiple PHP versions with Apache by using 1 version of PHP as apache module and 1 as CGI or fast-CGI. This however will allow you to run just 2 instances of different PHP versions and will also require you to change the apache service configuration. This article will show you how to install any number of different PHP versions as CGI and swap them on per directory basis in your document root folder without the need to restart or reload the web server configuration. It is ideal in cases you wish to test your app against various PHP version or in cases when one application would require certain version installed and another application would require a different version (and you want to run them both).
First, we will need to install Apache, since the virtual machine we have built in the last article has no web server installed by default. Installing it would be quite simple. Login via SSH in the system or open a Console Terminal from its Desktop (Dashboard -> Internet Apps -> Accessories -> (See 13 More results link) -> Terminal) and type:
sudo suThis will change your username to the root user on the machine, since we will be running system-wide operations and we do not want to append ‘sudo’ to each of the commands. Once as root, type:
apt-get install apache2 apache2-threaded-devThis will get Apache2 and its apxs2 installed on the system. If you open http://localhost/ in your browser from within the virtual machine, you should be able to see a blank directory listing. This shows Apache is working correctly.
Prior installing any PHP version, we will need some more software libraries available. In SSH/Terminal type:
apt-get install libxml2-dev libbz2-dev libcurl4-openssl-dev libjpeg8-dev libpng12-dev libxpm-dev libfreetype6-dev libt1-dev libc-client-dev libmcrypt-dev libpspell-dev libedit-dev libsnmp-dev libtidy-dev libxslt1-dev libexpat1-devThe above line requests the needed libraries to be downloaded on your virtual machine and be installed by the apt packaging system. Some of the packages are version dependent, which means that they might change in the future. If you do receive an error that certain package is not found, you can easily find what its name is by typing:
apt-cache search <missing-package-without-version-number-here>Finally, on some systems the libexpat.so file is getting distributed in the “wrong” location. We will need to determine where it got installed and correct the location so that PHP will be able to locate it. To do so, run the locate command in SSH (or if you do not have locate, use whereis instead):
updatedb && locate libexpat.soOn my system, the libexpat.so file was located under /usr/lib/x86_64-linux-gnu/libexpat.so, but PHP will search for it under /usr/lib/libexpat.so. To correct this, we can create a symbolic link to it, as shown below:
ln -s /usr/lib/x86_64-linux-gnu/libexpat.so /usr/lib/libexpat.soWe are now ready to build our first PHP version.
Building PHP5.2
As we need a lot more control over where and what is installed on the system, we will no longer be using the packaging system which comes with Ubuntu (and Debian systems) but instead we will build the binaries on our own. The packaging system already did all the hard work for us by having each and every library installed and configured on the virtual machine. We just need to link the pieces together.
Starting with PHP version 5.2, the very first thing to do is to create a folder where our sources will be kept and to download the files from www.php.net:
mkdir /root/php5/cd /root/php5
wget http://docs.php.net/get/php-5.2.17.tar.gz/from/this/mirror
The latest one from the 5.2 branch is the 5.2.17 version and we will use the above archive to build it. Next, we will extract it and run configure, make and make install.
Extracting the archive:
tar -zxvf php-5.2.17.tar.gz
If you do not see a .tar.gz file but instead see a file called mirror, then just rename it (Wget tends not to follow the names as it should), “mv mirror php-5.2.17.tar.gz” and then again, run the tar -zxvf command.
Next, navige under the new folder:
cd php-5.2.17
and then run the configuration tool:
./configure –prefix=/usr/local/lib/php52 –with-mysqlThis is really the basic configuration which installs PHP with minimum options, if you would like to enable/disable a specific function you can edit it to your liking. Most (if not all) dependencies should be resolved with the libraries we have installed earlier. The only important bit is to keep the –prefix=/usr/local/lib/php52. This instructs the installation procedure to copy the files to this particular folder. If you get an error that something is missing and needs to be installed/re-installed, see “Appendix A” at the bottom of this article, for the most common issues.
It would take about a minute for the configure to finish. Once finished, we are ready to “make” this PHP instance by typing the word make and make install in SSH:
make && make installIt will take quite some time for the build to complete. Go get some pizza or beer in theĀ meantime
To verify everything is in order once the procedure is completed, you can browse under /usr/local/lib/php52 folder. There should be several subfolders and quite some files.
This is all about it. PHP 5.2 is now configured and built. Let’s move to php5.3
Building PHP5.3
We do the same for php5.3 as we did with php5.2:
cd /root/php5wget http://docs.php.net/get/php-5.3.9.tar.gz/from/this/mirror
mv mirror php-5.3.9.tar.gz
tar -zxvf php-5.3.9.tar.gz
cd php-5.3.9
Then we do ./confgure:
‘./configure’ ‘–prefix=/usr/local/lib/php53′ ‘–enable-discard-path’ ‘–enable-sigchild’ ‘–disable-force-cgi-redirect’ ‘–disable-ipv6′ ‘–disable-fastcgi’ ‘–with-zlib’ ‘–with-zlib-dir’ ‘–enable-bcmath’ ‘–with-libexpat-dir=/usr’ ‘–with-bz2′ ‘–enable-calendar’ ‘–with-curl’ ‘–with-curlwrappers’ ‘–enable-exif’ ‘–enable-ftp’ ‘–with-pspell’ ‘–with-libedit’ ‘–with-xpm-dir’ ‘–with-t1lib’ ‘–enable-wddx’ ‘–with-gettext’ ‘–enable-mbstring’ ‘–with-mcrypt’ ‘–with-mysql’ ‘–with-mysqli’ ‘–with-ncurses’ ‘–enable-pcntl’ ‘–with-pdo-mysql’ ‘–with-pdo-pgsql’ ‘–with-pgsql’ ‘–with-readline’ ‘–enable-shmop’ ‘–with-snmp=shared’ ‘–enable-ucd-snmp-hack’ ‘–enable-soap’ ‘–enable-sockets’ ‘–enable-sqlite-utf8′ ‘–with-tidy’ ‘–with-xmlrpc’ ‘–with-xsl=/usr/local/libxslt’ ‘–enable-zend-multibyte’I’ve used slightly different and bigger configure line here to illustrate how you can enable further options. If for some reason the above line fail, you can revert back to the php5.2 one, which is the real basic configure string (or you can check the Appendix for common issues and how to fix it). The important bit is again the –prefix=/usr/local/lib/php53 since we want each php version to be in its own separate directory and not overlap each other.
Then make && make install
make && make installWait for the process to complete and then move to the next step, installing php5.4
Building PHP5.4
PHP version 5.4 differs very little from the above steps. You would still need to obtain the source (though the URL will probably be different in the future, since 5.4 is still in RC at this moment):
cd /root/php5wget http://snaps.php.net/php5.4-201201151630.tar.gz
tar -zxvf php5.4-201201151630.tar.gz
cd php5.4-201201151630
Then we configure (using either the short one from 5.2 or the extended one from 5.3):
./configure –prefix=/usr/local/lib/php54 –with-mysqland finally:
make && make installNow to the interesting part…
Configure Apache to use the different versions
As mentioned earlier in this article, we are going to configure apache to use different PHP versions running as CGI. To accomplish this, we will use the Action module which is available in Apache, but not installed and enabled by default. First step is to enable the Actions module:
cd /etc/apache2/mods-enabled/ln -s ../mods-available/actions.conf actions.conf
ln -s ../mods-available/actions.load actions.load
Next step is to have all the PHP cgi binaries linked to a single folder, from which we will be loading them. The reason we are linking them (with sym links) instead of copying is simple: if you ever need to rebuild the PHP configuration to add or remove a certain functionality, the sym link will point to the new binary and you do not need to keep a copy of them all over the server:
cd /usr/lib/apache2/mkdir phps
chown root:www-data phps
cd phps
Now link them:
ln -s /usr/local/lib/php/php52/bin/php-cgi php52ln -s /usr/local/lib/php/php53/bin/php-cgi php53
ln -s /usr/local/lib/php/php54/bin/php-cgi php54
The final step, is to tell Apache to load these whenever we need them. Open Apache httpd.conf file /etc/apache2/httpd.conf (which if you are using Ubuntu should be empty, but still included by apache.conf) and write the following lines in it:
#Define Script Alias directory
ScriptAlias /phps /usr/lib/apache2/phps
#Define Actions
Action application/x-httpd-php52 /phps/php52
Action application/x-httpd-php53 /phps/php53
Action application/x-httpd-php54 /phps/php54
#Default PHP version handler.
AddHandler application/x-httpd-php53 .php
Testing the installations
Now to test what we have built. Since the goal of the article was to have multiple (3 in this case) simultaneous PHP versions, we will create a test file. First, we go to the main root folder (/var/www) and create an index.php file containing:
<?phpphpinfo();
?>
If you visit http://localhost/ you should now see that the version processing this file is the default one added in the httpd.conf (5.3 if you haven’t changed it). Now create a file called .htaccess inside the same folder and place the following code:
AddHandler application/x-httpd-php52 .php
Refresh the page and see if the version has changed to 5.2. If it hasn’t, then most probably your /var/www directory has AllowOverride set to None. Change this in /etc/apache2/sites-enabled/default file and replace ‘AllowOverride None’ to ‘AllowOverride All’. Then restart the Apache server for the changes to take effect.
The same method applies to any PHP version you install and can be applied on per directory or even on per file extension basis (.shtml processed with php53 for examle and .php with 5.2). You can also add any number of PHP instances regardless of the version number. You might also build a version with Suhosin patch applied if you fancy yourself the security type of person.







