Switching PHP versions when using Homebrew
Homebrew is an excellent option for installing one or more PHP versions on your Mac.
But how can you switch PHP versions when you have installed more than one version of PHP with Homebrew?
Which do you prefer - slowly or quickly?
Scenario
You have installed PHP 7.4, 8.0, 8.1, and 8.2 with Homebrew. You have no idea which PHP version is currently linked, but you want to use PHP 8.2.
Slowly switching PHP versions
First, you need to find out which PHP version is currently linked.
Running
php -v
yields
PHP 7.4.33 (cli) (built: Jan 21 2023 06:43:54) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
with Zend OPcache v7.4.33, Copyright (c), by Zend Technologies
Second, since you know that PHP 7.4 is currently linked, you need to unlink PHP 7.4.
Running
brew unlink php@7.4
yields
Unlinking /opt/homebrew/Cellar/php@7.4/7.4.33_1... 25 symlinks removed.
Third, you need to link PHP 8.2, the PHP version you want to use.
Running
brew link php@8.2 --force --overwrite
yields
Linking /opt/homebrew/Cellar/php/8.2.1_1... 24 symlinks created.
Fourth, you want to double-check that PHP 8.2 is actually linked now.
Running
php -v
yields
PHP 8.2.1 (cli) (built: Jan 12 2023 03:48:24) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.2.1, Copyright (c) Zend Technologies
with Zend OPcache v8.2.1, Copyright (c), by Zend Technologies
Perfect, you can start working with PHP 8.2 after running four (!) commands.
Quickly switching PHP versions
How about running a single command instead of four commands?
How about running
8.2
to switch from any (!) PHP version to PHP 8.2? Let me show you how you can achieve that in two steps.
First, you need to install a modern version of grep
with Homebrew.
Running
grep --version
on macOS Ventura yields
grep (BSD grep, GNU compatible) 2.6.0-FreeBSD
Unfortunately, that version does not support Perl-compatible regular expressions (PCREs) that you will use in the next step.
Running
brew install grep
yields
==> Fetching grep
==> Downloading https://ghcr.io/v2/homebrew/core/grep/manifests/3.8_1
Already downloaded: /Users/am/Library/Caches/Homebrew/downloads/a2ee255269e00fca81c021b40c338155577736b42bab878651de2922798bd235--grep-3.8_1.bottle_manifest.json
==> Downloading https://ghcr.io/v2/homebrew/core/grep/blobs/sha256:d2450448352fb2c389634cab3dec581882f6fc0f02a79489b4ba9c603b8f780b
Already downloaded: /Users/am/Library/Caches/Homebrew/downloads/aefda17db919b6aed862b1ae9d2deb2d07197fef50b34f0bcacf179108b8fd12--grep--3.8_1.arm64_ventura.bottle.tar.gz
==> Pouring grep--3.8_1.arm64_ventura.bottle.tar.gz
==> Caveats
All commands have been installed with the prefix "g".
If you need to use these commands with their normal names, you
can add a "gnubin" directory to your PATH from your bashrc like:
PATH="/opt/homebrew/opt/grep/libexec/gnubin:$PATH"
==> Summary
🍺 /opt/homebrew/Cellar/grep/3.8_1: 19 files, 1MB
==> Running `brew cleanup grep`...
Disable this behaviour by setting HOMEBREW_NO_INSTALL_CLEANUP.
Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).
💡 Note that the command grep
has been installed with the prefix g
to allow you to use grep
as installed with macOS if necessary.
Second, after careful inspection, add the following shell script to ~/.zshrc
.
# determine versions of PHP installed with HomeBrew
installedPhpVersions=($(brew ls --versions | ggrep -E 'php(@.*)?\s' | ggrep -oP '(?<=\s)\d\.\d' | uniq | sort))
# create alias for every version of PHP installed with HomeBrew
for phpVersion in ${installedPhpVersions[*]}; do
value="{"
for otherPhpVersion in ${installedPhpVersions[*]}; do
if [ "${otherPhpVersion}" = "${phpVersion}" ]; then
continue;
fi
value="${value} brew unlink php@${otherPhpVersion};"
done
value="${value} brew link php@${phpVersion} --force --overwrite; } &> /dev/null && php -v"
alias "${phpVersion}"="${value}"
done
The script will first determine the versions of PHP you have installed with Homebrew.
The script will then create aliases for each PHP version you have installed with Homebrew. For each PHP version, the corresponding alias will unlink all other PHP versions, link the PHP version, and finally show the version information.
By adding the script to .zshrc
, the script will run every time you open a new terminal. This means that the list of aliases will stay current at all times, depending on the versions of PHP that you have currently installed with Homebrew.
When you have PHP 7.4, 8.0, 8.1, and 8.2 installed with Homebrew, added the script to .zshrc
, and opened a new terminal, running
alias | grep php
yields
7.4='{ brew unlink php@8.0; brew unlink php@8.1; brew unlink php@8.2; brew link php@7.4 --force --overwrite; } &> /dev/null && php -v'
8.0='{ brew unlink php@7.4; brew unlink php@8.1; brew unlink php@8.2; brew link php@8.0 --force --overwrite; } &> /dev/null && php -v'
8.1='{ brew unlink php@7.4; brew unlink php@8.0; brew unlink php@8.2; brew link php@8.1 --force --overwrite; } &> /dev/null && php -v'
8.2='{ brew unlink php@7.4; brew unlink php@8.0; brew unlink php@8.1; brew link php@8.2 --force --overwrite; } &> /dev/null && php -v'
As promised, Running
8.2
switches to PHP 8.2 and yields
PHP 8.2.1 (cli) (built: Jan 12 2023 03:48:24) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.2.1, Copyright (c) Zend Technologies
with Zend OPcache v8.2.1, Copyright (c), by Zend Technologies
Have you found a better option for switching PHP versions when using Homebrew?
Do you find this article helpful?
Do you have feedback?
Just blogged: Switching between #PHP versions when using @MacHomebrew:https://t.co/AcFKU7sEuZ
— Andreas Möller (@localheinz) May 5, 2020