在 CentOS 中,虽然可以通过包管理器 YUM 或 DNF 快捷方便地安装 PHP,但是往往不是最新版本。因此,想要体验新版本 PHP 才具备的功能特性,通过源代码编译安装 PHP 是个不错的选择。
关于如何在不同的操作系统中以不同的方式安装 PHP,官方文档提供了丰富的资料可供参考。如果你的时间有限,急需在短时间内安装使用 PHP,可参考本文提供的最佳实践快速进行安装配置。
本文以 PHP 当前最新稳定版本 8.1.9 为例,详细介绍了如何在 CentOS 上通过编译源代码的方式安装配置 PHP,以及如何配置启动 PHP 的 FastCGI 进程管理器 FPM(FastCGI 进程管理器)。本文提供的安装步骤在 CentOS 7、CentOS 8 以及 CentOS Stream 8 中均实际测试过,对于在编译过程中可能遇到的问题也做了详细说明。
本文假设你登录的账户已取得管理员账户(root)权限,因为文中出现的命令大部分都需要用到 root 账户权限。如果你登录的是普通账户,可运行 sudo -s
命令切换到带有 root 权限的 Shell,否则需要在每条命令前添加 sudo
命令。
本文在用到包管理器时,会统一使用 yum
命令,但是要知道在 CenOS 8、CentOS Stream 8 及更新版本的 CentOS 中,yum
命令已被 dnf
命令替代(以符号链接的形式存在),运行 yum
命令实际上是运行 dnf
命令。
一、下载源码
从 PHP 官方下载页面获取最新稳定版源代码压缩包的下载链接:
PHP 官方下载下面:https://www.php.net/downloads
PHP 提供了三种类型的压缩包格式,Gzip(扩展名为 .gz)、Bzip2(扩展名为 .bz2)、XZ(扩展名为 .xz),可根据自己的需要选择,本文以 Gzip 格式为例。
切换到系统的源代码存放目录,将 PHP 的源代码压缩包下载下来:
cd /usr/local/src
curl -LO https://www.php.net/distributions/php-8.1.5.tar.gz
二、编译构建
相对于用包管理器安装 PHP,通过源代码编译 PHP 会有较多步骤,并且在编译过程中可能会遇到各种各样的意外情况,但是只要保持耐心,确定问题根源所在,就能有效地解决它。
编译 PHP 主要分两步,一是用 PHP 源代码附带的配置脚本定制功能,生成 Makefile 文件(待执行的一组任务规则,告诉 Make 工具如何编译和链接程序),二是用 Make 工具根据 Makefile 文件中的规则自动化构建 PHP。下文会详细解释这两个步骤。
1、编译环境
PHP 主要是用 C 语言编写的,因此编译 PHP 需要确保 CentOS 系统中安装了 C 编译器,本文以 GCC(GNU Compiler Collection)为例,当然你也可以使用你所喜欢的其它 C 编译器。
另外还需要安装自动化构建工具 Make,它的作用是根据配置好的 Makefile 文件自动将源代码构建成可执行程序和库。
运行以下命令为 CentOS 系统安装 GCC 及 make 程序:
yum install -y gcc make
2、定制功能
解压缩 PHP 源代码压缩包,并切换到源代码所在目录(注意,除非有说明,所有操作都会在该目录下进行,切勿离开):
tar -xvf php-8.1.5.tar.gz
cd php-8.1.5
在该目录下可以找到一个名为 configure 的 Shell 脚本文件,它是 PHP 源代码附带的“配置脚本(configure script)”。该脚本有两个作用:一是通过它提供的丰富的选项细颗粒度地定制 PHP 功能;二是自动匹配系统中的库和待编译 PHP 所依赖的库(如果依赖库有缺失,该脚本会中断执行并提示缺失库的名称,以便你来解决该依赖)。
运行以下命令查看含有所有可用配置选项的脚本帮助内容(按 q 键退出):
./configure --help | less
除此外,也可以参考 PHP 官方文档的“核心配置选项列表”。这些内容对每个配置选项都做了简要说明,想要查看选项所对应功能的详细介绍可以参考 PHP 官方文档的“功能参考”。
至于应该使用哪些选项,与你的实际需求有关。比如,你想要让 PHP 程序支持图形的处理,就需要安装 GD 图形库,否则就不需要安装。如果你的 PHP 应用采用了 Laravel、Symfony、Wordpress 等框架或 CMS,可以在其文档中找到对 PHP 运行环境的要求。
本文示例假设所编译的 PHP 能够支持 FPM,以便通过 FastCGI 协议与 Web 服务器协作处理对 PHP 程序的请求,并且能够让 PHP 程序支持 OpenSSL、zlib、 cURL、GD 图形库(以及 GD 对 webP、JPEG、FreeType 的支持)、 Multibyte String(多字节字符串)、Zip、访问 MySQL 的两种扩展 mysqli 和 PDO_MYSQL。这些功能与编译配置选项的对应关系如下所示:
配置选项 | 对应功能 |
–prefix | 指定安装位置 |
–enable-fpm | 支持 FPM 功能 |
–with-openssl | 支持 OpenSSL 功能 |
–with-zlib | 支持 zlib 功能 |
–with-zip | 支持 Zip 功能 |
–with-curl | 支持 cURL 功能 |
–enable-gd | 支持 GD 功能 |
–enable-mbstring | 支持多字节字符串的处理 |
–with-mysqli=mysqlnd | 支持通过 mysqli 访问 MySQL |
–with-pdo-mysql=mysqlnd | 支持通过 PDO 访问 MySQL |
要想让 PHP 具备上面所提到的那些附加功能,编译时可能需要依赖很多函数库(Library),如果缺少某个库,在运行配置脚本时就会中断并抛出提示,不过每次中断只会抛出一个提示。如果上面提到的功能符合你的需求,为避免多次尝试浪费时间,可以直接运行以下命令为操作系统安装这些库:
yum install -y libxml2-devel openssl-devel \
sqlite-devel curl-devel libpng-devel \
libwebp-devel libjpeg-devel freetype-devel
除此外,为了让 PHP 具备读写 Zip 的功能(比如PHP 依赖管理工具 Composer 就需要此功能 ),还需要安装一个名为 Libzip 的库。
对于 CentOS 8、CentOS Stream 8 可以直接通过运行以下命令安装:
yum install -y libzip-devel
而对于 CentOS 7,通过包安装管理器安装的版本为 0.10,低于 PHP 对 Libzip 的最低版本要求 0.11,所以需要额外手动编译。具体方法可参考下面这篇文章:
安装完成后,运行以下命令将 libzip 的 pkg-config 配置文件目录添加到系统环境变量 PKG_CONFIG_PATH
中:
export PKG_CONFIG_PATH=/usr/local/libzip/lib64/pkgconfig
这样 PHP 的配置脚本就能自动识别并使用你所安装的 libzip。
此外,如果想让正则表达式功能支持多字节字符串,需要用到名为 Oniguruma 的库,但是 CentOS 的默认软件库中不包含该库,需要手动激活或指定软件库。
在 CentOS 8 和 CentOS Stream 8 中可以运行以下命令安装:
yum install oniguruma-devel --enablerepo=powertools
在 CentOS 7 中可以运行以下命令安装:
yum install oniguruma-devel --enablerepo=epel
在安装完编译 PHP 所依赖的软件库后,运行配置脚本进行配置:
./configure --prefix=/usr/local/php \
--enable-fpm --with-openssl --with-zlib \
--with-curl --enable-gd --with-webp \
--with-jpeg --with-freetype --enable-mbstring \
--with-zip --with-mysqli --with-pdo-mysql
注意,命令中的 --prefix
选项是用来指定 PHP 安装位置的,你可以选择任意位置,但是作为最佳实践,将其指定为系统的本地程序目录(/usr/local/php
)是一个不错的选择。当然,你也可以忽略该选项,这会导致 PHP 的安装文件散落在各处(即 /usr/local
目录下的 etc
、lib
、bin
等目录)。
另外,这里使用了 --with-mysqli
和 --with-pdo-mysql
两个选项让 PHP 同时支持通过 mysqli 和 PDO 两种方式访问 MySQL,这是为了兼顾有的 PHP 程序只采用两者之一访问 MySQL。选项的值可以使用 mysqlnd 也可以不带值。关于为何以这样的形式设置对 MySQL 的支持,可参考 PHP 官方文档的“MySQL原生驱动程序”。
配置脚本运行完毕,如果你能看到如下所示的提示信息,就表示一切正常,成功生成了 Makefile 文件,可以正式开始进行编译了。
+--------------------------------------------------------------------+
| License: |
| This software is subject to the PHP License, available in this |
| distribution in the file LICENSE. By continuing this installation |
| process, you are bound by the terms of this license agreement. |
| If you do not agree with the terms of this license, you must abort |
| the installation process at this point. |
+--------------------------------------------------------------------+
Thank you for using PHP.
3、进行编译
接下来就可以运行以下命令对 PHP 源码进行编译了:
make
如果你的服务器配置较高,可以在编译时通过 make
命令的 -j
选项开启多个进程以加快编译速度,比如同时用 3 个进程进行编译:make -j3
。
编译时间的长短与服务器的配置、可用系统资源以及具体的编译配置有关。如果在编译期间长时间卡在某处,可能是因为系统资源不足导致的,你需要移除占用资源较多的 PHP 配置,或升级服务器配置。
编译成功后,你可以看到如下所示的提示信息:
Build complete.
Don't forget to run 'make test'.
4、进行测试(可选)
接下来是一个可选步骤。编译完成后,可以运行以下命令进行测试,以确保编译的 PHP 不存在严重问题:
make test
测试完成后,你可能会在提示信息中看到两个列表“FAILED TEST SUMMARY”和“WARNED TEST SUMMARY”,包含了很多测试失败或测试通过但给出警告的条目。不必担心这些提示,只要测试通过了就表示 PHP 是可用的。
测试完成后,你可以选择根据提示将测试报告发送给 PHP 质量保证团队以帮助他们更好地理解 PHP 的行为,以便让 PHP 变得更好。
5、添加扩展
除了通过将相关功能以编译的方式添加到 PHP 中,对于已安装完成的 PHP,也可以通过为其安装 PECL 扩展的方式添加额外的功能。你可以根据以下列表提供的内容添加你需要或感兴趣的扩展:
三、完成安装
编译完成后即可运行以下命令将 PHP 安装到之前指定的目录:
make install
至此 PHP 就安装完成了。如果你是第一次按照本文步骤安装 PHP,为方便之后运行 PHP 的相关命令,请运行以下命令将 PHP 的可执行文件目录添加到系统环境变量 PATH
中:
echo 'export PATH="/usr/local/php/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
现在运行以下命令,应该能够看到所安装 PHP 的版本号:
php --version
四、配置定制
对于启用了 FPM 的 PHP,含有两种配置文件,分别是用来配置 PHP 行为的 php.ini 和配置 FPM 的 php-fpm.conf(包含存放在 php-fpm.d 文件夹中的进程池配置文件)。默认情况下这三个配置文件都是不存在的,需要手动将其拷贝到 PHP 安装目录的对应位置。
1、配置 php.ini
运行以下命令将 php.ini 拷贝到 PHP 安装目录的 lib 文件夹中:
cp php.ini-production /usr/local/php/lib/php.ini
一般情况下 php.ini 不需要修改就能使用,如有需要,也可以参考配置文件中的注释说明或 PHP 官方文档中的“php.ini 指令”进行配置。
假设要使用的 PHP 应用需要通过“Unix domain socket”(如 /tmp/mysql.sock)而非“Network socket”(如 127.0.0.1:3306)访问本地的 MySQL 数据库,就需要在 php.ini 中为 PHP 指定 MySQL 的 Unix socket 文件路径。
用你喜欢的编辑器(这里用的是 vi 编辑器)打开 php.ini 进行修改:
vi /usr/local/php/lib/php.ini
假设你所安装 MySQL 的 Unix socket 路径是 /tmp/mysql.sock,可以按照下面这样修改 mysqli.default_socket 和 pdo_mysql.default_socket 两个指令的值:
mysqli.default_socket=/tmp/mysql.sock
pdo_mysql.default_socket=/tmp/mysql.sock
注意,该配置又称为运行时配置(Runtime Configuration),对于开启了 FPM 的 PHP,只有在启动 FPM 时才会被读取一次,因此每次修改 php.ini 文件后,都需要重新启动 FPM 才能使新的修改生效。
最后保存退出配置文件(vi 编辑器先按 ESC 再输入 :wq
并回车)。
2、配置 php-fpm.conf
FPM 启动后会出现两种进程,分别是主进程(master process)和进程池(pool of processes)。前者只有一个,作用是读取、估算配置,以及管理进程池。后者可以有多个(可通过配置文件中的进程管理指令进行设置),作用是处理请求。
主进程可以以管理员账户(root)的身份运行,以读取配置文件。而进程池则需要以普通账户身份运行,这是因为实际处理请求的是进程池,限制其权限可以避免因 PHP 应用的缺陷危及操作系统的安全。
一般情况下账户名与 Web 服务器程序(如 Nginx)的配置中设定的用账户名一致,如 www-data。你可以运行以下命令检查系统中是否存在该用户:
id www-data
如果出现类似“no such user”的提示就表示不存在此账户,可以运行以下命令创建一个名为 www-data 的无登录权限系统账户:
useradd www-data -s /sbin/nologin
现在离开 PHP 的源码目录,切换到 PHP 安装目录下的配置目录:
cd /usr/local/php/etc
运行以下两条命令生成可用的 FPM 配置文件及其进程池文件:
cp php-fpm.conf.default php-fpm.conf
cp php-fpm.d/www.conf.default php-fpm.d/www.conf
除非有需要,可以不修改 php-fpm.conf 文件,这里需要关注的是被该文件所包含的存放在 php-fpm.d 目录下的进程池配置文件 www.conf(如果有需要,可以创建多个进程池文件,从而让 FPM 运行多个有着不同配置的进程池,详见配置文件中的注释说明)。
用你喜欢的编辑器(这里用的是 vi 编辑器)打开 www.conf 进行修改:
vi php-fpm.d/www.conf
修改 user 和 group 这两个指令的值,通常是 Web 文件所有者的用户名和用户组(这里用的是上面创建的名为 www-data 的账户):
user = www-data
group = www-data
如果你打算让 Web 服务器(如 Nginx、Apache)通过网络端口(即 localhost:9000 或 127.0.0.1:9000)与 FPM 进行通信,到这里就算配置完成了。
如果想要让 Web 服务器通过 Unix socket 与 FPM 进行通信,需要为指令 listen
设定 Unix socket 文件路径,以便 FPM 开启时在该位置创建 Unix socket 文件(路径和文件名随意):
;listen = 127.0.0.1:9000
listen = /tmp/php-fpm.sock
然后还要设置 Unix socket 文件的权限,以便让 Web 服务器能够读取:
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
配置修改完成后,可以运行以下命令进行测试,如果能看到 successful 字样就表示配置文件不会影响 FPM 的运行:
/usr/local/php/sbin/php-fpm -t
五、启动 FPM
接下来就可以启动 PHP 的 FPM,以配合 Web 服务器处理对 PHP 程序的请求了。
虽然可以直接通过 php-fpm
命令启动 FPM,但是为了让其更稳定的运行(避免因服务器宕机或维护性重启导致 FPM 停止运行),有必要将其作为服务托管给操作系统,这样不论何种原因导致的系统重启,FPM 都能随机启动。
在 CenOS 中,可以通过系统和服务管理器 systemd 来管理操作系统中的各种服务。要将 PHP 托管给 systemd,需要为其创建一个配置文件,以便让其管理。
使用你喜欢的编辑器创建一个名为 php-fpm.service 的配置文件到如下所示路径(这里使用的是 vi 编辑器):
vi /etc/systemd/system/php-fpm.service
然后将如下所示的内容复制粘贴到该文件中并保存(vi 编辑器先按 ESC 再输入 :wq
):
[Unit]
Description=PHP FastCGI process manager
After=local-fs.target network.target nginx.service
[Service]
Type=forking
ExecStart=/usr/local/php/sbin/php-fpm
ExecReload=/bin/kill -USR2 $MAINPID
[Install]
WantedBy=multi-user.target
接着运行以下命令,让 systemd 读取新创建的配置文件:
systemctl daemon-reload
现在即可通过运行以下命令启动 FPM 服务:
systemctl start php-fpm
如果修改了配置文件可运行以下命令重启 FPM:
systemctl restart php-fpm
运行以下命令查看 FPM 服务的状态:
systemctl status php-fpm
如果服务的状态为 Active: active (running) 且没有显示任何错误或警告信息的话,就表示一切正常。
最后,将 FPM 作为服务添加到随机启动:
systemctl enable php-fpm
至此,就完成了在 CentOS 上安装配置 PHP 的全部流程。
六、升级版本
如果想要升级到 PHP 今后发布的新版本,只需要按照以上步骤重新操作一到三步即可。因为重新安装 PHP 时不会覆盖已有配置文件,也不会影响启动 FPM 服务相关功能,所以无需修改它们。
七、总结
完成以上流程后,应该能够得到如下所示的这些可用文件或信息。有些可用于配置 PHP 或 FPM 的文件,有些可能会被其它软件用到(如 Web 服务器软件 Nginx、Apache 等)。
PHP 配置文件路径:
/usr/local/php/lib/php.ini
FPM 配置文件路径:
/usr/local/php/etc/php-fpm.conf
/usr/local/php/etc/php-fpm.d/www.conf
FPM 生成的 Unix socket 文件路径:
/tmp/php-fpm.sock
FPM 绑定的 IP 地址和端口(如果启用了的话):
127.0.0.1:9000
FPM 的系统服务配置文件路径:
/etc/systemd/system/php-fpm.service
如果你在操作的过程中遇到了任何问题,可留言提出。