以前都是靠各种一键脚本来安装 PHP,今天我尝试一下从源码手动编译安装 PHP,这里记录一下过程,有不足之处欢迎指正。废话不多说,直接开始。
系统环境
[root@hwc ~]# cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core)
环境需要
- 安装 PHP 需要
libxml2-devel、openssl-devel、curl-devel、libpng、libpng-devel、libicu-devel、gcc-c++、libmcrypt-devel、libtidy-devel、unixODBC-devel、postgresql-devel。yum -y install libxml2 libxml2-devel openssl openssl-devel curl curl-devel libpng libpng-devel libicu-devel gcc-c++ libmcrypt-devel libtidy-devel unixODBC-devel postgresql-devel - 手动安装
unixODBC到/usr/local/unixODBC首先从官网下载最新的unixODBC包并解压(如果感觉速度慢,可以使用备用下载)cd /usr/local wget http://ftp.unixodbc.org/unixODBC-2.3.7.tar.gz tar -zxvf unixODBC-2.3.7.tar.gz进入解压出来的文件夹内,配置安装目录,并编译安装。这里
-prefix一定要为/usr/local/unixODBC,否则后面配置 PHP 时会报错cd unixODBC-2.3.7 ./configure --prefix=/usr/local/unixODBC make && make install
以上是我配置的时候遇到的缺少的包,具体每个人配置的时候缺少的可能不一样,报错时请安装相应的包
安装
首先下载 PHP 安装包,这里我下载的是php-7.1.33,下载到/usr/local(如果下载速度过慢,可以使用备用下载)
cd /usr/local
wget https://www.php.net/distributions/php-7.1.33.tar.gz
tar -zxvf php-7.1.33.tar.gz
然后配置安装选项
cd /usr/local/php-7.1.33
./configure --enable-fpm --enable-mysqlnd --enable-opcache --enable-pcntl --enable-mbstring --enable-soap --enable-zip --enable-calendar --enable-bcmath --enable-exif --enable-ftp --enable-intl --with-mysqli --with-pdo-mysql --with-pdo-odbc=unixODBC --with-pdo-pgsql --with-openssl --with-curl --with-gd --with-gettext --with-mhash --with-openssl --with-mcrypt --with-tidy --enable-wddx --with-xmlrpc
上面的配置参数开启了很多 PHP 扩展,某些扩展需要特定的包,如果没有的话,请自行安装,或酌情删除某些参数 关于配置的可选参数及作用,请参考核心配置选项列表
配置成功会出现下面这样的输出。希望你能一次成功,但是如果你的系统比较干净,在执行完上一步安装了那些包后仍然可能缺少一些包,缺少包的话配置就会报错。看见报错别怕,根据报错内容去安装对应的包就可以
Thank you for using PHP.
config.status: creating php7.spec
config.status: creating main/build-defs.h
config.status: creating scripts/phpize
config.status: creating scripts/man1/phpize.1
config.status: creating scripts/php-config
config.status: creating scripts/man1/php-config.1
config.status: creating sapi/cli/php.1
config.status: creating sapi/fpm/php-fpm.conf
config.status: creating sapi/fpm/www.conf
config.status: creating sapi/fpm/init.d.php-fpm
config.status: creating sapi/fpm/php-fpm.service
config.status: creating sapi/fpm/php-fpm.8
config.status: creating sapi/fpm/status.html
config.status: creating sapi/phpdbg/phpdbg.1
config.status: creating sapi/cgi/php-cgi.1
config.status: creating ext/phar/phar.1
config.status: creating ext/phar/phar.phar.1
config.status: creating main/php_config.h
config.status: executing default commands
配置成功之后编译测试并安装,测试环节不要少
make && make test
make install
测试环节可能会失败,可能会遇到一些bug,把错误信息根据提示发送给 PHP 官方就好,你也可以选择不发送,这都没关系。只要编译成功,就可以执行安装。 安装之后,查看是否安装成功
[root@hwc ~]# php -v
PHP 7.1.33 (cli) (built: Jan 11 2020 17:34:26) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2018 Zend Technologies
配置php.ini
查看php.ini应该放置的目录
[root@hwc ~]# php --ini
Configuration File (php.ini) Path: /usr/local/lib
Loaded Configuration File: (none)
Scan for additional .ini files in: (none)
Additional .ini files parsed: (none)
从Configuration File (php.ini) Path: /usr/local/lib可以看到php.ini应该放到/usr/local/lib目录内,然后Loaded Configuration File: (none)表示在/usr/local/lib目录内并未加载到php.ini,我们需要把php.ini文件放到那里
先去 PHP 安装包目录,然后拷贝php.ini-development到/usr/local/lib/php.ini。
cp /usr/local/php-7.1.33/php.ini-development /usr/local/lib/php.ini
请注意如有需要,请将路径替换成你的正确的路径 拷贝过去之后再查看一下
[root@hwc ~]# php --ini
Configuration File (php.ini) Path: /usr/local/lib
Loaded Configuration File: /usr/local/lib/php.ini
Scan for additional .ini files in: (none)
Additional .ini files parsed: (none)
可以看到php.ini文件已经加载到
如果你想更改php.ini文件的加载路径,你可以在编译安装前通过配置参数--with-config-file-path=来配置
配置php-fpm.conf
php-fpm是一个FastCGI程序,是用来管理CGI进程(例如:php-cgi,PHP解释器)的。 执行配置文件测试命令以查看测试文件情况
[root@hwc ~]# php-fpm -t
[11-Jan-2020 18:25:22] ERROR: failed to open configuration file '/usr/local/etc/php-fpm.conf': No such file or directory (2)
[11-Jan-2020 18:25:22] ERROR: failed to load configuration file '/usr/local/etc/php-fpm.conf'
[11-Jan-2020 18:25:22] ERROR: FPM initialization failed
可以看到系统并未加载到/usr/local/etc/php-fpm.conf。它当然加载不到,因为还没配置。
进入到/usr/local/etc目录下,可以看到有个php-fpm.conf.default,拷贝出来一份重命名为php-fpm.conf,然后还有一个文件是/usr/local/etc/php-fpm.d/www.conf.default,这里也要做一下相同处理。
cp /usr/local/etc/php-fpm.conf.default /usr/local/etc/php-fpm.conf
cp /usr/local/etc/php-fpm.d/www.conf.default /usr/local/etc/php-fpm.d/www.conf
改好名后再测试一下
[root@hwc ~]# php-fpm -t
[11-Jan-2020 18:54:18] ERROR: Unable to globalize '/usr/local/NONE/etc/php-fpm.d/*.conf' (ret=2) from /usr/local/etc/php-fpm.conf at line 125.
[11-Jan-2020 18:54:18] ERROR: failed to load configuration file '/usr/local/etc/php-fpm.conf'
[11-Jan-2020 18:54:18] ERROR: FPM initialization failed
还是失败,怎么回事?查看失败记录,很容易看到php-fpm.conf第125行出了错误,而且是路径书写错误。好了,那改吧。
vim /usr/local/etc/php-fpm.conf
来到vim编辑界面输入:set number以显示行号,让我们更快地找到第125行
来到第125行,可以看到第125行写的是
include=NONE/etc/php-fpm.d/*.conf
把NONE修改成绝对路径试试,修改后如下
include=/usr/local/etc/php-fpm.d/*.conf
保存并退出后,再次测试
[root@hwc ~]# php-fpm -t
[11-Jan-2020 19:02:39] NOTICE: configuration file /usr/local/etc/php-fpm.conf test is successful
OK,成功了。
在启动服务之前,需要修改www.conf配置文件,确保 php-fpm 模块使用 www 用户和 www 用户组的身份运行
vim /usr/local/etc/php-fpm.d/www.conf
找到如下部分并进行如下修改
; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user's group
; will be used.
user = www
group = www
然后启动php-fpm,php-fpm的可执行文件路径由 PHP 配置时的--prefix=决定,prefix默认是/usr/local。而php-fpm的可执行文件在prefix/sbin目录下,所以默认是在/usr/local/sbin目录下
启动php-fpm
[root@hwc ~]# /usr/local/sbin/php-fpm
[11-Jan-2020 19:31:56] ERROR: [pool www] cannot get uid for user 'www'
[11-Jan-2020 19:31:56] ERROR: FPM initialization failed
启动失败,没有www用户,那就创建
groupadd www
useradd -g www -s /sbin/nologin www
再次启动
[root@hwc ~]# /usr/local/sbin/php-fpm
没有报错,经如下检查,说明启动成功
[root@hwc ~]# ps -ef | grep php-fpm
root 19159 1 0 19:35 ? 00:00:00 php-fpm: master process (/usr/local/etc/php-fpm.conf)
www 19160 19159 0 19:35 ? 00:00:00 php-fpm: pool www
www 19161 19159 0 19:35 ? 00:00:00 php-fpm: pool www
root 19170 8731 0 19:40 pts/0 00:00:00 grep --color=auto php-fpm
php-fpm启动与停止
为了能够更加方便地启动与停止 php-fpm ,我们需要编写一个服务
vim /usr/lib/systemd/system/php-fpm.service
添加以下内容,请把路径换成自己的php-fpm路径
[Unit]
Description=php-fpm
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
ExecStart=/usr/local/sbin/php-fpm
[Install]
WantedBy=multi-user.target
之后就可以使用systemctl方便地管理php-fpm服务了
# 设置开机自动启动
systemctl enable php-fpm
# 设置禁止开机自动启动
systemctl disable php-fpm
# 启动服务
systemctl start php-fpm
# 停止服务
systemctl stop php-fpm
# 查看服务状态
systemctl status php-fpm
错误处理
- 关于启动php-fpm报错,显示127.0.0.1:9000端口已被占用
报错内容如下
ERROR: unable to bind listening socket for address '127.0.0.1:9000': Address already in use (98)查看一下是谁在占用端口
[root@hwc php-7.1.33]# netstat -lntup | grep 9000 tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 25688/php-fpm: mast你会发现就是它自己在占用这个端口。执行下面命令关闭其进程,然后再次启动php-fpm就好了。
killall php-fpm