Skip to content
PortBay

Local development

PHP version manager for Mac: every working option in 2026

Homebrew's link dance, the shivammathur tap back to 5.6, phpbrew in maintenance mode, per-site switching in Valet and Herd — and the per-project model that removes the problem instead of managing it.

Nour Beiruti8 min read

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 global

This 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

ApproachVersions availableSwitching modelVersions in parallel?
Homebrew coreSupported versions onlyGlobal link/unlinkOnly via manual php-fpm ports
shivammathur tap5.6 – 8.6Global link/unlinkOnly via manual php-fpm ports
phpbrewAnything it can compilePer shellPer shell, manual serving
Valet (isolate)Your Homebrew installsPer siteYes, per site
Laravel Herd7.4 – 8.5 bundledPer site (GUI)Yes, per site
PortBayManaged, multi-versionPinned per projectYes, 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.

PortBay mascot — a friendly blue tugboat

Run your first local site in one click.

Download for macOS

Free & open source · macOS 11+ on Apple Silicon · Pro from $10/mo