pvm is a PHP version manager for the terminal. It installs PHP from Homebrew, switches versions with shell-native hooks, and routes PHP tools through stable shims in ~/.pvm/shims.
- install and uninstall PHP versions with Homebrew
- switch PHP per shell, per project, or globally
- link the global PHP version through Homebrew so external tools like Valet can see it
- support Bash, Zsh, and Fish
- use
.php-versionfiles for project-local selection - keep
php,phpize,php-config,pecl, and related tools stable through shims - install Composer through the official installer so it follows the active PHP version
- manage per-version extension overrides with
pvm ext - inspect PHP config and broken extension directives with
pvm doctor
- Homebrew
- Bash, Zsh, or Fish for interactive shell integration
If Homebrew is missing, pvm can prompt to install it using the official Homebrew installer.
brew tap AtefR/pvm
brew install pvmThen add pvm to your shell:
echo 'eval "$(pvm init bash)"' >> ~/.bashrc
echo 'eval "$(pvm init zsh)"' >> ~/.zshrc
echo 'pvm init fish | source' >> ~/.config/fish/config.fishReload your shell after updating the config.
curl -fsSL https://raw.githubusercontent.com/AtefR/pvm/main/bootstrap.sh | bashThe bootstrap installer copies pvm into ~/.local/share/pvm, creates ~/.local/bin/pvm, and updates the current shell config.
git clone https://github.com/AtefR/pvm.git
cd pvm
./install.shpvm install 8.4 --use
php -v
pvm install 8.3
pvm local 8.3
php -v
pvm global 8.4
pvm currentpvm install 8.4
pvm install latest --use
pvm use 8.3
pvm deactivate
pvm local 8.2
pvm local --unset
pvm global 8.4
pvm global --unset
pvm list
pvm list-remote
pvm currentpvm which php
php -v
phpize --version
pecl versionpvm composer install
composer --version
pvm composer update-self
pvm composer whichpvm ext list
pvm ext disable opcache
pvm ext enable opcache
pvm doctorpvm ext manages only the pvm-owned override layer. It does not rewrite the stock Homebrew PHP config.
pvm resolves PHP in this order:
PVM_VERSIONfrompvm use- nearest
.php-version ~/.pvm/default-version- system PHP outside
pvmshims
pvm global <version> also updates Homebrew's linked php so non-shell-aware tools can use the same version. pvm global --unset removes those Homebrew PHP links.
pvm install <version> [--use]pvm uninstall <version>pvm use [version]pvm deactivatepvm local <version>pvm local --unsetpvm global <version>pvm global --unsetpvm listpvm list-remotepvm currentpvm which <tool>pvm ext <list|enable|disable> [extension] [--version <version>]pvm composer <install|update-self|which>pvm exec <version> <command...>pvm reshimpvm doctorpvm init <bash|zsh|fish>
Add the output of pvm init <shell> to your shell config and reload the shell.
Use pvm composer install instead of brew install composer. The pvm install follows the active PHP version.
Run:
pvm doctorThat helps identify broken php.ini or conf.d entries.
bash -n bin/pvm libexec/*.sh install.sh bootstrap.sh test/*.sh
shellcheck bin/pvm libexec/*.sh install.sh bootstrap.sh test/*.sh
test/smoke.sh