在Ubuntu服务器上同时运行多个PHP版本(比如PHP 7.4、PHP 8.0、PHP 8.1、PHP 8.2),最核心的运维技巧就是用ln命令创建软链接来动态切换默认PHP版本。具体做法是:先通过apt或ppa源安装多个PHP版本,然后用ln -sf命令把/usr/bin/php这个软链接指向你想用的那个版本的二进制文件,比如ln -sf /usr/bin/php8.1 /usr/bin/php,这样系统调用php时就会自动使用8.1版本。整个过程不需要卸载任何版本,切换只需一行命令,秒级生效。
这个方案之所以被大量运维人员采用,是因为它简单、可靠、不破坏系统。很多项目依赖不同PHP版本,比如老项目用PHP 7.4,新项目用PHP 8.2,一台服务器上不可能只装一个版本。而Ubuntu默认的包管理器安装多版本后,每个版本的二进制文件都独立存放在/usr/bin/下,名字分别是php7.4、php8.0、php8.1、php8.2。我们要做的就是让"php"这个通用命令指向其中一个。
为什么需要多版本PHP共存实际生产环境中,多版本PHP共存是刚需。原因主要有三个:第一,历史项目升级需要时间,老代码可能不兼容新版本语法,必须先在旧版本上跑着;第二,不同框架对PHP版本有明确要求,Laravel 9需要PHP 8.0以上,而一些老的CMS系统可能只支持PHP 7.x;第三,测试环境需要验证新版本兼容性,你得在同一台机器上同时跑新旧代码做对比。
如果不做版本管理,每次切换都要改配置文件、重启服务,非常低效。而用ln软链接的方式,切换版本就是一条命令的事,而且对所有依赖php命令行的程序(比如composer、php-fpm、crontab定时任务)都全局生效。
Ubuntu上安装多个PHP版本的完整步骤在开始创建软链接之前,你得先把多个PHP版本装好。Ubuntu 20.04和22.04的做法略有不同,下面给出最通用的方法。
首先添加PPA源(以Ubuntu 22.04为例):
sudo add-apt-repository ppa:ondrej/php sudo apt update
然后安装你需要的版本,比如同时装7.4、8.0、8.1、8.2:
sudo apt install php7.4 php7.4-cli php7.4-fpm php7.4-mysql sudo apt install php8.0 php8.0-cli php8.0-fpm php8.0-mysql sudo apt install php8.1 php8.1-cli php8.1-fpm php8.1-mysql sudo apt install php8.2 php8.2-cli php8.2-fpm php8.2-mysql
安装完成后,你可以用以下命令确认所有版本都已就绪:
ls /usr/bin/php*
你会看到类似这样的输出:/usr/bin/php7.4 /usr/bin/php8.0 /usr/bin/php8.1 /usr/bin/php8.2,每个都是独立的二进制文件。
用ln命令创建软链接切换PHP版本核心操作来了。假设你当前想把默认PHP切换到8.1版本,执行:
sudo ln -sf /usr/bin/php8.1 /usr/bin/php
这条命令的含义是:在/usr/bin/目录下创建一个名为php的软链接(符号链接),它指向/usr/bin/php8.1这个实际文件。-s表示创建符号链接(软链接),-f表示如果目标文件已存在则强制覆盖。
验证是否切换成功:
php -v
输出应该显示PHP 8.1.x。如果你想切回7.4:
sudo ln -sf /usr/bin/php7.4 /usr/bin/php
就是这么简单,一条命令搞定。注意,这里不需要删除任何文件,也不需要重启服务器,命令行立即生效。
同时管理php-fpm和php-cgi的软链接很多人只切换了php命令,却忘了php-fpm和php-cgi。如果你用的是Nginx+PHP-FPM架构,那php-fpm的版本也必须同步切换,否则Web请求会打到错误的版本上。
同样的方法,切换php-fpm:
sudo ln -sf /usr/bin/php-fpm8.1 /usr/bin/php-fpm
切换php-cgi(如果用的话):
sudo ln -sf /usr/bin/php-cgi8.1 /usr/bin/php-cgi
建议把这三个命令写成一个脚本,方便一键切换。后面我会给出完整的脚本示例。
管理composer的PHP版本指向composer是PHP的依赖管理工具,它也依赖php命令。当你切换了php软链接后,composer通常会自动跟随。但如果你的composer是全局安装的且指定了固定路径,可能需要额外处理。
检查composer当前使用的PHP版本:
composer -vv
如果显示的版本不对,可以重新安装composer或者修改它的shebang行。一般情况下,只要php软链接正确,composer就没问题。
编写一键切换PHP版本的Shell脚本为了提高运维效率,强烈建议写一个切换脚本。下面是一个实用的bash脚本示例:
#!/bin/bash
# 文件名: switch-php.sh
# 用法: sudo ./switch-php.sh 8.1
VERSION=$1
if [ -z "$VERSION" ]; then
echo "用法: sudo ./switch-php.sh [7.4|8.0|8.1|8.2]"
exit 1
fi
PHP_BIN="/usr/bin/php${VERSION}"
if [ ! -f "$PHP_BIN" ]; then
echo "错误: PHP ${VERSION} 未安装"
exit 1
fi
echo "正在切换到 PHP ${VERSION}..."
sudo ln -sf "$PHP_BIN" /usr/bin/php
sudo ln -sf "/usr/bin/php-fpm${VERSION}" /usr/bin/php-fpm
sudo ln -sf "/usr/bin/php-cgi${VERSION}" /usr/bin/php-cgi
echo "切换完成!当前版本:"
php -v
给脚本执行权限并使用:
chmod +x switch-php.sh sudo ./switch-php.sh 8.2
这个脚本会同时切换php、php-fpm、php-cgi三个软链接,并且做了版本存在性检查,避免指向不存在的文件导致系统异常。
不同Web服务器的配置注意事项如果你用Apache,Apache通常通过mod_php模块加载PHP,模块版本在安装时就绑定了。切换php命令行版本不会影响Apache的mod_php。你需要用a2dismod和a2enmod来切换Apache的PHP模块:
sudo a2dismod php7.4 sudo a2enmod php8.1 sudo systemctl restart apache2
如果你用Nginx+PHP-FPM,那只需要确保php-fpm软链接正确,然后重启对应版本的fpm服务:
sudo systemctl restart php8.1-fpm
这里有个关键点:Nginx的fastcgi_pass配置通常指向unix socket,比如/run/php/php8.1-fpm.sock。你切换php-fpm软链接后,还需要确认Nginx配置里的socket路径和实际启动的fpm服务版本一致。否则Nginx会连接到错误的socket文件。
查看当前所有已安装PHP版本和软链接状态运维过程中,你需要经常确认当前状态。以下几个命令很实用:
# 查看所有已安装的PHP版本 dpkg -l | grep php | grep -E "^ii" # 查看php软链接当前指向哪里 ls -la /usr/bin/php # 查看php-fpm软链接 ls -la /usr/bin/php-fpm # 查看当前运行的PHP-FPM进程 ps aux | grep php-fpm
ls -la的输出会清楚显示软链接的指向,比如:lrwxrwxrwx 1 root root 15 ... /usr/bin/php -> /usr/bin/php8.1,箭头后面就是实际指向的文件。
常见问题和避坑指南第一,不要用ln(不带-s)创建硬链接。PHP二进制文件不适合硬链接,而且硬链接不能跨文件系统,容易出问题。始终用ln -s创建软链接。
第二,切换版本后记得重启相关服务。php命令行切换后立即生效,但php-fpm服务需要重启才能加载新版本。如果你改了软链接没重启fpm,Web请求还是会用旧版本处理。
第三,注意扩展模块的兼容性。不同PHP版本的扩展目录不同,比如/usr/lib/php/20190902是7.4的,/usr/lib/php/20200930是8.0的。切换版本后,如果代码依赖某个扩展,要确认该扩展在目标版本下已安装。
第四,crontab定时任务中如果直接调用php,切换软链接后会自动跟随新版本。但如果你的crontab里写的是绝对路径比如/usr/bin/php7.4,那就不会受软链接影响。这点要特别注意。
第五,如果系统中有多个用户,普通用户可能没有权限修改/usr/bin/下的软链接。所以切换操作必须用sudo,或者提前把权限设置好。
进阶:用update-alternatives管理PHP版本其实Ubuntu自带了update-alternatives机制来管理多版本软件,它比手动ln更规范。你可以这样配置:
sudo update-alternatives --set php /usr/bin/php8.1 sudo update-alternatives --set php-fpm /usr/bin/php-fpm8.1
这种方式的好处是系统会自动维护一个alternatives数据库,切换时有记录可查。但说实话,对于PHP这种切换频率不高的场景,直接用ln -sf更直观、更快。两种方式都可以,看个人习惯。
总结:最佳实践建议在Ubuntu上用ln管理多版本PHP,核心就是"安装多版本→创建软链接→同步切换相关命令→重启服务"这四步。建议把常用版本都装好,写好切换脚本放在/usr/local/bin/下,需要切换时一键执行。同时做好版本记录,在/etc/motd或者运维文档里写清楚当前默认版本是什么,避免团队协作时出现混乱。
这套方案经过大量生产环境验证,稳定可靠。不管是个人开发机还是企业级服务器,都是管理多版本PHP最高效的方式之一。掌握了ln软链接的用法,你在Ubuntu上管理任何多版本软件(Python、Node.js、Java)都能举一反三。
