一、查看已安装的 PHP 版本

也可以查看 Homebrew Cellar 中实际存在的 PHP:

查看当前终端正在使用的 PHP:

二、切换命令行 CLI PHP 版本

假设要从当前版本切换到目标版本 php@X.Y:

例如切换到 PHP 7.4:

注意:brew link 切换成功后,当前已经打开的终端会话仍可能继续使用旧 PHP。原因通常是当前 Shell 的 PATH 中仍保留了旧版本的专用目录,或者 Shell 仍保留旧命令查找结果。最简单可靠的处理方式是关闭当前终端窗口/标签页并重新打开一个新的终端会话,然后再次执行 php -v。

这里的“终端”和“Shell”是两个概念:macOS 自带“终端(Terminal)”、iTerm2、Warp 等属于终端软件;zsh、bash、fish 等属于终端中实际运行的 Shell。无论使用哪种终端软件,新开一个会话通常都能重新加载 PATH 配置。

可使用以下命令确认当前 Shell、PHP 查找顺序以及 Homebrew 公共链接:

如果 which -a php 中旧版本路径排在 $(brew –prefix)/bin/php 前面,应检查 Shell 配置文件中是否写死了某个 PHP 版本。常见配置文件包括 ~/.zshrc、~/.zprofile、~/.bash_profile、~/.bashrc 和 ~/.config/fish/config.fish。

建议不要长期在 PATH 中固定 /opt/homebrew/opt/php@X.Y/bin,而统一让 php 走 Homebrew 公共链接 $(brew –prefix)/bin/php。这样以后只需要 brew unlink / brew link 即可切换版本。

若只想刷新当前会话:zsh 或 bash 可执行 hash -r;zsh 也可执行 rehash。若仍显示旧版本,直接新开终端窗口/标签页最简单。对于其他 Shell,可采用其对应的命令缓存刷新方式,或直接重新打开终端会话。

如果同时安装了无版本号的 php 包,必要时先执行:

三、Apache 使用 mod_php 时的切换方法

先判断 Apache 是否加载了 PHP 模块:

如果能看到 php7_module、php_module 等,说明 Apache 使用 mod_php。此时仅执行 brew link 不会自动切换 Apache,必须修改 Apache 配置中的 LoadModule。

先查找当前 PHP 模块配置:

典型配置:

切换到 PHP 7.4 时修改为:

修改前先确认目标模块存在:

然后检查并重启 Apache:

四、Apache 使用 PHP-FPM 时的切换方法

如果 Apache 配置中使用 proxy_fcgi、SetHandler 或 fcgi://127.0.0.1:9000,则通常是 PHP-FPM。查看相关配置:

查看 PHP-FPM 服务:

切换服务示例:

确认目标 PHP-FPM 的监听地址:

如果新旧版本都监听同一个地址(例如 127.0.0.1:9000),Apache 配置一般不需要修改;如果监听端口不同,则需要同步修改 Apache 的 FCGI 地址。

五、切换后的验证

CLI:确认 php -v 和 which php。

Apache:确认 apachectl -M | grep php。

PHP-FPM:确认 brew services list | grep php。

浏览器:建议放置临时 phpinfo() 页面确认 Web 端版本,验证后删除。

还可检查常用扩展是否存在:

1. 扩展缺失时的处理方法

切换 PHP 版本后,各版本使用的是各自独立的扩展目录和 php.ini。旧版本中存在的扩展,不代表新版本自动具有。先使用以下命令确认当前加载的配置文件、扩展目录和模块:

常见扩展可分为两类:

① PHP / Homebrew PHP 包自带扩展:如 mysqli、mysqlnd、PDO、pdo_mysql、gd、curl、mbstring、openssl、intl、xml、soap、zip、sockets、bcmath、ldap、pgsql、pdo_pgsql、sqlite3 等。目标 PHP 安装正常时,这类扩展通常随 PHP 一起编译安装。如果切换后缺失,优先检查是否加载了错误的 php.ini,或重新安装该 PHP 版本,而不是直接使用 PECL。

② PECL / 第三方扩展:如 redis、imagick、xdebug、mongodb、swoole 等。这些扩展需要针对当前 PHP 版本单独安装或重新编译,不能直接复用另一个 PHP 版本生成的 .so 文件。切换 CLI 到目标 PHP 后再安装,例如:

PECL 安装完成后,如果没有自动写入配置,可先查看当前扫描的配置目录:

然后在当前 PHP 对应的 conf.d 目录创建扩展配置,例如:

注意:不同 PHP 版本的扩展 API/ABI 通常不同。不要把 php@7.2 的扩展 .so 直接复制到 php@7.4、php@8.x 使用,否则可能出现 Unable to load dynamic library、Module compiled with module API=… 或直接崩溃。

2. 常用扩展参考基线

下面这组模块可作为常用业务 PHP 环境的核对参考。不同 PHP 大版本可能有少量模块增删或名称变化,不要求逐项完全一致,但数据库、字符集、网络、图像、XML、压缩和加密相关模块应重点确认。

常用项目可重点快速检查:

若需要判断某个扩展是否真正加载,可使用:

Web 环境还需用 phpinfo() 再确认一次,因为 Apache mod_php / PHP-FPM 与 CLI 可能读取不同的 php.ini。确认完成后应删除 phpinfo() 测试文件。

六、回滚方法

如果切换后项目不兼容,可按相反方向恢复。CLI 示例:

mod_php 环境还需要把 Apache 的 LoadModule 路径改回原 PHP 版本,再执行 apachectl configtest 并重启 Apache。PHP-FPM 环境则停止新版本服务并重新启动旧版本服务。

七、常见问题

1. brew link 已切换,但网页仍是旧 PHP

原因通常是 Apache 使用 mod_php 或独立 PHP-FPM。brew link 主要影响 CLI,不代表 Web 服务自动切换。应按第 3 或第 4 节检查。

2. 出现 Library not loaded / *.dylib

通常是旧 PHP 二进制依赖的 Homebrew 动态库已被升级或清理。优先尝试重新安装对应 PHP 版本,使其重新匹配当前依赖:

如果 PHP 来自第三方 tap,Homebrew 可能要求先显式信任该 formula 或 tap。不要随意把不同 ABI 版本的 dylib 强行软链接到旧文件名。

3. PHP-FPM 已启动,但 Apache 使用 mod_php

这种情况下 PHP-FPM 服务可能完全没有被 Apache 使用。应以 Apache 配置为准,不要仅凭 brew services list 判断 Web 使用的 PHP 版本。

八、推荐的标准切换流程

1. 查看已安装版本与当前版本。

2. 确认 Apache 使用 mod_php 还是 PHP-FPM。

3. 切换 CLI 的 Homebrew link。

4. 按实际模式切换 Apache 模块或 PHP-FPM 服务。

5. 执行 apachectl configtest。

6. 重启 Apache 或相关服务。

7. 分别用 CLI 和浏览器验证 PHP 版本及扩展。

8. 确认业务正常后,再清理不再使用的旧服务。

提示:生产或长期使用环境中,切换前建议备份 PHP 配置目录(php.ini、conf.d、php-fpm.d)和 Apache 配置,并记录原版本,以便快速回滚。