PHP versions

The PHP panel lists every php formula Homebrew has installed, newest first, and shows which one is in charge of what.

Two switches, not one

There are two independent things called "the PHP version", and Vhostly exposes them separately because they are separately wrong most of the time.

Apache loads exactly one PHP module. That is the version every static site on the machine runs, and it is what Switch and restart changes.

The terminal runs whatever php resolves to on your PATH. That is what php artisan and composer use, and it is what Use in terminal changes.

Either can be pointed at any installed version, and they do not have to agree.

This is machine-wide

Read this before you plan around it: PHP is not per-site. Apache loads one libphp.so, and every static site served by that Apache uses it. Switching to 8.1 for a legacy project switches every other project too, until you switch back.

If you need two versions serving at once, the way to do it today is a proxy site: run the odd project under its own PHP — php -S, FrankenPHP, a container — and point a proxy vhost at it. Apache keeps serving everything else with the module it has loaded.

Switching Apache's PHP

Switch and restart rewrites one line in httpd.conf:

LoadModule php_module /opt/homebrew/opt/php@8.3/lib/httpd/modules/libphp.so

and restarts Apache. If the line was commented out, switching also uncomments it, which is the usual fix for "Apache downloads my .php file instead of running it".

A version only appears as switchable if it actually ships that module. Some formulae do not, and Vhostly says so rather than writing a path that would stop Apache from starting.

Switching the terminal's PHP

Use in terminal unlinks every other php formula and runs:

brew unlink php@8.4
brew link --overwrite --force php@8.3

The panel shows the commands it ran. Open a new shell afterwards — your current one has the old path cached.

This is Homebrew's own linking, so it behaves exactly as it would if you typed it. If you manage PHP versions with something else, phpenv or asdf, leave this alone and let your tool own the PATH.

Installing another version

Anything Homebrew is missing is offered under Other versions — php, php@8.4, php@8.3, php@8.2, php@8.1. Installing runs brew install and can take a while, especially if Homebrew decides to build from source.

Versions installed outside the app appear as soon as you press Refresh.

php.ini and modules

Each formula keeps its own php.ini, in the location Homebrew chose for it. The panel shows the resolved path — from php --ini — so you can open it, and lists the extensions that version has compiled or loaded.

Vhostly never edits php.ini. After you change one, restart Apache from the Apache panel for the module to pick it up; a new terminal is enough for the CLI.