CentOS上PHP源码安装和配置

2023-10-29

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主要有以下作用:

  1. 处理HTTP请求:当Web服务器(如Nginx或Apache)接收到PHP脚本的HTTP请求时,它会将请求发送给PHP-FPM进程池。

  2. 解释和执行PHP代码: PHP-FPM会解释处理收到的php文件并执行其中的代码,然后将结果返回给Web服务器,使其能够将结果发送回客户端浏览器。

  3. 进程管理: PHP-FPM还负责管理和控制多个PHP进程,并在需要时动态地创建或销毁这些进程。可以基于请求量及资源使用情况自动调整进程数,以达到优化响应速度及提高系统可用性的目的。

  4. 特定功能的支持: 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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CentOS上PHP源码安装和配置 的相关文章

  • Laravel 转义 Blade 模板中的所有 HTML

    我正在 Laravel 中构建一个小型 CMS 并尝试显示内容 存储在数据库中 它显示 HTML 标签而不是执行它们 就像所有打印数据都有一个自动 html entity decode 一样
  • 如何在 PHP 中使用 RS256 签署 X.509 证书?无法获取有效指纹...x5t

    我已经实现了 JWT 令牌生成器库Here https github com F21 jwt blob master JWT JWT php 并且我能够获得 RS256 令牌 有效负载 但我对标题数据有疑问 我需要一个标头值 x5t 该标头
  • 在 php 中将单词转换为数字 II

    这里有一个很棒的功能在 PHP 中将单词转换为数字 https stackoverflow com questions 1077600 converting words to numbers in php来自埃尔约博 但我有一个问题 字符串
  • 使用月份、年份、星期几和周数计算月份中的某一天

    如何在 PHP 中计算月份中的某一天 并给出月份 年份 星期几和周数 例如 如果我有 2013 年 9 月 星期几是星期五 周数是 2 那么我应该得到 6 2013 年 9 月 6 日是第二周的星期五 实现此目的的一种方法是使用相对格式 h
  • YouTube 数据 api 未按 viewCount 排序

    我正在尝试按 viewCount 从高到低排序 YouTube 频道视频 但结果并不是按最大观看次数排序 以下是我正在使用的 API https www googleapis com youtube v3 search key api ke
  • Google 应用程序引擎 - 上传的文件在谷歌云存储上不公开

    我有一个允许用户上传图像的应用程序 并且我希望其他用户能够看到该图像 我使用 CloudStorageTools createUploadUrl 方法允许用户通过 POST 上传 然后 我将上传的文件并使用 move uploaded fi
  • Symfony 3新建项目报错

    我开始编写有关 Symfony 3 的教程 在使用以下命令创建新项目时遇到问题 php symfony phar new Symfony 我有这个错误 GuzzleHttp Exception RequestException Error
  • 如何修复 Nginx 自动 301 重定向到带有尾部斜杠的相同 URL?

    当我尝试将 Web 应用程序的子目录中的索引文件访问到相同的 URL 但附加了斜杠 时 Nginx 出现了不良行为 它正在重新路由请求 我有一个简单的 Web 应用程序 其中设置了一个根目录和其中的许多子目录 每个子目录中都有一个 inde
  • WordPress WooCommerce - 使用 WC_Cart 类将可变产品添加到购物车

    我正在尝试将可变产品添加到 WordPress 插件 WooCommerce 的购物车中 到目前为止 我已经能够添加单一 简单的产品 woocommerce gt cart gt add to cart product id quantit
  • 将错误保存到 MySQL 数据库

    我有一个 php 查询来更新 MySQL 数据库 请参见下文 sql update hr payroll set payroll number payroll number tax code tax bacs ref bacs ref pa
  • 从 TypeScript 运行任何 Linux 终端命令?

    有没有办法直接从 TypeScript 类中执行 Linux 终端命令 这个想法是做类似的事情 let myTerminal new LinuxTerminal let terminalResult myTerminal run sudo
  • PHP file_exists() 对我不起作用?

    由于某种原因 下面的 PHP 代码将无法工作 我无法弄清楚 很奇怪的是 file exists 似乎没有看到图像确实存在 我已经检查以确保将良好的文件路径插入到 file exists 函数中并且它仍在运行 如果我将 file exists
  • MYSQL:SQL查询获取自增字段的值

    我有一张桌子 主键是id及其自动递增 现在 当我插入新记录时 我需要获取更新记录的 id 我怎样才能做到这一点 如果我使用查询 select max id from table name 执行后我可以获得id 但我能确定它是刚刚插入的记录的
  • 如果一个多维数组中的子数组与另一个多维数组不同,则覆盖该子数组

    我坚持这个问题 真的不知道如何解决 我有两个多维数组 需要将第二个数组中的每个 entry id 与第一个数组进行匹配 然后需要检查第二个数组中的每个 file no 是否在数据库 第一个数组 中 并且 status 是否与第一个数组匹配
  • 在 wampserver 2.2 上安装 php_imagick.dll PHP 扩展

    我使用的是 32 位操作系统的 Windows 7 我安装了 ImageMagick 6 8 7 Q16Link https www imagemagick org script download php windows我能够从命令行 转换
  • 如何在特定 systemd 服务重新启动时触发自定义脚本运行

    我想知道如何安排自定义脚本在重新启动服务时运行 我的用例是 每当重新启动 Tomcat 服务时 我都必须运行多个命令 我想知道是否有一种方法可以编写脚本并安排它在重新启动 Tomcat 服务时运行 我已将 tomcat 脚本设置为 syst
  • 劫持系统调用

    我正在编写一个内核模块 我需要劫持 包装一些系统调用 我正在暴力破解 sys call table 地址 并使用 cr0 来禁用 启用页面保护 到目前为止一切顺利 一旦完成 我将公开整个代码 因此如果有人愿意 我可以更新这个问题 无论如何
  • PHP strtotime() 未返回正确的月份

    由于当前月份 年份是 2012 年 1 月 为什么以下代码返回 2011 年 12 月而不是 2011 年 11 月 echo date F Y strtotime 2 months 如果有影响的话 这是在 PHP 5 3 0 上 要获得您
  • 如何在PHP中获取div中的所有链接

    我想从另一个网站打开一个页面 并提取一个中的所有链接 href div of class layout 2 2 在此页面中 我如何使用 PHP 来做到这一点 我想复制layout 2 2中的每个链接this https url 网页 这是我
  • node-mongodb-native的插入性能

    我正在使用 MongoDB 测试 Node js 的性能 我知道其中每一个都很好 彼此独立 但我正在尝试一些测试来感受它们 我遇到了这个问题 但无法确定来源 问题 我正在尝试在单个 Node js 程序中插入 1 000 000 条记录 它

随机推荐

  • C51定时器与计数器(学习笔记)

    1 什么是定时器与计数器 1 定时器与计数器都是soc当中的一个内部外设 计数器顾名思义是用来计数的 就和我们的秒表一样 假如定时20秒 当我们按下秒表开始计数时 数秒的过程就是计数 计时器 当秒表数到20时 定时器 就自动暂停 2 工作模
  • Redis系列--新数据类型详解

    一 Bitmaps 一 简介 计算机存储数据时 都是以二进制位表示 Redis提供了Bitmaps这个 数据类型 可以实现对位的操作 1 Bitmaps本身不是一种数据类型 实际上它就是字符串 key value 但是它可以对字符串的位进行
  • matlab 将深度图像转换为点云

    目录 一 功能概述 1 算法概述 2 主要函数 3 参考文献 二 代码实现 三 结果展示 1 深度图像 2 彩色图像 3 生成点云 四 参考链接 一 功能概述 1 算法概述 深度相机能够获取物体到相机的距离信息 可以根据距离信息 计算像素的
  • 递归调用之迷宫问题

    我们假设数字1表示墙 数字0表示可以走 那么就可以用一个二维数组来模拟一个迷宫 并可以用递归调用来求解路线 下面的代码是用Java模拟的一个迷宫 代码很简单 public class MiGong public static void ma
  • button标签的onclick事件

    1 普通的button标签定义onclick事件 1 无参
  • delphi 10.3 FastReport 多设备跨平台 打印之解决方法

    以下能WINDOWS10 DELPHI 10 3 FastReport6 0上顺利通过 基础知识点 需掌握 https blog csdn net qq 25439957 article details 87110559 FastRepor
  • Java天地 学习探讨Java Spring中使用classpath加载配置文件浅析

    Spring中使用classpath加载配置文件浅析 如果您感觉可以请提出您宝贵的意见 在应用Spring的工程中 使用class path的方式加载配置文件应该是最常用的做法 然而对大部分人来说 刚开始使用Spring时 几乎都碰到过加载
  • 免费搜索引擎登录入口

    百度免费登录入口 http www baidu com search url submit htm 新浪免费登录入口 http bizsite sina com cn newbizsite docc index 2jifu 09 htm 搜
  • Vue中@input用法以及v-model示例

  • 外部局域网直接访问WSL2

    1 开启hyper v 1 首先 进入控制面板 程序 启用或关闭windows功能 勾选hyper v 确认后重启电脑 2 打开 Windows PowerShell 输入 systeminfo 命令 能够看到出现了很多处理器的信息 最末尾
  • MongoDB - 安装

    一 Docker安装MongoDB 1 安装 安装版本 7 0 0 docker run itd name mongodb v C data mongodb data data db p 27017 27017 mongo 7 0 0 au
  • QT环境变量配置

    QT官网地址 https my qt io 一 windows系统 1 1 QT下载安装 1 2 进入Qt安装目录 1 3 拷贝gcc所在的路径 不同安装目录有所差异 C Qt Qt5 5 0 Tools mingw492 32 bin 1
  • 数学建模常用Matlab/Lingo/c代码总结系列——旅行商TSP问题

    Lingo代码 MODEL SETS CITY 1 6 U U I sequence no of city LINK CITY CITY DIST The distance matrix X X I J 1 if we use link I
  • vuex中拿不到state中值的问题(state是undefined)

    首先下载vuex然后看一下项目中main文件内有没有引入store文件并且挂载 import Vue from vue import App from App vue import Element from element ui impor
  • IDEA 打包MapReduce程序到集群运行的两种方式以及XShell和Xftp过期的解决

    参考博客 MapReduce打包成jar上传到集群运行 http t csdn cn 2gK1d Xshell7 Xftp7 解决强制更新问题 http t csdn cn rxiBG IDEA打包MapReduce程序 方式一 轻量级打包
  • forkJoin, zip, combineLatest区别

    前言 forkJoin zip combineLatest是rxjs中的合并操作符 用于对多个流进行合并 很多人第一次接触rxjs时往往分不清它们之间的区别 其实这很正常 因为当你准备用来合并的流是那种只会发射一次数据就关闭的流时 比如ht
  • [小技巧] git diff 里显示日文

    先在命令行执行下面的命令 export LANG ja JP UTF 8 然后执行 git diff
  • TensorRT对face_boxes的加速

    TensorRT对face boxes进行加速 难点 priorbox layer和mobileNet SSD中的priorbox layer实现不太一样了 所以要对这层自己进行实现 当前遇到的报错 问题1 nvinfer1 DimsCHW
  • mac word无法显示仿宋字体解决方案

    仿宋是论文写作重要的字体 今天发现好多朋友的macOS系统里的word显示不了仿宋 或者显示不了一些字体 而我的电脑则是时而显示正常 时而显示异常 于是搜了一些解决方案并且自己实测了一下 在应用程序中找到word 右键显示包内容 在Reso
  • CentOS上PHP源码安装和配置

    CentOS上PHP源码安装和配置 此文是在CentOS 7上已经部署了Nginx的基础上进行的 关于CentOS7上安装Nginx 可参考我之前的文章 CentOS上Nginx安装记录 我们现在在这个基础上安装PHP 7 PHP里面概念挺