How To Run Multiple PHP Versions

The PHP programming language has gone long way since its beginnings. It made another big step by making it easy and convenient to run Apps in different versions of PHP at the same time. In this post, I go over the compiling of any PHP Version you wish, installation of the PHPFarm technology and the configuration of the Apache web server, all of which part of the task to run different PHP versions simultaneously on one machine with different apps

System: Ubuntu 14, Apache 2.4, LAMP

Installation of PHPFarm

Before compiling different versions of PHP, we install the PHPFarm. To do so

Step 1 – Install supporting necessary libraries:
udo apt-get install libxml2 libxml2-dev libssl-dev
sudo apt-get install libcurl4-openssl-dev pkg-config
sudo apt-get install libcurl4-gnutls-dev libjpeg-dev libpng12-dev libmysqlclient-dev
Step 2 – Install the PHPFarm

We grab the PHPFarm from PHPFarm Git repo

cd /home/tools
sudo git clone https://github.com/cweiske/phpfarm

This will clone PHPFarm at /home/tools/phpfarm directory

Compile PHP Versions

Once, we have the PHPFarm, lets compile some version of PHP.

Step 3 – Custom Configurations

First, we specify some custom configurations for new php version. Go to the ‘src’ directory of PHPFarm and create file of certain naming

cd /home/tools/phpfarm/src
sudo vim custom-options-5.3.29.sh

For some example of custom options, please see AmacGregor Git Repo
In our case, we use the following custom options by inserting them in the /home/tools/phpfarm/srccustom-options-5.3.29.sh:

#gcov='--enable-gcov'
configoptions="\
--enable-bcmath \
--enable-calendar \
--enable-exif \
--enable-ftp \
--enable-mbstring \
--enable-pcntl \
--enable-soap \
--enable-sockets \
--enable-sqlite-utf8 \
--enable-wddx \
--enable-zip \
--disable-debug \
--with-mysql \
--with-zlib \
--with-gettext \
--with-pdo-mysql \
--with-curl \
--with-openssl \
$gcov"
Step 4 – Compile PHP

Next, we compile new PHP version with our custom options:

cd /home/tools/phpfarm/src
sudo ./compile.sh 5.3.29

This will generate new version of PHP 5.3.29. Afterwards, test that it is working

cd /home/tools/phpfarm/inst/bin
./php-5.3.29 --version

Configure Virtual Host of Apache For Certain Version

Step 5 – Install supporting modules of PHPFarm for Apache

The FastCGI is technology to incorporate PHPFarm into Apache, so we are installing supporting libraries

sudo apt-get install libapache2-mod-fastcgi apache2-mpm-worker apache2-suexec
sudo a2enmod actions fastcgi suexec
sudo service apache2 restart

After restarting Apache service, the newly installed modules are included

Step 6 – Mapping CGI to PHPFarm

Next, we create web directory with configurations to map each PHP Version to the CGI service of Apache

sudo mkdir /var/www/cgi-bin
cd /var/www/cgi-bin
sudo vip php-cgi-5.3.29

Afterwards, we are adding mapping in form of Bash script named php-cgi-5.3.29 as follows

#!/bin/sh
PHPRC="/etc/php5/cgi/5.3.29/"
export PHPRC
PHP_FCGI_CHILDREN=3
export PHP_FCGI_CHILDREN
PHP_FCGI_MAX_REQUESTS=5000
export PHP_FCGI_MAX_REQUESTS
exec /home/tools/phpfarm/inst/bin/php-cgi-5.3.29

As you see the last line it maps to our PHP version. The variable “PHPRC” also specifies the location of php.ini file to use. By default, it uses the php.ini in the dir of /home/tools/phpfarm/inst/php-cgi-5.3.29/lib.php

Make our file of mapping is executable and chown rights to apache user („www-data“ by default):

sudo chmod +x /var/www/cgi-bin/php-cgi-5.3.29
sudo chown -R www-data:www-data /var/www/cgi-bin
Step 7 – Configure Virtual Host of Apache

At last, we configure particular application via Virtual Host Configurations at Apache to use the PHPFarm and our certain version of PHP by editing /etc/apache2/sites-enabled/some-domain.conf

<VirtualHost *:80>
	DocumentRoot /home/websites/min-view-drupal
	ServerName minnehaha.com
	ServerAlias www.minnehaha.com
	#LogLevel debug
	#FastCgiServer /home/websites/cgi-bin/php-cgi-5.3.29
    	FastCgiServer /home/websites/cgi-bin/php-cgi-5.4.27
	ScriptAlias /cgi-bin-php/ /home/websites/cgi-bin/
	<Directory "/home/websites/min-view-drupal">
		Options Indexes MultiViews FollowSymLinks
		AllowOverride All
		Require all granted
		AddHandler php-cgi .php
		#Action php-cgi /cgi-bin-php/php-cgi-5.3.29
		Action php-cgi /cgi-bin-php/php-cgi-5.4.27
		<FilesMatch "\.php$">
                	SetHandler php-cgi
            	</FilesMatch>
	</Directory>
	<Directory "/home/websites/cgi-bin">
   		Order allow,deny
   		Allow from all 
  		Require all granted
	</Directory>
 	Errorlog "${APACHE_LOG_DIR}/virtual-hosts/minnehaha/error.txt"
	CustomLog "${APACHE_LOG_DIR}/virtual-hosts/minnehaha/customLog.txt" common
</VirtualHost>

Here, all the highlighted lines involve configuring the PHPFArm. The line 7,8 includes the PHPFarm service. The lines 13-18, enables the certain version for our application. The lines 20-24 enables apache server to read our mapping configuration file which should be moved to general Apache configuration script since this directory may be shared between other Virtual hosts. In short if you have multiple Virtual Hosts then the following should be moved into general to declare only once:

...
FastCgiServer /home/websites/cgi-bin/php-cgi-5.4.27
ScriptAlias /cgi-bin-php/ /home/websites/cgi-bin/
...
<Directory "/home/websites/cgi-bin">
   		Order allow,deny
   		Allow from all 
  		Require all granted
	</Directory>
...

At last, restart Apache to load our newest changes:

sudoe services apache2 restart
Step 8 – Test it

To test it, include the phpinfo command into the index.php file of the root dir(i.e./home/websites/min-view-drupal) of the application

<?php phpinfo();?>

This should display php version along other setting once pointing the browser to the application of virtual host configured above(i.e. minnehaha.com)

Switching PHP Versions

After compiling another version of PHP as we did in Step 4, the switching between PHP Versions is as easy as configuring apache virtual host to read another mapping as done in Step 8(see commented out php version 5.4.27) to point to another php version done by creating new mapping as done in Step 7.

Troubleshooting

1. client denied by server configuration:

This error we got when the location(i.e. /home/websites/cgi-bin) of our mapping script of step 7 wasn’t configured to be loaded by Apache in virtual host missing the following:

<Directory "/home/websites/cgi-bin">
   		Order allow,deny
   		Allow from all 
  		Require all granted
	</Directory>

By including the above snippet and restarting Apache, the problem was solved

2. FastCgiServer: redefinition of a previously defined FastCGI server phpFarm

This error appeared when I declared the following in multiple Virtual host configurations:

FastCgiServer /home/websites/cgi-bin/php-cgi-5.4.27
ScriptAlias /cgi-bin-php/ /home/websites/cgi-bin/

Once, I moved it out into the general apache configuration while commenting out all other instances, it solved the problem

Sources

  • https://github.com/cweiske/phpfarm
  • http://www.jabommi.de/wiki/downgrade-php-5-5-to-5-3-ubuntu-14-with-multiple-php-versions/
  • https://wiki.apache.org/httpd/PHP-FPM
  • https://www.howtoforge.com/how-to-use-multiple-php-versions-php-fpm-and-fastcgi-with-ispconfig-3-ubuntu-12.04-lts
  • http://geekpad.ca/blog/post/compiling-php-and-php-fpm-part-2
  • http://www.sitepoint.com/run-multiple-versions-php-one-server/
  • https://gist.github.com/amacgregor/11041627#file-custom-options-sh

Upgrading PHP on Mac and Ubuntu

In this post we list the steps of installing php 5.4, however, the steps are the same for any version. You may have to choose different binary names but for those you can look up in macports.com. In addition, once multiple versions of php binaries installed, it is easy to switch between the versions. It involves only two steps – activate proper version binaries all of which covered in this post

Mac

Step-1 Installing PHP 5.4
We use macports packaging management system to fetch artifacts

sudo port selfupdate
sudo port install php54
sudo port install php54-gd
sudo port install php54-mysql
sudo port install php54-apache2handler
sudo port activate php54
sudo port activate php54-gd
sudo port activate php54-mysql
sudo port activate php54-apache2handler

The activate commands may not need to be run since its auto activate when running ‘port install’, however. We list here for information

Step-2 Enable PHP in Apache
When installing php54-apache2handler module via MacPorts, it downloads php54.so binary for apache and places it in the /path/to/apache2/modules folder(in our case it is /opt/local/apache2)

So, you have to tell Apache load the new php54 version binary by replacing following lines in apahce configure file http.conf (/path/to/apache2/http.conf) as following:

LoadModule php5_module libexec/apache2/libphp5.so

–with–

LoadModule php5_module modules/mod_php54.so

Afterward, restart Apache service. This ensure that the php module is loaded.

Note: you may want to confirm that the new module ‘mod_php54.so’ with proper permissions is present (for mac 10.7 in /path/to/apache2/modules)

Step-3 Customize PHP

cd /opt/local/etc/php54
cp php.ini-development php.ini

Step-4. Verify Php Version
To verify, run:

php -v

The version may be different. This happens if you have php already installed, then you have to remove the default PHP configuration:

which php
/usr/bin/php
sudo rm /usr/bin/php
sudo ln -s /path/to/php/executable php

Here, we removed the pointer to the old php executable and create reference to the new one. MacPorts downloads the new php executable in /opt/local/bin directory and name it ‘php55’

Aftewards, the ‘php -v’ should match with version you installed.

Switching PHP Version
To switch between versions you would run:

sudo port select --set php php54

And then updating /path/to/apache2/http.conf to load proper *.so module for the particular PHP

...
LoadModule php5_module modules/mod_php54.so
...

To see what php modules available and their exact naming see ‘/path/to/apache2/modules’

To see MacPorts logs

To see MacPorts logs

 /opt/local/var/macports/logs/

Uninstalling before upgrading
You may have to uninstall before you can install newer version. If so, make sure first deactivate/uninstall dependencies i.e. php5-gd and php5-mysql. Please see more
How to Deactivate One Macport Variant and Switch to Another One

Ubuntu

For ubuntu

sudo apt-get install python-software-properties
sudo add-apt-repository ppa:ondrej/php5-oldstable
sudo apt-get update
sudo apt-get install php5
sudo apt-get install php5-mysql
sudo apt-get install php5-curl
sudo apt-get install php5-gd

The ‘php5-oldstable’ is for PHP 5.4. For the php5.5 there is ppa:ondrej/php5, however. The repository ppa:ondrej/php5 doesn’t seem to have lucid Ubuntu distribution as well it is upgrading to Apache2.4 which a lot of changes.

The ‘python-software-properties’ is installed in order to use ‘add-apt-repository’ command, however. you as well manually can add the repository at /etc/apt/sources.list as following:

deb http://ppa.launchpad.net/ondrej/php5-oldstable/ubuntu lucid main
deb-src http://ppa.launchpad.net/ondrej/php5-oldstable/ubuntu lucid main

If you may need to uninstall php on ubuntu:

sudo apt-get -y purge php*

or more conservative approach:

sudo apt-get -y purge libapache2-mod-php5 libapache2-mod-php5filter libexpect-php5 libgv-php5 libow-php5 php5 php5-adodb php5-auth-pam php5-cgi php5-cli php5-common php5-curl php5-dbg php5-enchant php5-exactimage php5-ffmpeg php5-fpm php5-geoip php5-gmp php5-idn php5-imagick php5-imap php5-interbase php5-intl php5-json php5-lasso php5-ldap php5-librdf php5-mapscript php5-memcache php5-memcached php5-mhash php5-midgard2 php5-ming php5-mssql php5-mysql php5-mysqlnd php5-odbc php5-pgsql php5-ps php5-pspell php5-radius php5-recode php5-remctl php5-rrd php5-sasl php5-snmp php5-sqlite php5-suhosin php5-svn php5-sybase php5-tidy php5-tokyo-tyrant php5-uuid php5-xcache php5-xdebug php5-xmlrpc php5-xsl

You can also search for all php packages as following:

sudo aptitude search php5|awk {'print $2'}|grep -v i386|grep -v "^A"|tr "\n"  " "

Other

1. How to locate a dir from which the Apache is currently running on your machine

ps -ef | grep apache

2. How to locate a dir from which the current installation of PHP is running from on machine
Create php config info file – phpinfol.php and place the following.

<?php phpinfo(); ?>

Afterwards, open this file in the browser

Issues

1. Page Not Found

After doing everything and pointing to phpinfo.php, the browser returns page not found. the issue was that it was loading the php module from the wrong dirrectory. The http.conf was containing:

...
LoadModule php5_module modules/mod_php54.so
...

But needed to be:

LoadModule php5_module libexec/apache2/mod_php54.so
2. Exception: Stripe needs the CURL PHP extension. in require_once()[…]

One of the libraries(Stripe) is using CURL, so i forgot to install. To do so:

sudo port install php54-curl

For Ubuntu

sudo apt-get install php5-curl

This also activates the php-curl, so all is left to restart the apache server. Depending on you PHP Version, there may be different php-curl module to install. Please see macports.com for list of packages and versions

3. Stripe needs the Multibyte String PHP extension

Here the Stripe module is using MultiByte String lib that is missing. To install

sudo port install php54-mbstring  

Depending of your PHP Version, you may have to install a different version of mbstring lib. Afterwards, make sure to restart the apache server

3.PDOException: SQLSTATE[HY000] [2002] No such file or directory in lock_may_be_available()

(line 167 of /Users/maxit/Sites/drupal/commerce/first-commerce/includes/lock.inc)

By default, mysql is configured not to use TCP connection(particular for php55), so your sites will break. For solution see post Installing Mysql On Mac for ‘ERROR 2003 (HY000): Can’t connect to MySQL server on 127.0.0.1’

References

Installing PHP 5.2 and configure Apache 2.2 on Windows & Linux

 

Over the years it has been times when i have to reinstall PHP to configure with Apache to work together. Today, it has been that occasion where i have to set up my local developing environment on new laptop to support some WordPress, Zend and Magento developments. It has never been a smooth process and it was no different this time….i guess i was too naive thinking that things have changed….Perhaps, things have changed, i just should have looked at new ways – deploying on cloud via Saas, however. This post is PHP(3.2.17) installed and configured with Apache 2.2.22

 

Installing PHP 5.2

My first failure come with the fact that the newest PHP 5.4 and 5.3 does not support Apache. Make sure you download the right  version VC6 (on Sep 13,2012).  Later, i also learn there is differences between Thread Safe and Non-Thread Safe versions. To run with Apache 2.2.22, you need Thread safe version

1. Download proper PHP version to work with Apache on Windows

2. Extract to your chosen directory. In our case, we use ‘C:/DevTools/php’

3. Update the windows environment variable ‘Path’.

We create new variable ‘PHP_HOME’ and then append ‘%PHP_HOME%’ to the ‘PATH’ variable. To check it works, open command line and type ‘php -v’. If it works then you should see php version displayed

 

Configuring Apache 2.2

I have Apache 2.2.x installed and tested currently. For how to install Apache server, please, consult other source

1. Edited Apache Configuration file httpd.conf (by default in C:\Program Files\Apache Software Foundation\Apache2.2)

In the httpd.conf, we add these lines,  right below the other LoadModule lines:
LoadModule php5_module "c:/DevTools/php/php5apache2_2.dll" #(change the path to wherever the file is)
AddType application/x-httpd-php .php .phtml .inc .php3
AddType application/x-httpd-php-source .phps

!!! Important to note, if you have Apache2.0, then use php5apache2.dll instead of php5apache2_2.dll

 

2. For Apache to use index.php as the default index page, change the line
DirectoryIndex index.html
-to-
DirectoryIndex index.php index.html index.htm

 

3. Copy the file “php5ts.dll” to “c:\Program Files\Apache Group\Apache2\bin\”.

The ‘ts’ at the end of php5ts.dll must mean Thread Safe, so if you don’t see it you must have happen to download & install non thread safe version of PHP that will not work with Apache 2.2.22

 

4. Copy the file “php.ini-recommended” to c:\Program Files\Apache Group\Apache2\ and rename it to “php.ini”

 

5. For PHP sessions to work properly, you need to specify where to save the sessions.

Edit the php.ini file, and find the setting for session.save_path. Set it to “c:\windows\temp\” or another folder you use as a temp directory.

5a.Enable GD extension for Image handling
The GD extension is used so often to handle the images that we recommend to enabled this extension at this time. To do so uncomment the following line and specify path to the GD extension in php directory

extension="C:\path_to_php\ext\php_gd2.dll"

 

6.  Restart Apache server:

Go to start -> run -> services.msc

or

From Apache Service Monitor (Start->All Programs->Apache HTTP Server 2.2->Apache Service Monitor->ReStart)

Test Drive

Its time to test our php configuration to work with appache server. To do so, create a file phpinfo.php with content:

<?php print phpinfo(); ?>

Save this file into dir Apache is serving pages(by default its “c:\Program Files\Apache Group\Apache2\htdocs”)
This should display php configuration info file that is also useful when installing add-ons of PHP because you can come here and always check if a particular add-on was installed for the PHP

Configure MySql

We assume you have mysql installed. To configure PHP to work with mysql you have to uncomment the following line and specify path to the libraries in php.ini file

extension="C:\path_to_php\ext\php_mysql.dll"
extension="C:\path_to_php\ext\php_pdo_mysql.dll"

This will enable necessary libraries for your php sites to talk to mysql database. We also enabled pdo_mysql library that is often used by opens source platforms such as Drupal

Virtual Hosts

Virtual host allows you easy to configure multiple sites to run on your apache server with different domain names

1. Enable Virtual Hosts

To enable the virtual hosts, uncoment the following line in path_to_apache/conf/httpd.conf

# Virtual hosts
Include conf/extra/httpd-vhosts.conf

Here we uncomment line ‘Include..’ so the vhosts configurations are loaded

2. Configure Virtual host

To configure virtual host, add the following in path_to_apache/conf/extra/httpd-vhosts.conf

<VirtualHost *:80>
    DocumentRoot "C:\path_to_sites\my-site"
    ServerName some-domain
    <Directory C:\path_to_sites\my-site>
        Options FollowSymLinks
        AllowOverride All
	Allow from all
	Order Deny,Allow
    </Directory>
    ErrorLog "C:\server\apache\logs\stefan-cascade-error_log"
    CustomLog "C:\server\apache\logs\stefan-cascade-access_log" common
</VirtualHost>

Here, the ‘DocumentRoot and ‘Direcory’ specifies the path where is the code base for your site located. The ‘ServerName’ specifies domain name of your site(i.e. some-domain). This can be anything as long as you update the hosts file to point request to your local computer/apache server the next step

3. Point Domain name to Apache server

In previous step, you specified domain. Lets update hosts file, so all requests made to this domain name from your browser goes to the local apache server. To do so update %SystemRoot%\system32\drivers\etc\hosts as following

127.0.0.1      some-domain

This will make all requests to ‘some-domain’ go to your local computer/apache server

Test Virtual Host

Create file of index.html with some text and put it into your virtual host as specified above(i.e.C:\path_to_sites\my-site). Afterwards restart apache and open browser with ‘some-name’ as url. This should display the text in your index.html file

Issue Encountered

1. When restarting Apache, it was giving the following error:

“The Requested operation has failed!”

The Apache logs showed no clues of whats the problem, so I run 'httpd.exe -e debug' from command line in apache/bin folder. From there, it was clear the problem:

Solution: this is because we are installing PHP that is Non-Thread safe version but Appache 2.2.22, apparently, requires to have PHP Thread Safe

2. “Permission denied: AH00529: […].htaccess pcfg_openfile: unable to check htaccess file”

This happens when the Apache user (often www-data or if not, check the file – envvars in apache dir) doesn’t have access to read your web directory. The solution is to add Appache user to the group assigned to the web dir

usermod www-data --append --groups root

Here, we add user www-data to a group named root that is currently assigned to the web directory serving your site

AH01630: client denied by server configuration

This error came after upgrading from Apache 2.2 to Apache 2.4 with old configurations of “Order allow,deny

Allow from all” in virtual host setting in 2.2 with new configuration of”Require all granted” in the 2.4

Other

1. Host File

In case you forgotten, the host file in windows are located

 	%SystemRoot%\system32\drivers\etc\hosts