本文配置的是 centos 系统上,用 nginx 服务器同时支持 php7 与 php5。
缘起
8 月份的时候我写了一篇吐槽的博客 记一次项目的开发到部署, 这里面我说过自己配置过 nginx 对于双版本 php 的支持,所以说这篇文章我本来早就想写了,一直没时间……现在补上。
必要的安装
自己配的时候,原本系统已经装好了 php5.6 和 nginx,只不过服务都没跑起来,所以我只要装 php7 就行了。那么 php7 我是怎么装的呢,恩……采用最原始的下载 C 代码编译安装…………具体的安装过程下一篇博客记录吧。
这里吐槽一下 ubuntu16.04,我用 apt 包管理器装 php 的时候没注意,等我装完一看装的 php7……瞬间惊呆了。
nginx 与 php 之间的通信
在写怎么配置之前,我觉得有必要说清楚 ngnix 与 php 之间是怎么通信的。让我们一步一步来哈~
首先一个请求过来,例如 http://php7.host/index.php,然后 nginx 就根据域名找对应的 server 块,这里域名是 php7.host,所以 nginx 会找 server 中设置 server_name php7.host,然后解析里面 location 规则。
但凡是支持运行 php 的,必定会有对于请求结尾是 .php 的处理,这种处理的 location,基本都是以下的配置规则,或者是它的精细化。
1 | server { |
以上匹配规则就说明最后带 .php 的执行以下操作。
实际上,nginx 本身是不支持调用解析 php,所以必须通过一个通用的接口来调起守护进程进行 php 解析,这个就是 FastCGI。所谓 FastCGI,就是在 Http server(例如 nginx)和动态脚本语言(例如 php)中间通信的的接口。它负责启用一个或多个叫做 FastCGI 进程管理器的守护进程来解析 php,而 php-fpm 就是 FastCGI 进程管理器中处理 php 的一种,也是处理 php 最常用的一种,至少目前的 php 都默认把 php-fpm 都一起编译进了内核。
所以 nginx 在处理动态脚本的时候其实就是一个反向代理服务器,自身处理一些静态请求(例如请求文件),然后将所有需要脚本语言解析的动态请求(例如 php,python)全部交给 FastCGI 接口。
FastCGI 进程管理器与 nginx 通信则是通过 socket,文件 socket 和 ip socket 都可以,所以一个 FastCGI 进程管理器就会监听一个 socket 文件或者一个端口,且不能重复占用。
根据以上的知识,其实做到支持两个版本的 php 就是将两个请求的 url 单独分开处理,交给两个不同的 php-fpm 进程进行解析,而且分别使用不同的 socket 通信。
配置 php5
这里的配置和普通意义上配置 php 环境类似。
1、nginx 配置
首先说一下,为了以示区别,php5 不用默认的 localhost 访问,采用域名 php5.host,然后本地设置 host 指向 127.0.0.1,然后单独拉个 server 块,FastCGI 进程管理器指定监听 socket 文件。
以下为具体的 server 块配置,具体在 nginx.conf 配置
1 | upstream phpfile{ |
然后重启 nginx
1 | /usr/local/nginx/sbin/nginx -t; |
2、php-fpm 配置
nginx 配置之后,然后配置 php-fpm.conf
主要就是让 php-fpm 从 /run/php/phpfpm.socket 中获取数据。
1 | [global] |
然后启动 php-fpm 就可以了
1 | /usr/local/php/sbin/php-fpm --fpm-config /usr/local/php/etc/php-fpm.conf |
贴个图展示下成果

配置 php7
由于 php7 是后来我编译安装的,原本 php5.6 装在 /usr/local/php/ 下,所以 php7 为了防止名字冲突(其实已经很多地方已经冲突了,造成我在部署 php7 的时候踩了一个坑),php7 就装在 /usr/local/php7/ 下
1、nginx 配置
和 php5 一样,为了以示区别,php7 用域名 php7.host 访问,本地设置 host 指向 127.0.0.1,然后也是单独拉出来一个 server 块。这里指定 FastCHI 进程管理器监听一个端口,就 8022 吧。
以下为具体的 server 块配置,具体在 nginx.conf 配置
1 | upstream phpport{ |
然后重启 nginx
1 | /usr/local/nginx/sbin/nginx -t; |
2、php-fpm 配置
nginx 配置之后,然后配置 php-fpm.conf
主要就是让 php-fpm 从 8022 端口中获取数据。
1 | [global] |
然后启动 php-fpm 就可以了
1 | /usr/local/php7/sbin/php-fpm --fpm-config /usr/local/php7/etc/php-fpm.conf |
贴个图展示下成果

一些吐槽
之前一切都很顺利,在配置 php7 的时候就开始踩坑了。
在装完 php 的时候,php 会默认装一个全局的命令 php-fpm,然后这个 php-fpm 命令不用想也知道是事先安装的 php5.6 的,php7 的 php-fpm 命令则需要通过最原始的绝对路径来调用。不指明路径的话,那么还是 php5.6 的 php-fpm 换了个 php7 配置文件重新跑,而 php7 的服务压根没跑起来。
所以我在配置的时候就发生了诡异的现象:域名 php5.host 访问的好好的,启动 php7 的 php-fpm 之后,用 php7.host 访问显示的 php 版本还是 php5.6,而 php5.host 访问则 404 了。这报错曾让我一度怀疑起了人生……
其实用查看现在跑了哪些进程也可以看出来是否配置正确,因为如果两版本 php 服务都跑起来的话,是会看到两个一毛一样的 php-fpm,当然再加一个参数就可以看出来这两个 php-fpm 分别属于哪种 php 了
1 | ps anx | grep php |
所以说啊,没事别装两个版本的 php……一来一些全局命令如果不注意就会用错版本,二来一些扩展的维护也比较麻烦。
The End~