A PHP version manager on a Mac solves one recurring problem: client A's app needs PHP 8.1, client B's needs 8.4, and the legacy project you inherited still runs 7.4 — on an operating system that ships no PHP at all (Apple removed it in Monterey). There are five working approaches in 2026: Homebrew's link/unlink dance, the shivammathur tap for versions Homebrew core dropped, phpbrew, per-site switching inside Valet or Herd, and per-project pinning in a managed environment. Here's each one with its honest cost.
Homebrew core: the link/unlink dance
brew install [email protected] [email protected]
brew unlink [email protected] && brew link --force [email protected]
php -v # 8.1 is now globalThis is the baseline, and its two limits define the whole topic. First, Homebrew core only carries currently-supported PHP versions — when a version goes end-of-life upstream, the formula eventually goes with it, which is no help for the 7.4 project. Second, the switch is global: one active php on your PATH at a time, so working on two projects means switching back and forth all day, plus restarting php-fpm if a web server is involved.
The shivammathur tap: every version back to 5.6
brew tap shivammathur/php
brew install shivammathur/php/[email protected]
brew link --overwrite --force shivammathur/php/[email protected]The shivammathur/homebrew-php tap is the de-facto answer for versions core won't give you: PHP 5.6 through 8.6 (the next version, built nightly), actively maintained — the tap saw commits this week. Switching is still global link/unlink, but for servingtwo versions at once there's a real pattern: run each version's php-fpmon its own port and point your web server's config at the right one per site. That works and scales; it's also exactly the multi-file nginx setup our macOS Tahoe PHP guide walks through — budget an afternoon and expect to revisit it after OS upgrades.
phpbrew: the old guard
phpbrew builds PHP versions from source into your home directory and switches per shell — closer to nvm's model than Homebrew's. It deserves its 5.5k GitHub stars historically, but the honest 2026 status is maintenance mode: the last release (2.2.0) shipped in December 2023, and source builds mean you own every extension compilation error yourself. If you use it happily today, fine; we wouldn't start a new setup on it.
Per-site switching: Valet and Herd
The Laravel-ecosystem tools move the switch from your shell to the site. Valet's valet isolate [email protected] pins a version to one site — though Valet is a layer over your own Homebrew PHP installs, so the version juggling above remains yours to maintain underneath. Laravel Herd bundles its own binaries (7.4–8.5) and switches per site from a GUI — the smoothest of the manual options, with the trade that databases, mail and multi-version Node sit behind the $99/year Pro tier. MAMP also bundles multiple PHP versions, but only two are visible at once and the rest of the tooling shows its age.
Per-project pinning, no shell config
The version-manager problem dissolves if versions belong to projects instead of to your PATH. That's the model PortBay (free, open source, macOS) uses: each project pins its PHP version, every version runs side by side as its own php-fpm, and nothing is ever “the global PHP” — switching projects is opening a different folder, not relinking a binary. The runtime comes provisioned with the rest of the stack (a per-project database, trusted HTTPS on .test, mail capture), and the honest trade is scope: macOS only, web stacks only — if you need PHP inside arbitrary shell scripts on a global PATH, the Homebrew routes above stay relevant. Download it and the 7.4 legacy project and the 8.4 greenfield run at the same time without a single brew link.
Side by side
| Approach | Versions available | Switching model | Versions in parallel? |
|---|---|---|---|
| Homebrew core | Supported versions only | Global link/unlink | Only via manual php-fpm ports |
| shivammathur tap | 5.6 – 8.6 | Global link/unlink | Only via manual php-fpm ports |
| phpbrew | Anything it can compile | Per shell | Per shell, manual serving |
| Valet (isolate) | Your Homebrew installs | Per site | Yes, per site |
| Laravel Herd | 7.4 – 8.5 bundled | Per site (GUI) | Yes, per site |
| PortBay | Managed, multi-version | Pinned per project | Yes, automatic |
How to choose
One project, current PHP: Homebrew core and move on. A legacy version in the mix: add the shivammathur tap — it's the community standard for a reason. Laravel-centric and happy to pay: Herd. Multiple client projects on different versions that should all just serve simultaneously: per-project pinning is the model that removes the problem rather than managing it — PortBay does that for free, and the wider PHP-on-Mac guide covers how the version question fits the full local stack.
