Post navigation

Running multiple php versions on a single Apache install

This is a very strange topic: even though a cursory google search using the words “multiple php versions apache” spits out a considerable amount of informative howtos and blog entries, when I recently mentioned in a mailing list that it is in fact quite easy to have multiple php installs running in parallel using Apache virtual hosts, I immediately received a private request for my configuration.
Well, here it is, along with a few details on how to set up the complete environment.

The desired goal is having “alot” of php installations running in parallel, so that php scripts can be quickly tested against as many versions of php as possible. It is very useful f.e. when

you are migrating an existing app from php 4 to version 5

you are deploying your applications on a large base of servers where different versions of php are installed, but develop all the different apps on the same workstation

you develop a popular open source php library or shrink wrapped application, and want to make sure that it runs smoothly in every possible user setup

you want to test an application against different sets of php.ini configurations, to check for possible problems in areas such as output buffering, opcode caches etc…

you are into integration testing

There are many different setups that can be used to achieve this result (a big list is available on Gentoo docs, courtesy of Andreas Korthaus).
My preferred setup is: use a single apache instance, with a single php version installed as module, and many versions installed as cgi applications. Advantages:

no need to rename any php file to run it with different php versions

no need to restart the webserver or run any kind of script to switch php version

uses less memory than multiple apache installs

The main disadvantages are:

only 1 php version can run as an apache module, the others must limit themselves to cgi

a very misbehaved php application can in rare cases hog or crash the webserver, and it will have to be reset before testing with other php versions

The instructions below are geared to a windows environment with Apache 2, but converting them to linux is left as trivial exercise for the sysadmin.

Step1: download all the zip versions of php you need, and dump them somewhere on your disk. I usually name the directories “C:/php5” (stores always the latest php version), “C:/php4” (last version in the php 4 branch), “C:/php506” and so on

Step 2: install your apache server. Make sure that you know where the httpd.conf file is located

Step 3: for every php install, make sure you have a separate, working php.ini file. I prefer to keep the ini file in the same directory where the php exe is located. There are at least two settings that should be different for every php version:

error_log: it is always a good idea to have a separate log file for every php version

extension_dir: to make sure you are loading the php extensions from the correct path, I usually use the absolute path of the extensions dir (such as C:/php5/extensions or C:/php4/ext)

Step 4: (windows only): make sure you do not have any version of php4ts.dll or php5ts.dll inside your windows or system32 directories

Step 5: (windows only): make sure you do not have any of the dlls that come with php inside your windows or system32 directories. It will help avoiding the problem commonly known as “dll hell”

Step 5a: (windows only): if you are going to run any install of php 4 as cgi, copy the dlls that you find inside the “dlls” dir into the main php directory (eg. from C:/php4/dlls/ to C:/php4/). This is needed so that the php.exe executable, run as cgi app, can pick up the correct version of the dll libraries, and not the version from a different php install. If you are going to run php5 as cgi app, there is no problem, since the php.exe file and the required dlls are already in the same directory

Step 5b: (windows only): if you are going to run at least one php install as an apache module (php version 5 in this tutorial), you need to make sure that all the dll files it needs can be found at runtime. The difference from step 5a above is that, when running as an apache module, the process running is in fact apache.exe, not php.exe, and as such it will not, by default, search into c:/php for any dll to open, but look instead inside C:/Program Files/Apache2/Apache/bin. This problem will only become apparent when you enable in php.ini an extension that needs an extra dll, such as curl that depends on ssleay.dll. There are a couple of different solutions to this:

Put the dir to your php-as-apache-module install in the PATH environment var. This does not interfere with the other versions of php run as cgi, since the windows mechanism for opening dll files is to look in the exe file dir first, and in the path second. Otoh it might interfere if you run php scripts from a dos prompt

Copy the dll files from the php install (all those that are in the top dir and are whose name does not start by php for version 5, all those found in the ‘dlls’ dir for php4) into the apache/bin directory

Step 6: decide if you are going to use name-based or ip based virtual hosting. If you do not know what I am talking about, go read the Apache docs. If you are lazy, and it is fine for you to have the different php versions responding on different ports (beware of firewalls!), just keep on reading

Step 7: Stop the apache server, and edit the httpd.conf file. I prefer to keep all the php settings in a separate file, and include it in the main file like this:

Include conf/phpvhosts.conf

The content of the file phpvhosts.conf follows. It is set up to have the “main” virtual host listening on the standard apache port (as specified by the Listen directive in httpd.conf) with php 5, and two virtual hosts running two versions of php4 on ports 8447 and 8423. You guessed it, the port number matches the corresponding php version, so it is easy to remember. The comments inside the file itself are quite explicative.

Step 8: there is no step 8! Well… if you wanna check out if everything works, just set up a phpinfo.php file in your webserver root dir and access http://localhost/phpinfo.php, http://localholhost:8423/phpinfo.php and http://localholhost:84447/phpinfo.php to see if everything is fine

Some of considerations:

There are a lot of other configurations that you normally have to set up in httpd.conf. Of interest to php users is, for example, DirectoryIndex

To use port 80 for all php versions and switch to name based virtual hosting, you will have to comment out the two Listen directives and modify the VirtualHost directives in the file above. You will most likely also need to add some aliases to your ip address in C:/winnt/system32/drivers/etc/hosts

the above config file has been tested to work with both apache 2.0 and 2.2. It should not be hard to make a version for Apache 1.3 (in fact I suspect this one would just work)

Setting up separate Apache 1 and Apache 2 install is pretty trivial on windows (you just have to take care to have the first server installed shut down while you install the second, so that the port 80 is free; you can edit the config file to avoid port conflict later). If your primary goal is testing your app in as many different setups as possible, having 5 php installs on apache 2 and 5 on apache 1 is a good start. Plus, you can have two version of php running as apache modules

Arnold Daniels has a blog entry on how to set up multiple php versions using different apache instances It is geared towards linux installs. Jamie Burns has a similar blog entry, aimed at windows

12 thoughts on “Running multiple php versions on a single Apache install”

In step 3 you mentioned that each php version should have it’s own php.ini file in the same directory as it’s php.exe. Sounds good, but how to tell those executables to use them and not to use %windir&%\php.ini?

My http.conf allows only one PHPIniDir. Defining another one in a VirtualHost gives: Only first PHPINIDir directive honored per configuration tree – subsequent ones ignored.

@Hb: I only use one single PHPIniDir directive. It is used by the phpversion that is run as an Apache module. All the other php versions are running as cgi applications, and as such would ignore PHPIniDir anyway. For those, I use SetEnv PHPRC “path to ini file” instead, as you can see in my httpd.conf example. I have tried with apache 2.0 and 2.2, and I have had no problems so far…

I am new to php and for apache. I have doe the setup for multiple versions of php as mentioned above, but when i tried to access the application with another version of php using different port number am getting below error.

Forbidden
You don’t have permission to access /php423/php.exe/dcs/index.php on this server.

@Jaime in this day and age, I would run php as php-fpm, and connect it to Apache using mod_proxy_fcgi.
You can easily set up 2 php-fpm processes, listening on different ports.
Then you can use apache mod_proxy_fcgi to proxy to the correct fpm ‘daemon’ based on vhost, path or what you prefer