CentOS上PHP源码安装和配置
此文是在CentOS 7上已经部署了Nginx的基础上进行的
关于CentOS7上安装Nginx,可参考我之前的文章:
CentOS上Nginx安装记录
我们现在在这个基础上安装PHP 7。
PHP里面概念挺多的,没想到安装这个PHP需要花那么多时间去查资料。虽然还有很多没搞懂,但查询过程中也让我对Linux更加的理解。
做下记录,希望后面的人走更少的弯路。
PS.网上很多教程,但基本上都是讲了安装和配置的一部分,我写的这篇文章对过程的记录相对比较完整。
本文操作环境:centos7系统、Nginx nginx/1.22.0
目标:安装和配置 PHP7.3版
一、关于安装PHP的一些问题
1.安装PHP需要什么硬件硬件要求?
如果内存小于1G,需要开启swap内存交换空间
2.安装PHP需要软件包升级吗?
我见到有一些安装教程,安装前建议先升级更新一下CentOS7的安装包。
yum -y update :升级所有软件包的同时也升级软件和系统内核;
yum -y upgrade :只是升级所有软件包,但是不升级软件和系统内核。 #有文章推荐这一命令
完成后,重启httpd: systemctl restart httpd.service :重启httpd。
感觉这样做系统就会花很长的时间去更新linux系统了,可以考虑upgrade,但因为系统背后会装很多我不懂的东西,我无法理解,所以我自己的操作是略过这一步的。如果遇到实在有问题实在一直没办法解决时,也只能通过这些方法尝试看能不能解决。
3.需要安装libzip吗?
见过很几篇不同的PHP安装的文章和教程,各式各样的,其中有说需要安装libzip,查了一下,libzip库是用于读取、创建和修改ZIP格式文档的开源C/C++库,它是PHP提供的一个可选扩展模块,用于支持PHP的Zip操作函数。是否要安装libzip库取决于你的应用程序是否需要使用Zip操作函数。如果需要,就需要安装。如果不需要,可以不安装。
我在实际安装过程中,没有安装libzip,开始时提示报错:
checking for libzip... not found
configure: error: Please reinstall the libzip distribution
好像还挺重要的,感觉是一个缺省的选项来的。
官网是这样说的:
“
从 PHP 7.4.0 开始,必须在编译 PHP 时用 –with-zip 配置选项来提供 zip 支持。之前的 PHP 版本,需要使用 –enable-zip 选项。从 PHP 7.4.0 起,移除捆绑的 libzip。
从 PHP 7.3.0 开始, 不鼓励使用捆绑的 libzip 进行构建,但通过在配置中添加 –without-libzip 参数仍然可以实现。
新增 –with-libzip=DIR 配置选项以使用系统 libzip 安装。需要 libzip 版本 0.11,推荐使用 0.11.2 或更高版本。
”
因为不知道什么用途,我这篇文章先用官网教的方法,用–without-libzip参数处理,到时需要用到,再进行安装。
也有些教程还说要安装libiconv,libmcrypt-devel,mhash,mcrypt
我尽可能通用和常规的最少配置来安装和配置,因此这里暂时不安装libzip和上面的其它几个库,等到明确需要时,才考虑去安装。
4.安装PHP,需要另外再安装sqlite扩展吗?
答:sqlite是小型网站和系统常用的数据库,PHP网站经常使用的两种数据库,一种是mysql,另一种就是sqlite。PHP7版本默认已经包含了sqlite3扩展,无需手动安装。可以通过phpinfo()函数或者php -m命令查看是否已经加载了sqlite3扩展。如果没有加载,则需要在php.ini文件中添加extension=sqlite3.so或者extension=php_sqlite3.dll来启用该扩展。
5.如何移除已经安装的旧版php?
据说yum remove命令可以移软件,例如
yum -y remove php*
但是php不同版本是可以在同一个系统中的,所以移除旧版本不是必须操作,不影响安装新版本的php。
6.CentOS安装完PHP7之后,需不需要手动在PATH中设置环境变量?
答:通常情况下,安装完PHP7后不需要手动设置环境变量。因为在安装PHP7时,会将PHP二进制文件路径添加到系统的环境变量中。但是如果您在使用PHP时遇到了找不到命令的问题,可以手动将PHP二进制文件路径添加到PATH环境变量中。这篇文章的安装配置过程中,发现自动配置的环境变量有问题,需要手动调整。具体见下面配置过程。
7.PHP-FPM是什么来的?
PHP-FPM(FastCGI Process Manager)是一个PHP FastCGI的进程管理器,是PHP5.3.3及以上版本中的一个内置模块。它可以实现对PHP进程的管理,支持多种运行模式,包括静态、动态、线程池等模式,可以大大提高PHP的性能和稳定性。这个可以说是重要的必选项。
在部署PHP网站过程中,PHP-FPM主要有以下作用:
-
处理HTTP请求:当Web服务器(如Nginx或Apache)接收到PHP脚本的HTTP请求时,它会将请求发送给PHP-FPM进程池。
-
解释和执行PHP代码: PHP-FPM会解释处理收到的php文件并执行其中的代码,然后将结果返回给Web服务器,使其能够将结果发送回客户端浏览器。
-
进程管理: PHP-FPM还负责管理和控制多个PHP进程,并在需要时动态地创建或销毁这些进程。可以基于请求量及资源使用情况自动调整进程数,以达到优化响应速度及提高系统可用性的目的。
-
特定功能的支持: PHP-FPM还提供了一些特定的功能,例如请求限制、内存缓存等,可以以插件形式添加其它扩展,保证系统的稳定性并降低攻击风险。
简单说就是,部署PHP网站中需要PHP-FPM来实现。
二、安装依赖
有人总结要安装编译php需要下面这些依赖包,
yum install gcc autoconf gcc-c++yum install libxml2 libxml2-devel openssl openssl-devel bzip2 bzip2-devel libcurl libcurl-devel libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel gmp gmp-devel readline readline-devel libxslt libxslt-develyum install systemd-develyum install openjpeg-devel
也有的列出下面这些
yum install gcc gcc-c++ make zlib zlib-devel pcre pcre-devel libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel libxml2 libxml2-devel glibc glibc-devel glib2 glib2-devel bzip2 bzip2-devel ncurses ncurses-devel curl curl-devel e2fsprogs e2fsprogs-devel krb5 krb5-devel openssl openssl-devel openldap openldap-devel nss_ldap openldap-clients openldap-servers
需要依赖包很多,为了简单,可以都执行一遍,这样会减少报错的机会。也可以编译时,在报错后再来决定要安装哪些依赖。
我自己执行了下面的依赖安装
yum -y install make zlib zlib-devel gcc-c++ libtool openssl openssl-devel //此命令已经在安装Nginx时已经执行过。
yum -y install libxml2 libxml2-devel sqlite-devel libwebp libwebp-devel libjpeg-devel libpng-devel
libwebp libwebp-devel libjpeg-devel libpng-devel这几个依赖是我后来在安装过程中出现报错加上的。
三、下载、解压、编译安装PHP源码
1.下载源码
cd /usr/local/src
mkdir php-install-package
cd php-install-package
wget https://www.php.net/distributions/php-7.3.31.tar.gz
2.解压并进入目录
tar zxvf php-7.3.31.tar.gz
cd php-7.3.31
3.生成makefile文件
使用缺省的makefile,简单编译和安装操作如下:
make
make install
但是,如果我们想控制一些编译和安装的配置,则需要在编译前,自己生成makefile的配置,所以我没有直接执行上面的编译和安装操作,而是在生成makefile后再执行。
这里有一个生成mkefile配置的实例:
ls
./configure --disable-debug --prefix=/usr/local/php --enable-shmop --with-gd --with-jpeg-dir=/usr/lib64 --with-png-dir=/usr/lib64 --with-libxml-dir=/usr/lib64 --with-zlib-dir=/usr/local/lib --with-mysqli=mysqlnd --with-mysql=mysqlnd --with-pdo-mysql=mysqlnd --enable-sockets --with-iconv --enable-mbstring --enable-mbregex --enable-ftp --enable-gd-native-ttf --with-curl --enable-fpm --enable-pcntl --enable-sysvmsg --enable-sysvsem --enable-sysvshm --enable-zip --with-freetype-dir
ls
其中:
其中,
--prefix=[path]: 设定安装路径
--disable-debug: 编译时禁止加入调试符号
--enable-shmop: 启用shmop模块。Shmop is an easy to use set of functions that allows PHP to read, write, create and delete Unix shared memory segments.
--with-gd: 增加GD库的支持。GD库,是php处理图形的扩展库。
--with-jpeg-dir=[DIR]: GD库中jpeg lib的安装路径的prefix
'--with-png-dir=/usr/lib64' '--with-libxml-dir=/usr/lib64' '--with-zlib-dir=/usr/lib64': 与--with-jpeg-dir类似
--with-mysqli=FILE: 包含mysqli的支持。如果DIR取值为mysqlnd,则 the MySQL native driver will be used mysql_config
--with-mysql=DIR: 包含mysql的支持。如果DIR取值为mysqlnd,则 the MySQL native driver will be used /usr/local
--with-pdo-mysql=DIR: 支持PDO Mysql扩展模块。PDO扩展为PHP访问数据库定义了一个轻量级的、一致性的接口,它提供了一个数据访问抽象层,这样,无论使用什么数据库,都可以通过一致的函数执行查询和获取数据。如果DIR取值为mysqlnd,则 the MySQL native driver will be used /usr/local
--enable-sockets: 增加socket支持
--with-iconv-dir=DIR: 激活iconv,iconv是默认激活的,会到默认路径中区搜索。iconv函数库能够完成各种字符集间的转换,是php编程中不可缺少的基础函数库。
--enable-mbstring: Enable multibyte string support
--enable-mbregex:该选项默认开启。 MBSTRING: enable multibyte regex(正则表达式) support
--enable-ftp: Enable FTP support
--enable-gd-native-ttf: GD: Enable TrueType string function (ttf: TrueType string)
--with-curl=[DIR]: Include cURL support
--enable-fpm: Enable building of the fpm SAPI executable (非常重要的一个选项,用来开启FPM的支持)
--enable-pcntl: Enable pcntl support (CLI/CGI only) (php进程控制扩展)
--enable-sysvmsg: Enable sysvmsg support. 即System V消息队列
--enable-sysvsem: Enable sysvsem support. 即System V信号量
-enable-sysvshm: Enable sysvshm support. 即System V共享内存
php中对共享内存段的操作有两组函数:System V IPC和Shared Memory。 其中System V IPC系列函数能够更方便的操作数据,无需像Shared Memory那样必须自己掌握读写时的偏移量、长度等,也不用序列化/反序列化来回转换(因为Shared Memory函数只支持字符串格式的数据参数)。但是System V IPC系列不支持Windows,所以如果要在win环境下使用,只能选Shared Memory。
--enable-zip: Include Zip read/write support
--with-freetype-dir=DIR: GD库相关。 GD: Set the path to FreeType 2 install prefix
我这里只选择几个自己可以理解的配置参数执行,并加上–without-libzip,这篇文章中选择不安装libzip。
./configure --prefix=/usr/local/php --enable-shmop --with-gd --enable-sockets --with-iconv --enable-mbstring --enable-mbregex --enable-ftp --enable-fpm --enable-pcntl --enable-sysvmsg --enable-sysvsem --enable-sysvshm --enable-zip --with-jpeg-dir=/usr/lib64 --with-webp-dir=/usr/lib64 --without-libzip
相当于下面这几个选项没有加入配置
–disable-debug
–with-jpeg-dir=/usr/lib64
–with-png-dir=/usr/lib64
–with-libxml-dir=/usr/lib64
–with-zlib-dir=/usr/local/lib
–with-mysqli=mysqlnd
–with-mysql=mysqlnd
–with-pdo-mysql=mysqlnd
–with-curl
–with-freetype-dir
–enable-gd-native-ttf //这个参数,运行过程中提示:unrecognized options: --enable-gd-native-ttf
因为我的mysql还没有安装,就打算在后期再配置,我的理解,上面还没有配的一些配置,大多可以在安装好之后,在php.ini文件中配置。
4.执行编译和安装
make
make install
make花的时间相对多些,通常在执行make过程中也会有报错,一般根据报错提示去搜索一下,看是缺哪个依赖,补充安装后再make都可以解决。我是有一个地方卡住了,搞了两天都搞清楚是什么原因,报错点在:
parse_date.c -o ext/date/lib/parse_date.lo
cc: 编译器内部错误:已杀死(程序 cc1)
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://bugzilla.redhat.com/bugzilla> for instructions.
make: *** [ext/date/lib/parse_date.lo] 错误 1
这个点一直过不了,网上教的方法也都解决不了。
最后发现CPU一直100%,再去追查,是我的系统中了挖矿病毒。这个我在另外一篇文章里面详细说。解决了这个问题后,就可以顺利下一步安装了。
记录一下执行make install的记录:
[root@localhost php-7.3.31]# make install
/bin/sh /usr/local/src/php-install-package/php-7.3.31/libtool --silent --preserve-dup-deps --mode=install cp ext/opcache/opcache.la /usr/local/src/php-install-package/php-7.3.31/modules
Installing shared extensions: /usr/local/php/lib/php/extensions/no-debug-non-zts-20180731/
Installing PHP CLI binary: /usr/local/php/bin/
Installing PHP CLI man page: /usr/local/php/php/man/man1/
Installing PHP FPM binary: /usr/local/php/sbin/
Installing PHP FPM defconfig: /usr/local/php/etc/
Installing PHP FPM man page: /usr/local/php/php/man/man8/
Installing PHP FPM status page: /usr/local/php/php/php/fpm/
Installing phpdbg binary: /usr/local/php/bin/
Installing phpdbg man page: /usr/local/php/php/man/man1/
Installing PHP CGI binary: /usr/local/php/bin/
Installing PHP CGI man page: /usr/local/php/php/man/man1/
Installing build environment: /usr/local/php/lib/php/build/
Installing header files: /usr/local/php/include/php/
Installing helper programs: /usr/local/php/bin/
program: phpize
program: php-config
Installing man pages: /usr/local/php/php/man/man1/
page: phpize.1
page: php-config.1
Installing PEAR environment: /usr/local/php/lib/php/
[PEAR] Archive_Tar - already installed: 1.4.14
[PEAR] Console_Getopt - already installed: 1.4.3
[PEAR] Structures_Graph- already installed: 1.1.1
[PEAR] XML_Util - already installed: 1.4.5
[PEAR] PEAR - already installed: 1.10.13
Wrote PEAR system config file at: /usr/local/php/etc/pear.conf
You may want to add: /usr/local/php/lib/php to your php.ini include_path
/usr/local/src/php-install-package/php-7.3.31/build/shtool install -c ext/phar/phar.phar /usr/local/php/bin
ln -s -f phar.phar /usr/local/php/bin/phar
Installing PDO headers: /usr/local/php/include/php/ext/pdo/
[root@localhost php-7.3.31]#
**注意:**You may want to add: /usr/local/php/lib/php to your php.ini include_path,这句话意思是,你可能需要往目录 /usr/local/php/lib/php中添加php.ini,我在官方文档中,说是将文件复制到/usr/local/php/php.ini,执行以下命令。
cd /usr/local/src/php-install-package/php-7.3.31/ #进入安装包目录
cp php.ini-development /usr/local/php/php.ini
5.测试安装成功
[root@localhost ~]# cd /usr/local/php/bin
[root@localhost bin]# ls
pear peardev pecl phar phar.phar php php-cgi php-config phpdbg phpize
[root@localhost bin]# php -v
bash: php: 未找到命令...
[root@localhost bin]# /usr/local/php/bin/php -v
PHP 7.3.31 (cli) (built: Apr 15 2023 13:17:25) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.31, Copyright (c) 1998-2018 Zend Technologies
[root@localhost bin]#
可以看到,即使直接进入相应的目录,去执行php文件也是会失败的,而一个要使用完整的路径去执行。
为什么呢?
现在终于理解,linux和Dos不同,linux并不会自动识别当前路径,而是需要我们告诉它,以下方法就可以了:
[root@localhost bin]# ./php -v
PHP 7.3.31 (cli) (built: Apr 15 2023 13:17:25) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.31, Copyright (c) 1998-2018 Zend Technologies
在这里./就是告诉linux,执行当前路径的文件。
到此,输出结果表明:已经成功安装了php 7.3.31版本。
四、添加PHP环境变量
一般情况下,安装PHP过程是会自动添加环境变量,如果系统未自动添加环境变量,则需要手动添加。
从上面安装完成后测试可知,系统并不能直接执行php命令,而需要使用完成的路径,说明php的可执行文件并没有在系统的环境变量中。通过whereis和which命令可以确定这一点。
通过whereis命令快速定位系统中已安装的特定软件或工具的位置:
[root@localhost bin]# whereis php
php: /usr/local/lib/php.ini /usr/local/php
通过which命令可以查找其是否在可执行范围:
[root@localhost bin]# which php
/usr/bin/which: no php in (/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/local/php/bin/bin:/root/bin)
[root@localhost bin]#
可以看到,php不在环境变量中。
我们进入全局环境变量文件,vim /etc/profile,看到文件末尾已经添加了:
#PHP7.3
export PHP_HOME=/usr/local/php/bin
export PATH=$PATH:$PHP_HOME/bin
可是路径好像不对,上面的路径,导致PATH=/usr/local/php/bin/bin,多了一个bin
修正为:
#PHP7.3
export PHP_HOME=/usr/local/php
export PATH=$PATH:$PHP_HOME/bin
保存后,使其重新加载并测试:
[root@localhost bin]# source /etc/profile
[root@localhost bin]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/local/php/bin/bin:/root/bin:/usr/local/php/bin
[root@localhost bin]# which php
/usr/local/php/bin/php
[root@localhost bin]# cd /
[root@localhost /]# php -v
PHP 7.3.31 (cli) (built: Apr 15 2023 13:17:25) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.31, Copyright (c) 1998-2018 Zend Technologies
[root@localhost /]#
至此,在任何路径下,都能成功运行php命令了。
五、PHP-FPM配置
在安装PHP过程,生成makefile文件的配置参数加了–enable-fpm,相当于安装了PHP-FPM。FPM即是:FastCGI Process Manager。
1.复制配置文件
前面已经执行过复制php.ini,我们现在来测试运行php-fmp
[root@localhost ~]# cd /usr/local/php/sbin
[root@localhost sbin]# ls
php-fpm
[root@localhost sbin]# ./php-fpm
[16-Apr-2023 10:43:01] ERROR: failed to open configuration file '/usr/local/php/etc/php-fpm.conf': No such file or directory (2)
[16-Apr-2023 10:43:01] ERROR: failed to load configuration file '/usr/local/php/etc/php-fpm.conf'
[16-Apr-2023 10:43:01] ERROR: FPM initialization failed
[root@localhost sbin]#
错误提示的意思是:加载配置文件’/usr/local/php/etc/php-fpm.conf’失败。执行cp php-fpm.conf.default php-fpm.conf复制一份即可以解决。
[root@localhost sbin]# cd ../etc
[root@localhost etc]# ls
pear.conf php-fpm.conf.default php-fpm.d
[root@localhost etc]# cp php-fpm.conf.default php-fpm.conf
[root@localhost etc]# cd ../sbin
[root@localhost sbin]# ./php-fpm
[16-Apr-2023 10:46:48] WARNING: Nothing matches the include pattern '/usr/local/php/etc/php-fpm.d/*.conf' from /usr/local/php/etc/php-fpm.conf at line 143.
[16-Apr-2023 10:46:48] ERROR: No pool defined. at least one pool section must be specified in config file
[16-Apr-2023 10:46:48] ERROR: failed to post process the configuration
[16-Apr-2023 10:46:48] ERROR: FPM initialization failed
[root@localhost sbin]#
错误提示的意思是:没有任何的匹配php-fpm.conf第143行,FPM初始化失败。
查看了一下,这一行的内容是:
include=/usr/local/php/etc/php-fpm.d/*.conf
即是在/usr/local/php/etc/php-fpm.d这个目录中,缺少*.conf配置文件,这个目录下有一个default的文件,执行复制命令后再运行php-fpm。
[root@localhost ~]# cp /usr/local/php/etc/php-fpm.d/www.conf.default /usr/local/php/etc/php-fpm.d/www.conf
[root@localhost ~]# cd /usr/local/php/etc/php-fpm.d/
[root@localhost php-fpm.d]# ls
www.conf www.conf.default
[root@localhost php-fpm.d]# cd ../../sbin
[root@localhost sbin]# ./php-fpm
[root@localhost sbin]#
没有再报错。
另外,官方文档中告诉我们还要从安装包文件夹那里复制sapi/fpm/php-fpm到/usr/local/bin,我们复制到到/usr/local/php/bin,我理解其实就是将php-fmp复制到环境变量所包含的目录中,那样,后面就不需要进入sbin目录下去执行php-fpm
[root@localhost ~]# cd /usr/local/src/php-install-package/php-7.3.31
[root@localhost php-7.3.31]# ls /usr/local/php/bin
pear peardev pecl phar phar.phar php php-cgi php-config phpdbg phpize
[root@localhost php-7.3.31]# cp sapi/fpm/php-fpm /usr/local/php/bin
[root@localhost php-7.3.31]# ls /usr/local/php/bin
pear peardev pecl phar phar.phar php php-cgi php-config phpdbg php-fpm phpize
[root@localhost php-7.3.31]#
2.修改php.ini,禁用PATHINFO处理方式
打开php.ini
nano /usr/local/php/php.ini
定位到 cgi.fix_pathinfo=
并将其修改为如下所示:
cgi.fix_pathinfo=0
提示:在php.ini配置中,cgi.fix_pathinfo=0表示禁用了 PHP 的 PATHINFO 处理方式。这意味着,当使用 CGI/FastCGI 服务器时,PHP 将不会尝试从 URL 中解析出文件名,并且将通过 SCRIPT_FILENAME 环境变量直接使用指定的 PHP 文件来处理请求。这通常被认为是更安全的设置,因为它可以防止一些潜在的安全漏洞。
3.配置身份运行
在启动服务之前,需要修改 php-fpm.conf 配置文件,确保 php-fpm 模块使用 www-data 用户和 www-data 用户组的身份运行。
vim /usr/local/php/etc/php-fpm.d/www.conf
找到
user = nobody
group = nobody
这个地方,官方文档建议修改为:
user = www-data
group = www-data
此时,再运行php-fpm
[root@localhost php]# php-fpm
[16-Apr-2023 11:51:55] ERROR: [pool www] cannot get uid for user 'www-data'
[16-Apr-2023 11:51:55] ERROR: FPM initialization failed
[root@localhost php]#
看来这个用户可能需要手动创建的,为了避免麻烦,我重新改回nobody算了,日后需要时再去创建修改。
[root@localhost php]# php-fpm
[16-Apr-2023 11:58:26] ERROR: unable to bind listening socket for address '127.0.0.1:9000': Address already in use (98)
[16-Apr-2023 11:58:26] ERROR: FPM initialization failed
说9000端口已经被占用
[root@localhost php]# ps -ef | grep php
root 12462 82177 0 12:04 pts/0 00:00:00 grep --color=auto php
root 67535 1 0 11:03 ? 00:00:00 php-fpm: master process (/usr/local/php/etc/php-fpm.conf)
nobody 67536 67535 0 11:03 ? 00:00:00 php-fpm: pool www
nobody 67537 67535 0 11:03 ? 00:00:00 php-fpm: pool www
[root@localhost php]#
显示,php-fpm已经在运行中。
[root@localhost php]# lsof -i :9000
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
php-fpm 67535 root 7u IPv4 2516913 0t0 TCP localhost:cslistener (LISTEN)
php-fpm 67536 nobody 5u IPv4 2516913 0t0 TCP localhost:cslistener (LISTEN)
php-fpm 67537 nobody 5u IPv4 2516913 0t0 TCP localhost:cslistener (LISTEN)
[root@localhost php]#
4.设置开机自启动php-fpm(php-fpm.service配置)
根据安装nginx的经验,首先想到的是创建一个名为php-fpm.service`的服务文件,将该文件存放在/lib/systemd/system/目录下。
我查了一下网上的资料,有些文章表达的意思是,在安装包目录里面有这个文件,那样我直接拷贝就好了。
[root@localhost etc]# find / -name php-fpm.service
find: ‘/proc/44711’: 没有那个文件或目录
find: ‘/proc/44721’: 没有那个文件或目录
/usr/local/src/php-install-package/php-7.3.31/sapi/fpm/php-fpm.service
[root@localhost etc]#
果然有这个文件。
其内容为:
[Unit]
Description=The PHP FastCGI Process Manager
After=network.target
[Service]
Type=simple
PIDFile=/usr/local/php/var/run/php-fpm.pid
ExecStart=/usr/local/php/sbin/php-fpm --nodaemonize --fpm-config /usr/local/php/etc/php-fpm.conf
ExecReload=/bin/kill -USR2 $MAINPID
PrivateTmp=true
将这个文件复制到/lib/systemd/system目录中
cp /usr/local/src/php-install-package/php-7.3.31/sapi/fpm/php-fpm.service /lib/systemd/system/php-fpm.service
然后测试systemctl status php-fpm
[root@localhost ~]# systemctl status php-fpm
● php-fpm.service - The PHP FastCGI Process Manager
Loaded: loaded (/usr/lib/systemd/system/php-fpm.service; disabled; vendor preset: disabled)
Active: inactive (dead)
[root@localhost ~]#
[root@localhost ~]# systemctl start php-fpm
[root@localhost ~]# systemctl status php-fpm
● php-fpm.service - The PHP FastCGI Process Manager
Loaded: loaded (/usr/lib/systemd/system/php-fpm.service; disabled; vendor preset: disabled)
Active: failed (Result: exit-code) since 一 2023-04-17 06:04:30 CST; 5s ago
Process: 73847 ExecStart=/usr/local/php/sbin/php-fpm --nodaemonize --fpm-config /usr/local/php/etc/php-fpm.conf (code=exited, status=78)
Main PID: 73847 (code=exited, status=78)
4月 17 06:04:30 localhost.localdomain systemd[1]: Started The PHP FastCGI Process Manager.
4月 17 06:04:30 localhost.localdomain php-fpm[73847]: [17-Apr-2023 06:04:30] ERROR: unable to bind listening socket for address '127.0.0.1:9000': Address already in use (98)
4月 17 06:04:30 localhost.localdomain php-fpm[73847]: [17-Apr-2023 06:04:30] ERROR: FPM initialization failed
4月 17 06:04:30 localhost.localdomain systemd[1]: php-fpm.service: main process exited, code=exited, status=78/n/a
4月 17 06:04:30 localhost.localdomain systemd[1]: Unit php-fpm.service entered failed state.
4月 17 06:04:30 localhost.localdomain systemd[1]: php-fpm.service failed.
启动php-fpm过程中,发现端口被占用,其实就是php-fpm已经启动,但好像systemctl好像不能识别。重启看看。
[root@localhost ~]# systemctl reload php-fpm
Job for php-fpm.service invalid.
reload的配置好像有问题,我怀疑是配置中的ExecReload=/bin/kill -USR2 $MAINPID这一行有问题,后面再处理研究。
临时通过将进程杀掉处理,然后再启动:
[root@localhost ~]# ps -ef | grep php-fpm
root 67535 1 0 4月16 ? 00:00:05 php-fpm: master process (/usr/local/php/etc/php-fpm.conf)
nobody 67536 67535 0 4月16 ? 00:00:00 php-fpm: pool www
nobody 67537 67535 0 4月16 ? 00:00:00 php-fpm: pool www
root 93356 53112 0 06:19 pts/0 00:00:00 grep --color=auto php-fpm
[root@localhost ~]# kill -15 67536
[root@localhost ~]# kill -15 67537
[root@localhost ~]# kill -15 67535
[root@localhost ~]# systemctl start php-fpm
[root@localhost ~]# systemctl status php-fpm
● php-fpm.service - The PHP FastCGI Process Manager
Loaded: loaded (/usr/lib/systemd/system/php-fpm.service; enabled; vendor preset: disabled)
Active: active (running) since 一 2023-04-17 06:22:07 CST; 1s ago
Main PID: 96669 (php-fpm)
Tasks: 3
CGroup: /system.slice/php-fpm.service
├─96669 php-fpm: master process (/usr/local/php/etc/php-fpm.conf)
├─96674 php-fpm: pool www
└─96675 php-fpm: pool www
4月 17 06:22:07 localhost.localdomain systemd[1]: Started The PHP FastCGI Process Manager.
[root@localhost ~]#
终于显示正常。
此时再测试reload命令,并查看日志:
[root@localhost ~]# systemctl reload php-fpm
[root@localhost ~]# journalctl -xe | grep php-fpm
截取摘录执行reload部份的日志:
-- Unit php-fpm.service has begun reloading its configuration
4月 17 06:36:43 localhost.localdomain systemd[1]: Can't open PID file /usr/local/php/var/run/php-fpm.pid (yet?) after reload: No such file or directory
-- Subject: Unit php-fpm.service has finished reloading its configuration
-- Unit php-fpm.service has finished reloading its configuration
[root@localhost ~]#
好像提示没有这个文件:/usr/local/php/var/run/php-fpm.pid
又去进一步了解。先看ExecReload=/bin/kill -USR2 $MAINPID。
在 kill
命令中,-USR2
选项表示要发送一个 SIGUSR2
信号给特定的进程或进程组。其中:
SIGUSR2
是 Linux / Unix 操作系统提供的一种信号,该信号可用于应用程序内部通信及优雅重启等场景下。针对 PHP-FPM 进程而言,通常使用这种信号来实现平滑重载(reload)配置。kill
命令用于向一个或多个进程发送指定的信号。通过结合-USR2
和$MAINPID
变量,可以从服务管理器触发交互式的信号发送。在上述示例中,$MAINPID
是一个环境变量,代表将由systemd
管理的 PHP-FPM 进程的主进程 ID。因此,执行bin/kill -USR2 $MAINPID
命令时,就会向相应的 PHP-FPM 主进程发送SIGUSR2
信号,以更新其配置并平滑重载 (reload) php-fpm 。
现在问题是:PIDFile并没有在这个位置/usr/local/php/var/run/php-fpm.pid,查看配置文档cat /usr/local/php/etc/php-fpm.conf 发现:
[global]
; Pid file
; Note: the default prefix is /usr/local/php/var
; Default Value: none
;pid = run/php-fpm.pid
pid文档位置配置的并没有问题,问题是代码都是注释掉的,由于注释掉,所以没有生成,我们把;pid = run/php-fpm.pid这行的注释去除。此时再/usr/local/php/var/run下就有了php-fpm.pid
然后重新再运行:
[root@localhost ~]# systemctl reload php-fpm
[root@localhost ~]# journalctl -xe | grep php-fpm
日志多了这几行,说明reload的问题解决,
-- Subject: Unit php-fpm.service has begun reloading its configuration
-- Unit php-fpm.service has begun reloading its configuration
-- Subject: Unit php-fpm.service has finished reloading its configuration
-- Unit php-fpm.service has finished reloading its configuration
注意:我发现kill -USR2这个命令reload进程,进程号是不会变化的。
至此,我们解决了reload报错的提示。
开机自启动设置
[root@localhost ~]# systemctl disable php-fpm
Removed symlink /etc/systemd/system/multi-user.target.wants/php-fpm.service.
[root@localhost ~]#
[root@localhost ~]# systemctl enable php-fpm
Created symlink from /etc/systemd/system/multi-user.target.wants/php-fpm.service to /usr/lib/systemd/system/php-fpm.service.
[root@localhost ~]#
到此,php-fpm.service的配置测试完成。
六、配置Nginx的FastCGI支持
通过配置nginx.conf,整合PHP和Nginx服务,让Nginx支持php的启动。
vim /usr/local/nginx/conf/nginx.conf
修改默认的 location 块,使其支持 .php 文件:
location / {
root html;
index index.php index.html index.htm;
}
下一步配置来保证对于 .php 文件的请求将被传送到后端的 PHP-FPM 模块, 取消默认的 PHP 配置块的注释,并修改为下面的内容:
配置将 .php 文件的请求传送到后端的 PHP-FPM 模块, 取消默认的 PHP 配置块的注释,我的配置如下面的内容:
location ~* \.php$ {
fastcgi_index index.php;
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
我的配置
location ~ \.php$ {
# root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
include fastcgi_params;
}
重启加载Nginx配置:
systemctl reload nginx
创建index.php测试文件:
echo "<?php phpinfo(); ?>" >> /usr/local/nginx/html/index.php
打开页面测试,页面显示:File not found.
查找nginx的错误日志文件:
[root@localhost ~]# find / -name "error.log" 2>/dev/null | grep nginx
/usr/local/webserver/nginx/logs/error.log
vim打开日志,shift+g显示最后的提示:
2023/04/18 07:45:17 [error] 31425#0: *21245 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, client: 192.168.8.13, server: localhost, request: "GET / HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "192.168.8.12"
在网上查了些资料,有很多种原因:
1.本地文件夹访问权限和属主检查
2.php.ini文件中没有配open_basedir
3.selinux问题,通过关闭解决
4.nginx中配置问题:root 路径配置必须要有,而且必须要写对
5.nginx中配置问题:不能识别到/scripts路径
第2和第4个原因的方法试过无效,最后通过第5个原因解决了。就是在在配置nginx.conf文件时
location ~ \.php$ {
# root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
include fastcgi_params;
}
改为:
location ~ \.php$ {
#root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
include fastcgi_params;
}
原因是:Nginx识别不到/scripts路径,所以phpinfo验证信息就无法正常通过。$document_root 代表当前请求在root指令中指定的值。
重新加载nginx后,便能够正确显示phpinfo信息。
至此,安装和配置PHP成功完成!
后记:以上把过程中走的一些弯路也记录下来了,前后是花了有一两周时间吧(不是连着做),中间也花了时间处理病毒。有机会有时间的话,我再整理一份顺利执行的指令和操作记录整理出来。
整个安装还是有挑战的,很多点都需要去查资料,过程可以学到不少。现在再去迎接下一个挑战。
(2023-4-18)
七、参考文章
参考文章:
1.https://blog.csdn.net/suo_y/article/details/124299052
2.https://www.cnblogs.com/hencehong/archive/2013/03/24/2977992.html
3.Unix 系统下的 Nginx 1.4.x安装PHP(官方的教程)
https://www.php.net/manual/zh/install.unix.nginx.php
4.ChatGPT
5.https://www.php.net/manual/zh/zip.installation.php
6.https://blog.csdn.net/a1779078902/article/details/82502145
7.https://blog.csdn.net/dolores_peng/article/details/78521879
8.https://blog.csdn.net/weixin_67792584/article/details/125033473
9.https://www.cnblogs.com/feng18/p/6225781.html
10.https://www.cnblogs.com/wanglijun/p/8777945.html