在 macOS 开发环境里,PHP 的麻烦往往不只是"装一个能跑的版本",而是"怎么同时维护多个版本,还能随时切换"。有的项目还停在 PHP 8.2,有的已经切到 8.4,如果只靠手动改 PATH,环境很容易混乱。phpbrew 的价值,就是把 PHP 多版本安装和切换这件事收拢到一套可重复的流程里。
需要先明确一点:phpbrew 除了负责版本切换,还会从源码编译并安装指定 PHP 版本。这意味着它不仅要初始化 shell,还要提前准备好编译依赖。
给 AI Agent 的提示词:
使用 Homebrew 安装
phpbrew,执行phpbrew init初始化环境,在 shell 中加载~/.phpbrew/bashrc,配置好编译依赖和相关环境变量后,通过phpbrew install编译安装多个 PHP 版本,再使用phpbrew use、phpbrew switch和phpbrew off在不同版本之间切换。
一、安装 phpbrew
在 macOS 上,可以直接通过 Homebrew 安装:
bash
brew install phpbrew
安装完成后先确认版本:
bash
phpbrew --version
如果还没有配置 Homebrew,本机常见的 Homebrew 前缀是:
bash
/opt/homebrew
这通常也是 Apple Silicon Mac 上大多数依赖库的安装位置。
二、初始化 phpbrew
安装完 phpbrew 后,先执行初始化:
bash
phpbrew init
这一步会创建:
bash
~/.phpbrew/
~/.phpbrew/bashrc
随后需要把 phpbrew 的初始化脚本加入 shell 配置。以 zsh 为例,可以把下面这段加入 ~/.zshrc:
bash
# PHPBrew / PHP
export PATH="/opt/homebrew/opt/php@8.4/bin:/opt/homebrew/opt/php@8.4/sbin:$PATH"
export PHPBREW_SYSTEM_PHP="$HOME/.local/bin/phpbrew-php"
[[ -r "$HOME/.phpbrew/bashrc" ]] && source "$HOME/.phpbrew/bashrc"
然后重新加载 shell:
bash
source ~/.zshrc
建议立刻验证加载结果:
bash
which php
php -v
type phpbrew
phpbrew --version
如果输出里看到:
php指向/opt/homebrew/opt/php@8.4/bin/phpphpbrew is a shell function from ~/.phpbrew/bashrc
说明初始化已经生效。
三、处理 PHP 8.4 下的 deprecation 噪声
这台机器上的一个实际问题是:Homebrew 安装的 phpbrew 在 PHP 8.4 环境下运行时,会打印一批 Deprecated: 提示。它不一定会让功能失效,但会让输出非常脏,尤其是在安装和切换版本时更明显。
比较稳妥的处理方式,是为 phpbrew 单独准备一个包装器,调用系统 PHP 时屏蔽这些 deprecation 噪声。可以创建:
bash
mkdir -p ~/.local/bin
cat > ~/.local/bin/phpbrew-php <<'EOF'
# !/bin/sh
exec /opt/homebrew/opt/php@8.4/bin/php -d error_reporting='E_ALL & ~E_DEPRECATED & ~E_STRICT' "$@"
EOF
chmod +x ~/.local/bin/phpbrew-php
然后在 ~/.zshrc 里设置:
bash
export PHPBREW_SYSTEM_PHP="$HOME/.local/bin/phpbrew-php"
这样做的目的不是替换你日常使用的 php,而是让 phpbrew 自己在执行时更安静、更稳定。
四、安装编译依赖
由于 phpbrew 安装 PHP 的方式是源码编译,所以在真正执行 phpbrew install 之前,需要先准备编译依赖。
建议先安装这些常用依赖:
bash
brew install bison libiconv libxml2 re2c bzip2 zip
这台机器上原本已经具备的常见依赖还包括:
openssl@3curlsqlitereadlinelibsodiumonigurumapkgconf
如果这些基础库缺失,后续编译 PHP 时经常会在 configure 或 make 阶段报错。
五、为 phpbrew 编译准备环境变量
在 Apple Silicon 的 Homebrew 环境里,很多依赖不在系统默认搜索路径里,所以在安装 PHP 之前,最好先把相关头文件和 pkg-config 路径明确暴露出来:
bash
export PATH="/opt/homebrew/opt/bison/bin:/opt/homebrew/opt/libxml2/bin:/opt/homebrew/opt/bzip2/bin:/opt/homebrew/opt/zip/bin:$PATH"
export PKG_CONFIG_PATH="/opt/homebrew/opt/libxml2/lib/pkgconfig:/opt/homebrew/opt/openssl@3/lib/pkgconfig:/opt/homebrew/opt/sqlite/lib/pkgconfig:/opt/homebrew/opt/readline/lib/pkgconfig:/opt/homebrew/opt/libsodium/lib/pkgconfig:/opt/homebrew/opt/oniguruma/lib/pkgconfig:/opt/homebrew/opt/curl/lib/pkgconfig:/opt/homebrew/opt/libiconv/lib/pkgconfig:$PKG_CONFIG_PATH"
export CPPFLAGS="-I/opt/homebrew/opt/libiconv/include -I/opt/homebrew/opt/libxml2/include -I/opt/homebrew/opt/bzip2/include $CPPFLAGS"
export LDFLAGS="-L/opt/homebrew/opt/libiconv/lib -L/opt/homebrew/opt/libxml2/lib -L/opt/homebrew/opt/bzip2/lib $LDFLAGS"
如果不先做这一步,phpbrew 在编译某些版本时,往往会出现"找不到头文件"或"扩展功能被静默禁用"的情况。
六、使用 phpbrew 安装 PHP 版本
真正开始安装前,可以先看 phpbrew 当前认识哪些 PHP 版本:
bash
phpbrew list-known | head -n 12
比如安装 PHP 8.4.20:
bash
phpbrew install --stdout --jobs=4 8.4.20 +default
安装 PHP 8.2.30:
bash
phpbrew install --stdout --jobs=4 8.2.30 +default
如果还需要 FPM,可以显式加上:
bash
phpbrew install --stdout --jobs=4 8.2.30 +default +fpm
这里有一个本机实测过的细节:--jobs=4 可以正常工作,但不建议写成 -j4。在这台机器上,-j4 被 phpbrew 透传后,会触发 make 报错:
text
the '-j' option requires a positive integral argument
所以更稳妥的写法是始终使用 --jobs=4 这种长参数形式。
七、查看和切换已安装的 PHP 版本
安装完成后,可以先看当前已注册的版本:
bash
phpbrew list
这台机器当前看到的是:
text
* (system)
php-8.4.20
php-8.2.30
这里的 system 表示当前 shell 还在使用 Homebrew 提供的系统 PHP,而 php-8.4.20、php-8.2.30 则是已经由 phpbrew 编译并安装好的版本。
只在当前终端会话里临时切换:
bash
phpbrew use php-8.4.20
或者:
bash
phpbrew use php-8.2.30
切换完成后验证:
bash
which php
php -v
本机已验证:
phpbrew use php-8.4.20后,php指向~/.phpbrew/php/php-8.4.20/bin/phpphpbrew use php-8.2.30后,php指向~/.phpbrew/php/php-8.2.30/bin/php
如果想回到系统 PHP:
bash
phpbrew off
八、持久切换默认 PHP
如果希望后续新开的 shell 也默认使用某个 phpbrew 安装的版本,可以执行:
bash
phpbrew switch php-8.4.20
或者:
bash
phpbrew switch php-8.2.30
取消持久切换、恢复到系统 PHP:
bash
phpbrew switch-off
这和 phpbrew use 的区别在于:
phpbrew use只影响当前 shellphpbrew switch会影响后续新开的 shell
九、验证当前生效的 PHP 版本
切换完成后,建议固定用下面几条命令验证:
bash
which php
php -v
type phpbrew
phpbrew list
如果要直接确认某个 phpbrew 安装版本是否真的能执行,也可以单独运行:
bash
~/.phpbrew/php/php-8.4.20/bin/php -v
~/.phpbrew/php/php-8.2.30/bin/php -v
这类检查比只看 phpbrew list 更可靠,因为它能直接确认目标二进制是否真的可运行。
十、常用命令总结
日常最常用的命令基本包括:
bash
phpbrew --version
phpbrew init
phpbrew list-known
phpbrew install --stdout --jobs=4 8.4.20 +default
phpbrew list
phpbrew use php-8.4.20
phpbrew switch php-8.4.20
phpbrew off
phpbrew switch-off
这些命令已经覆盖了安装、初始化、编译、切换和恢复系统版本的主要场景。
十一、推荐的实践方式
比较稳妥的用法通常是:
- 保留 Homebrew 自带 PHP 作为
system基线环境 - 用
phpbrew安装项目实际需要的版本,比如php-8.2.x和php-8.4.x - 临时测试时使用
phpbrew use - 长期主力版本使用
phpbrew switch - 编译前先固定好依赖路径和
PKG_CONFIG_PATH
这样做的好处是,系统 PHP 和项目 PHP 的边界清楚,多个版本可以并行存在,切换成本也足够低。
十二、常见问题排查
如果执行 phpbrew 时满屏都是 Deprecated: 提示,通常不是 PHP 版本坏了,而是 phpbrew 本身在 PHP 8.4 下的兼容性噪声。这时优先检查 PHPBREW_SYSTEM_PHP 是否已经指向你设置的包装器。
如果 phpbrew install 在 configure 阶段失败,首先检查 Homebrew 依赖是否装齐,其次检查下面这些变量是否已经设置:
bash
echo $PATH
echo $PKG_CONFIG_PATH
echo $CPPFLAGS
echo $LDFLAGS
如果编译参数里用了 -j4 之后出现并行构建报错,优先改回:
bash
--jobs=4
如果切换后 which php 仍然指向系统 PHP,通常说明当前 shell 没有正确加载:
bash
~/.phpbrew/bashrc
这时应重新检查 ~/.zshrc 中的 source 配置是否生效。
结语
phpbrew 的价值不只是"再装一个 PHP",而是把 PHP 的多版本编译、安装和切换变成一套可预期的流程。对于需要同时维护新旧项目的开发环境,这比手动切 PATH 稳定得多。比较实用的思路通常是:保留系统 PHP 作为底座,用 phpbrew 编译项目需要的版本,再通过 use 或 switch 做场景化切换。
参考资料
- phpbrew 官方仓库: github.com/phpbrew/php...
- phpbrew 文档站点: phpbrew.github.io/phpbrew/
- Homebrew: brew.sh/
- Homebrew Formula: formulae.brew.sh/formula/php...