在Linux服务器上维护不同项目时,经常会碰到老旧系统只支持PHP 7.x,而新业务需要PHP 8.x特性的情况。如果直接通过包管理器反复安装卸载,不仅容易弄脏系统依赖,还会中断线上服务。更稳妥的思路是在同一台机器上保留多个PHP版本,按需要随时切换命令行或者Web后端所使用的解释器。

从源码编译安装多个独立PHP版本
使用发行版自带的apt或yum安装PHP,通常一个源只提供单一主线版本,且路径固定,难以并存。最灵活的方式是从php.net下载各版本源码,在configure阶段通过--prefix参数指定不同安装目录。例如PHP 7.4装到/usr/local/php74,PHP 8.2装到/usr/local/php82,这样二进制文件与扩展互不影响。
在编译前需要准备好公共依赖。Ubuntu下可运行apt-get install -y libxml2-dev libsqlite3-dev libcurl4-openssl-dev pkg-config,CentOS则用yum install -y libxml2-devel sqlite-devel libcurl-devel。缺少这些包会导致configure报错退出。两个版本编译流程完全一致,只是前缀与版本号不同。
下面以PHP 7.4为例展示核心编译指令,注意--enable-fpm用于后续Web服务,--with-config-file-path也要指向对应目录以免配置混淆:
cd /usr/src wget https://www.php.net/distributions/php-7.4.33.tar.gz tar -xzf php-7.4.33.tar.gz cd php-7.4.33 ./configure --prefix=/usr/local/php74 --with-config-file-path=/usr/local/php74/etc --enable-fpm --with-mysqli --with-pdo-mysql --with-curl --with-openssl --enable-mbstring make -j$(nproc) make install
PHP 8.2的编译只需把下载链接与前缀换成/usr/local/php82即可。编译完成后,两个目录下的bin/php分别是各自版本的解释器。此时直接执行/usr/local/php74/bin/php -v便能确认版本,不会发生冲突。这种隔离安装是后续切换的基础。
使用update-alternatives管理CLI版本
每次敲绝对路径很麻烦,Linux的update-alternatives工具可以把多个程序注册到同一个命令名。把php命令指向一个由系统管理的软链,切换时只需一条命令改优先级。Debian系与部分CentOS仓库自带该工具,比手动改PATH更规范。
注册时要给每个版本一个不同的优先级数值,数字越大默认越优先。执行下列指令将两版本加入 alternatives 组:
update-alternatives --install /usr/bin/php php /usr/local/php74/bin/php 74 update-alternatives --install /usr/bin/php php /usr/local/php82/bin/php 82
切换CLI版本时使用update-alternatives --set php /usr/local/php74/bin/php即可立即生效,所有调用php的脚本都会走旧版。也可用--config php弹出交互菜单手动选。这种方案只影响命令行,不改Web服务器,适合跑 composer 或定时任务时临时换版本。
若系统没有update-alternatives,也可在~/.bashrc里写函数。比如定义usephp74() { export PATH=/usr/local/php74/bin:$PATH; },登录后执行函数就能让当前shell优先用指定版本。虽然不如系统级方案统一,但对单人开发机足够直观。
配置php-fpm多实例并切换Web后端
Web项目多数通过FastCGI对接PHP,每个版本应启动独立的php-fpm进程,监听不同端口或sock文件。假设PHP 7.4的fpm监听127.0.0.1:9074,PHP 8.2监听127.0.0.1:9082。修改各自etc/php-fpm.d/www.conf中的listen行后,分别用绝对路径启动:
/usr/local/php74/sbin/php-fpm -c /usr/local/php74/etc/php.ini /usr/local/php82/sbin/php-fpm -c /usr/local/php82/etc/php.ini
Nginx等Web服务在站点配置里通过fastcgi_pass指定后端地址,就能决定该站点用哪个PHP。要把某站点从8.2降到7.4,只需改这一行并reloadnginx,无需动系统全局。多个站点可同时跑不同版本,互不干扰。
为避免进程混乱,建议写两个systemd单元文件,分别叫php74-fpm.service与php82-fpm.service,里面ExecStart填对应目录的二进制。这样开机自启与日志管理都清晰。当某个版本不再需要,停掉对应服务并删前缀目录即可,不会留下包管理器难以清理的碎片。
切换Web版本的本质是换FastCGI上游,而非替换文件。理解这一点后,甚至可以给同一站点做灰度:旧版跑大部分路径,新版仅通过路由前缀转发,验证无误再全量切。多版本并存的价值不仅是兼容,更为平滑升级提供了实验场。