Use multiple php versions with Mac OSX, Homebrew and Apache

At work, I have to deal with tons of projects, each one having its own requirements.
And it’s unpredictable: sometimes I need PHP5.3, sometimes 5.4, 5.5, or 5.6.

The problem is: with Apache, in a “classic” usage, one uses mod_php.

Here comes the solution: Mac OSX have the great Homebrew to manage dependencies, and all PHP versions are available.

Here is a configuration of Apache and PHP with fast_cgi to have multiple versions of PHP on the same webserver.

All the code of this article can be found in a Gist, if you need to remember all.

I won’t make a presentation of Homebrew here. The documentation says what it is and how it works.

It’s the missing package manager for Mac OSX.

Also, I won’t talk about configuring nginx with php-fpm, because there are tons of articles about it on the internet.

Here, we’ll talk about using Apache and FastCGI.

Now, once you have installed it, we’ll have to install plenty of other things with it. Let me just call it “brew” until the end of this article, because so.

Install the different components we need

Install ALL php versions you need:

There may be some warnings or alerts because brew sometimes needs to “link” some packages for them to work, just do “brew unlink” or “brew link” when needed to (de)activate the package that conflicts.

Once done, you’ll have to install Apache. As it is not in the default brew repository you have to add it to your list with this command.

But first we need the system duplicates, another repository that “mirrors” the different unix system commands we often use (awk, make, unzip, etc.)

Just tap the repo like this:

And then install your fresh apache repository:

Update all brew repositories (and brew itself in case of):

After adding the repository you can install what you need:

Then, let’s continue.

Create some scripts to allow FastCGI use

FastCGI is an “old” system of using different applications conjointedly (like Apache and PHP).

For Apache and PHP we often use an Apache extension that loads a local PHP application and its config, but it’s “one PHP per Apache”.

FastCGI uses scripts that are executed by Apache and “transferred” into Apache handlers (sort of workers that Apache uses to do things).

Each handler can then be called specificily in some cases, like, for example, calling a PHP handler to interpret PHP code before Apache to send it back to the browser.

Each script look like this:

And should be saved in a file, somewhere.

There should be one cgi file for each PHP version you want.
I like to put them in /var/www/cgi-bin (or /www/cgi-bin on my local machine), depending on where you store your public webserver directory.
For the name, I personally use php56.bash, with the version name it’s cool and readable.

Remember these files, you will need them later in Apache.

So as I said you need one file per PHP version, so it means that if the previous one is made for PHP 5.6, you will have to create maybe a php55.bash or php70.bash, and edit them to change the two versions variables inside (and nothing else).

Configure Apache

Apache has to know, now, that we want to use FastCGI scripts.

For this, there are 2 things to do: configure Apache, and configure each virtual host.

Adding FastCGI to Apache configuration

This is very simple. Take a look at this apache config and append it to yours, like in /etc/apache2/httpd.conf for example, or anywhere you like as long as Apache uses this file in its configuration.

As you may have seen, all PHP FastCGI scripts are commented but as said above they are referenced as the files we created previously.

Uncomment the PHP versions you like to enable in your Apache config.

After that, if there are no errors, you can continue.

Configure Apache vhost to use a specific PHP version

Here is an example of a very simple vhost on your Mac:

In fact the only thing you should care about is to add the two lines that are mandatory to execute PHP in this vhost (because else it’s not executed at all, so be careful of this if you are using your Mac as network-shared computer).

These two lines do the magic so you can add a handler named php-cgi for .php files, and this handler calls the /php-fcgi/php56 action which is “script-aliased” to /var/www/cgi-bin/php56.bash (check back Apache config to see how it’s set up).
Magic!

Obviously, you can change the php56 version to any other version you have installed and configured.

And as it is per each vhost, you can just set up another vhost for another directory/project and it will use another PHP version!

Conclusion

Setting up Apache and FastCGI is not that easy as you saw, but it is actually one of the few solutions you can use to have multiple PHP versions on the same server.

Another solution is to use PHP-FPM with Apache MPM workers, but it’s not easy neither.

You can also use phpenv but it’s a bit apart from Homebrew, and long to configure.

So, yeah, definitely, I think that configuring FastCGI to have multiple versions of PHP in Apache is the best solution.

Or you might look at the awesome Nginx + PHP-FPM stack, which is great. But it’s not Apache, you see.

 

Leave a Reply