Managing multiple versions of PHP on Mac OS X with Homebrew

The blog is currently being ported from WordPress to over 12 years of static pages of content. If there's an article missing that you're hoping to see, please contact me and let me know and I'll prioritize getting it online.

October 12, 2016


I sense a trend starting.

A few weeks ago, I wrote a post about managing different versions of Python on Mac OS X, and today I’m going to explain how I use multiple versions of PHP on the same platform.

The Problem

Until the homebrew-php group figure out a better way of handling several versions of PHP (their instructions haven’t worked for several months), and without installing something like phpenv, I concocted my own means to manage PHP versions using bash aliases similar to my Python post.

(Command line output that I’ve pasted below may be truncated for brevity.)

Step 1: Install your favorite versions of PHP

Homebrew is still awesome at installing PHP, but trying to install multiple versions back-to-back will produce errors:

$ brew tap homebrew/dupes
$ brew tap homebrew/versions
$ brew tap homebrew/homebrew-php
$ brew install php{5{5,6},7{0,1}}
...
Error: Cannot install homebrew/php/php56 because conflicting
formulae are installed.
 
  php55: because different php versions install the same binaries.
 
Please `brew unlink php55` before continuing.

There’s an easy way around it:

$ for i in 55 56 70 71; do 
> brew install php$i
> brew unlink php$i
> done

This will install PHP 5.5, 5.6, 7.0 and 7.1, unlinking each version right after its installation, and leaving you with PHP 7.1 as your system default.

Step 2: Bash aliases

I put all of my aliases in a .bash_aliases.sh file in my home directory and call that from within my .bashrc file. (your system may use .bash_profile which will operate in the same way.

# ~/.bashrc
# put this at the bottom of the file
if [ -f ~/.bash_aliases.sh ]; then
    . ~/.bash_aliases.sh
fi
# ~/.bash_aliases.sh
 
function unlink_php {
  for i in `ls -1 /usr/local/opt/ | grep php | cut -c4-5 | uniq`; do
    brew unlink php$i > /dev/null
  done
}
 
for i in `ls -1 /usr/local/opt/ | grep php | cut -c4-5 | uniq`; do
  alias php$i="unlink_php && brew link php$i"
done

The unlink_php function basically auto-detects which versions of PHP you have installed with homebrew, and unlinks all of them. I’m sure you could be clever and detect via php -version which version is currently linked and just unlink that one, but this gives me peace of mind that ALL versions are properly unlinked.

Then, it uses the same auto-detection to create aliases for each version which also calls the unlink_php function so any time I switch to a different PHP version, Homebrew will unlink all others and re-link the version I want.

Now you can source that aliases script and you should be in business:

$ source ~/.bash_aliases.sh

Step 3: Magic

Verify that your new aliases are made:

$ alias | grep php
alias php55='unlink_php && brew link php55'
alias php56='unlink_php && brew link php56'
alias php71='unlink_php && brew link php71'

And then you can switch your version of PHP using your alias:

$ php55
Linking /usr/local/Cellar/php55/5.5.38_11... 17 symlinks created
$ php --version
PHP 5.5.38
 
$ php71
Linking /usr/local/Cellar/php71/7.1.0-rc.3_8... 17 symlinks created
$ php --version
PHP 7.1.0RC3