如何在 CentOS 上编译安装及配置最新版 PHP

在 CentOS 中,虽然可以通过包管理器 YUM 或 DNF 快捷方便地安装 PHP,但是往往不是最新版本。因此,想要体验新版本 PHP 才具备的功能特性,通过源代码编译安装 PHP 是个不错的选择。

关于如何在不同的操作系统中以不同的方式安装 PHP,官方文档提供了丰富的资料可供参考。如果你的时间有限,急需在短时间内安装使用 PHP,可参考本文提供的最佳实践快速进行安装配置。

本文以 PHP 当前最新稳定版本 8.1.9 为例,详细介绍了如何在 CentOS 上通过编译源代码的方式安装配置 PHP,以及如何配置启动 PHP 的 FastCGI 进程管理器 FPMFastCGI 进程管理器)。本文提供的安装步骤在 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 编译器,本文以 GCCGNU 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 程序支持 OpenSSLzlibcURLGD 图形库(以及 GD 对 webP、JPEG、FreeType 的支持)、 Multibyte String(多字节字符串)、Zip、访问 MySQL 的两种扩展 mysqliPDO_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 的配置选项与对应的功能

要想让 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 目录下的 etclibbin 等目录)。

另外,这里使用了 --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_socketpdo_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

修改 usergroup 这两个指令的值,通常是 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

如果你在操作的过程中遇到了任何问题,可留言提出。

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注