I prefer working with #Docker, but sometimes it’s required to have #PHP locally, and even more - multiple versions of it! There’s a simple way of achieving this: ASDF 😎.
First of all, you need to install asdf
using method of your choice, after that you need to add this to your ~/.zshrc
:
export PATH="${ASDF_DATA_DIR:-$HOME/.asdf}/shims:$PATH"
ASDF’s shim files have to be discoverable before any other binaries on your machine, to handle calls to the tools and resolve desired version (no worry, it’s possible to fall back to system versions too).
The next step is enabling PHP plugin:
asdf plugin add php
Installing PHP versions is really straightforward, all you need to do is execute asdf install php 8.4.10
, and then in any directory where you want to use this version: asdf set php 8.4.10
. The idea behind ASDF is that it keeps .tool-versions
file with a list of versions that must be used under this directory and its subdirectories. It looks like this:
php 8.4.10
nodejs 24.4.0
If you’re using p10k
, then you even can see what version of PHP is configured for specific directory you’re currently in:

In terms of PHP, before installing first version you most probably need to install some OS libraries, so ASDF can compile PHP from sources. In my case, for newly configured MacBook, I had to run:
brew install autoconf bison gd icu4c@77 libiconv libsodium libzip pkgconf re2c
Also, to get rid of SSL-related build failures, some configure options have to be passed when installing PHP:
PHP_CONFIGURE_OPTIONS="--with-openssl=$(brew --prefix openssl) --with-iconv=$(brew --prefix libiconv)" asdf install php 8.4.10
Using PHP_CONFIGURE_OPTIONS
you can modify how PHP’s build process will look like, it’s really powerful and flexible, but most importantly can solve your issues when your PHP installation requires a lot of additional extensions (like imagick
, grpc
or other).
When you have PHP version compiled and working, you may want to install another extensions using PECL or PIE. During the installation, it may be required to provide paths to libs used by that extensions - just use brew --prefix <lib>
in separate terminal, so you can copy & paste correct path. It can be sometimes tricky, because Homebrew packages’ names not necessarily match extensions’ names. Here are example mappings:
- for
imagick
extension you need to usebrew --prefix imagemagick
- for
amqp
extension you need to usebrew --prefix rabbitmq-c
- for
rdkafka
extension you need to usebrew --prefix librdkafka