Homebrew is how I tend to manage all of my local packages. It works great for me and gives me the flexibility of installing my own packages without the complexity and overhead of a system like Boxen which I used for a couple of years and had a great love/hate relationship trying to learn all about it. But it turned out in the long run to be just a bit too much effort for the return.
It is very easy to install multiple versions of php simultaneously. You can simply run:
$ brew taps homebrew/homebrew-php $ brew install php56
php56, can be any valid php version that is available:
$ brew search /php\\d\\d$/ homebrew/php/php53 homebrew/php/php54 homebrew/php/php55 homebrew/php/php56 homebrew/php/php70 homebrew/php/php71
The issue with this system is that by itself,
brew tends to want the php binary being installed to be linked to
/usr/local/bin/php. Many suggestions have you swap out which php binary is symlinked to
/usr/local/bin/php but that is always fraught with peril since you then need to remember which version is current in each project.
I work on a number of different PHP based projects, mostly Drupal or Symfony. So this is where I turned to a project called phpenv. phpenv is based on a similar project for Ruby named rbenv.
$ brew install phpenv
The upshot is that instead of running PHP out of a normal location like
/usr/local/bin, instead, we link
php to the phpenv "shim" which is a wrapper. The wrapper checks for a file named
.php-version starting in the current directory and working its way up through parent directories. If it can't find one, it checks for a global variable set in
~/.phpenv/version which can be set with:
$ phpenv global 5.6
You can set local versions simply by swapping the "global" modifier with "local".
$ phpenv local 5.6
Since phpenv was built to install new versions of php directly, we needed to adapt it to using brew installed versions of php. Normally, phpenv would have a list of possible versions in the
~/.phpenv/versions/ directory. So instead of building them there, we simply create symlinks to where brew has installed versions of php.
$ ls -l ~/.phpenv/versions/ total 48 lrwxr-xr-x 1 eporama staff 32 Oct 14 16:24 5.6 -> /usr/local/Cellar/php56/5.6.26_3 lrwxr-xr-x 1 eporama staff 32 Oct 14 16:24 7.0 -> /usr/local/Cellar/php70/7.0.11_5 lrwxr-xr-x 1 eporama staff 36 Oct 14 16:24 7.1 -> /usr/local/Cellar/php71/7.1.0-rc.3_8
Keeping php versions updated
To keep these up to date, simply running
brew upgrade doesn't work since brew doesn't like to update or install any new version of php when there is a different version already linked. Since Brew is unaware that we're going to use
phpenv, it is assuming that you want to link
/usr/local/bin/php to the version of php that you are installing, so if you install a different version, it will complain if the previous version is still linked. Luckily, it's fairly straight forward to link and unlink the binaries that are provided by any brew project. For example, if you currently had php-5.6 installed and linked, but wanted to update php-7.0, you would need to unlink php-5.6, then update and reverse the linking afterward.
$ brew unlink php56 $ brew update php70 $ brew unlink php70 $ brew link php56
I don't need to do most of that because I always leave the php packages unlinked so that
phpenv can handle them.
To wrap it all together
We wrap all of these together in a handy script that will update php via brew and remake all of the appropriate phpenv symlinks.