PHP

linux下安装php7或php8 以及编译时各种故障bug排除

字号+ 编辑: 种花家 修订: 种花家 来源: 原创 2023-10-10 我要说两句(0)

写爬虫的时候不想用和nginx已配置好的环境用php来跑命令行脚本, 需要安装一个和nginx apache之类的中间件没有瓜葛的独立php引擎, 专门用来跑脚本的。

首先从php.net下载一个php源码包, yum安装一下相关联的依赖:

依赖安装

自动安装的依赖根据系统类型不同, 命令也不同。

centos下

yum -y install libxml2 libxml2-devel openssl openssl-devel curl-devel libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel libmcrypt-devel pcre-devel

debian/ubuntu的环境下,你需要用到apt-get命令处理一下

apt-get update && apt-get install autoconf libxml2-dev libsqlite3-dev libcurl4-openssl-dev libssl-dev libonig-dev libtidy-dev zlib1g-dev pkg-config libbz2-dev libpng-dev libxslt-dev libzip-dev gcc g++ make m4 lzip

手动编译依赖

# 手动编译安装gmp
wget https://gmplib.org/download/gmp/gmp-6.2.1.tar.lz
lzip -d gmp-6.2.1.tar.lz
tar -xvf gmp-6.2.1.tar
./configure --enable-cxx
make && make install
# 手动编译安装libiconv
wget https://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.17.tar.gz
tar zxvf libiconv-1.17.tar.gz
./configure --prefix=/usr/local/libiconv
make && make install

php 7.3以前的版本, 使用以下命令来编译到/usr/local/php下面:

./configure --prefix=/usr/local/php --exec-prefix=/usr/local/php \
--bindir=/usr/local/php/bin --sbindir=/usr/local/php/sbin --includedir=/usr/local/php/include --libdir=/usr/local/php/lib/php --mandir=/usr/local/php/php/man \
--with-config-file-path=/usr/local/php/etc \
--with-mysql-sock=/var/lib/mysql/mysql.sock \
--with-mcrypt=/usr/include --with-mhash --with-openssl \
--with-mysqli=shared,mysqlnd \
--with-pdo-mysql=shared,mysqlnd \
--with-gd \
--with-zlib \
--enable-zip \
--enable-inline-optimization \
--disable-debug \
--disable-rpath \
--enable-xml \
--enable-bcmath \
--enable-sysvsem \
--enable-mbregex \
--enable-mbstring \
--enable-gd-native-ttf \
--enable-pcntl \
--enable-sockets \
--with-xmlrpc \
--enable-soap \
--without-pear \
--with-gettext \
--enable-session \
--with-curl \
--with-jpeg-dir \
--with-freetype-dir \
--enable-opcache \
--enable-fpm \
--with-fpm-user=nginx \
--with-fpm-group=nginx \
--without-gdbm \
--enable-fileinfo

php7.3或更高版本php(也适用于php8)配置不带php-fpm的编译命令

网上许多东西各种抄,你会去用--enable-shmop或者ldap这种参数去追进编译过程吗, 我学php到现在都不知道shmop是啥玩意。编译这玩意进去不是给自己添堵吗?

当然如果有人自己经常用ldap shmop, 那这是个人才,小弟佩服。

运行configure搞糊涂时需

configure --help

看一下。有些--with的语法已经不管用了, 统统要变成--enable

./configure --prefix=/usr/local/php --with-config-file-path=/usr/local/php/etc \
--with-bz2 --enable-ctype --enable-filter --with-gmp --with-libxml --with-pdo-sqlite --enable-phar \
--enable-exif --enable-session --enable-opcache --with-xsl \
--disable-debug \
--disable-rpath \
--enable-mysqlnd \
--with-mysqli=mysqlnd \
--with-pdo-mysql=mysqlnd \
--with-iconv=/usr/local \
--with-zlib \
--enable-xml \
--enable-bcmath \
--with-curl \
--enable-mbregex \
--enable-mbstring \
--enable-intl \
--enable-gd \
--with-openssl \
--with-mhash \
--enable-pcntl \
--enable-sockets \
--with-zip

如果报找不到iconv错误: 

checking for iconv support... yes
configure: error: Please reinstall the iconv library.

需要将--with-iconv=/usr/local改为--with-iconv

./configure --prefix=/usr/local/php --with-config-file-path=/usr/local/php/etc \
--with-bz2 --enable-ctype --enable-filter --with-gmp --with-libxml --enable-phar \
--enable-exif --enable-session --enable-opcache --with-xsl \
--disable-debug \
--disable-rpath \
--enable-xml \
--enable-bcmath \
--enable-mbregex \
--enable-mbstring \
--enable-intl \
--enable-gd \
--enable-pcntl \
--enable-sockets \
--enable-mysqlnd \
--with-mysqli=mysqlnd \
--with-pdo-mysql=mysqlnd \
--with-iconv \
--with-zlib \
--with-curl \
--with-openssl \
--with-mhash \
--with-zip

小编把openssl改成libressl了, 在libressl手动编译时, 小编通过./configure --prefix=/usr/local/libressl的参数安装到了/usr/local/libressl, 那么就要指定openssl的新目录

将--with-openssl改为--with-openssl=/usr/local/libressl

./configure --prefix=/usr/local/php --with-config-file-path=/usr/local/php/etc \
--disable-debug \
--disable-rpath \
--enable-ctype \
--enable-filter \
--enable-phar \
--enable-exif \
--enable-session \
--enable-opcache \
--enable-mysqlnd \
--enable-mbregex \
--enable-mbstring \
--enable-intl \
--enable-gd \
--enable-xml \
--enable-bcmath \
--enable-pcntl \
--enable-sockets \
--enable-soap \
--with-bz2 \
--with-gmp \
--with-libxml \
--with-xsl \
--with-mysqli=mysqlnd \
--with-pdo-mysql=mysqlnd \
--with-iconv=/usr/local \
--with-zlib \
--with-curl \
--with-openssl=/usr/local/libressl \
--with-mhash \
--with-zip

如果想多搞几个php.ini配置文件拆成几块, 可把这一段参数--with-config-file-path=/usr/local/php/etc换成类似如下的命令

--with-config-file-path=/usr/local/etc/php' '--with-config-file-scan-dir=/usr/local/etc/php/conf.d

第一段还是老样子, 后一段意思是扫描指定目录下方的全部配置文档

如果你不是想要单搞命令行的, 想把fpm搞进去, 请加一段fpm配置进去, 但别忘了事先把用户建立好:

# 建立用户
groupadd www
useradd -g www -s /sbin/nologin www
# 测试用户是否正常
id www
# 下面是在配置php-fpm编译项的时候追加的参数
--enable-fpm --with-fpm-user=www --with-fpm-group=www

上述fpm user和group自己创建的。

还是那句话, 如果编译过程中libiconv报错, 需要将配置参数中的--with-iconv=/usr/local改为--with-iconv

或者, 在make install之前添加一行试试

make ZEND_EXTRA_LIBS='-liconv'

安装php引擎

make && make install

php配置文件处理

接下来把php.ini的推荐配置文件(你可以在php安装包里面找), 拷贝到php配置目录下

cp php.ini-production /usr/local/php/etc/php.ini

如果你已经启用了fpm

cd /usr/local/php/etc
cp php-fpm.conf.default php-fpm.conf
cp ./php-fpm.d/www.conf.default ./php-fpm.d/www.conf

做个软连接

假设你把php安装到了默认的位置/usr/local/php/

ln -s /usr/local/php/bin/php /usr/bin/php

fpm服务配置

创建一个文件, 还是假设你的php被安装到了默认的路径/usr/local/php/

vim /lib/systemd/system/php-fpm.service

我们假设fpm的进程文件放在/var/run/目录下, 把配置放到/usr/local/php/etc/php-fpm.conf文件里

文件内容:

[Unit]
Description=The PHP 8.0 FastCGI Process Manager
Documentation=man:php-fpm8.0(8)
After=network.target
 
[Service]
Type=simple
PIDFile=/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
 
[Install]
WantedBy=multi-user.target

PDO的配置

默认来讲, 官方包默认安装进来的php是没有pdo_mysql功能的, 如果使用针对mysql的pdo一定会报错, 怎么办呢?

首先回到安装源目录, 例如安装源你将其解压到了/root/php-7.0.29目录下, 那么pdo_mysql插件会搁置在/root/php-7.0.29/ext/pdo_mysql这个路径下

再回想你安装的php7路径在哪里? 例如安装到了/usr/local/php7这个路径下, 那么进入到/root/php-7.0.29/ext/pdo_mysql下面:

cd /root/php-7.0.29/ext/pdo_mysql
/usr/local/php7/bin/phpize
./configure --with-php-config=/usr/local/php7/bin/php-config --with-pdo-mysql=share

当然如果你当前系统里面安装了mysql服务, 你可以把上面的share改成mysql的安装路径, 注意, 不是说要你指向mysql的bin目录, 而是安装路径, 例如/usr/local/mysql这样子。

接下来,需要修改php7下面的php.ini文件, 找到下面这一行:

[Pdo_mysql]

在其下方增加一段:

extension=pdo_mysql.so

有的同学就会问了, php.ini在哪里找到的? 因为本例程的实现目标只是拿php7引擎跑脚本, 所以安装后, 官方的make包里肯定是不会给你现成的php.ini的, 随便找个地方拷一份对应版本的配置文件吧,QQ群2702237。

PHP-Redis的配置

见站内文章 https://www.wkwkk.com/articles/44b97536a7fa2d5e.html

遇到的问题以及如何解决

啥玩意, 编译个php还能编译出bug? 没错, 现实就是如此, 既然你选择了php, 不去折腾, 又如何?

5066f8599a957f3304693f62b276a8a8.jpeg

论头秃, php还是蛮保护同行的发量的, 不要怕, 上去一把梭哈!

前提条件, 请你在编译前, 把该准备的库都准备好, 不然可能会报各种奇奇怪怪的错误, 见本文开篇依赖安装

configure: error: iconv does not support errno

先用libiconv 1.14版本打比方(本文顶部是1.17版的)

wget http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.14.tar.gz
tar -zxvf libiconv-1.14.tar.gz
cd libiconv-1.14
./configure --prefix=/usr/local/libiconv
make && make install

编译libiconv 1.14中途失败, 报错:

In file included from progname.c:26:
./stdio.h:1010:1: error: ‘gets’ undeclared here (not in a function); did you mean ‘fgets’?
 _GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");
 ^~~~~~~~~~~~~~~

第一种解决方法是安装libiconv 1.14以上的版本, 如果你非要安装libiconv1.14, 则需要找到其中的一个文件libiconv-1.14/srclib/stdio.in.h这个文件并且编辑它

找到698行代码:

_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");

将之改为:

#if defined(__GLIBC__) && !defined(__UCLIBC__) && !__GLIBC_PREREQ(2, 16)
 _GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");
#endif

已经安了libiconv还报错 error: please reinstall iconv 那就是检测不到libiconv了。何解?

头秃的事情来了。如果有人问小编这个问题, 小编建议: 注意编译选项当中的--with-iconv,考虑换着用以下三种参数挨个尝试:

1、--with-iconv  后面什么路径都不指定

2、--with-iconv=/usr/local

3、--with-iconv=/usr/local/libiconv  或者你安装过的自定义位置

因为根据上文的记述, 你应该已经把libiconv库安装到了/usr/local/libiconv这个路径下了, 编译器逻辑一定会找得到的。如果还是不行,据洋鬼子说, 要在执行configure命令之前先输入命令:

export LDFLAGS="$LDFLAGS -liconv"

参考原文: https://bugs.php.net/bug.php?id=80585

 [2021-01-04 15:06 UTC] tomas at rybarik dot comDescription:
------------
I'm unable to compile PHP 8.0.0 with enabled iconv.
This is output from configure command:
checking for iconv support... yes
checking for iconv... yes
checking if iconv is glibc's... yes
checking if iconv supports errno... no
configure: error: iconv does not support errno

I tried compile PHP 7.4.13 with the same version of iconv (1.16), there everything is OK.
checking for iconv support... yes
checking for iconv... yes
checking if iconv is glibc's... yes
checking if iconv supports errno... yes
checking if iconv supports //IGNORE... no


[2021-03-09 22:47 UTC] guillaume-php at outters dot euTomas, could you please tell us what error is logged in the config.log?

As suggested by cmg, this is a problem of detection; but in my case (FreeBSD 10.2, with "hand"-compiled GNU iconv 1.16 without pkgconfig), the detection program had no problem, rather it was its compile env that lacked a -liconv.

So this could be circumvented by running an:
export LDFLAGS="$LDFLAGS -liconv"
before the configure.

I _think_ that, like you, I had no problem compiling a PHP 7 in the same environment (so this detect failure would be a configure regression); but I cannot be certain.w

我测试过, 有时候行, 有的环境就不行。为了避免不使用容器的兄弟被恶心到,小编通过以下的写法是可以通过配置检查的

--with-iconv

如果还是解决不了你的问题, 那证明php官方下方评论区留下的谣言可能是真的:

ea00146157313d495ae9a1bf432d1236.jpg

他们和libiconv的包管理作者关系没搞好(https://bugs.php.net/bug.php?id=80585) 

2. No package ‘oniguruma’ found

yum install oniguruma-devel

3. No package ‘libzip’ found 或者 Requested ‘libzip >= 0.11’ but version of libzip is 0.10.1

checking for libzip >= 0.11 libzip != 1.3.1 libzip != 1.7.0... no
configure: error: Package requirements (libzip >= 0.11 libzip != 1.3.1 libzip != 1.7.0) were not met:
Requested 'libzip >= 0.11' but version of libzip is 0.10.1

这个报错提示非常明显,配置程序没有找到 libzip 库或者找到了但是版本低于 0.11,你用 yum 安装 libzip-devel 的话,安装的版本是 0.10,版本达不到要求。所以,我们需要卸载掉 yum 安装的 libzip 然后手动安装新版。

yum remove libzip libzip-develwget https://libzip.org/download/libzip-1.2.0.tar.gz
tar -zxvf libzip-1.2.0.tar.gz
cd libzip-1.2.0
./configure
make && make install

安装php7提示 configure: error: Cannot find OpenSSL's libraries

解决方法:

#find / -name "libssl.so"
#如果找到路径为/usr/lib/x86_64-linux-gnu/libssl.so 则输入以下命令
ln -s /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib

error: off_t undefined; check your library configuration

vim /etc/ld.so.conf

添加如下几行

/usr/local/lib64
/usr/local/lib
/usr/lib
/usr/lib64

保存退出:wq

使之生效

ldconfig -v

提示 configure: error: Cannot find ldap libraries in /usr/lib

解决办法:

cp -frp /usr/lib64/libldap* /usr/lib/

提示Package 'oniguruma', required by 'virtual:world', not found

解决办法:

# 安装依赖
[root@lnmp ~]# yum install autoconf automake libtool -y
# 拉取github包
[root@lnmp ~]# wget https://github.com/kkos/oniguruma/archive/v6.9.4.tar.gz -O oniguruma-6.9.4.tar.gz
[root@lnmp ~]# tar xf oniguruma-6.9.4.tar.gz
[root@lnmp ~]# cd oniguruma-6.9.4/
[root@lnmp oniguruma-6.9.4]# ./autogen.sh && ./configure --prefix=/usr
[root@lnmp oniguruma-6.9.4]# make && make install

configure: error: GNU MP Library version 4.2 or greater required.

gmp4.2以上的库找不到。现在已经出到6.2.1了。

在网上下载一个gmp的库, 下载:

wget https://gmplib.org/download/gmp/gmp-6.2.1.tar.lz

安装基本支持m4和lzip, 因为你要解包源码

apt-get install m4 lzip
lzip -d gmp-6.2.1.tar.lz
tar -xvf gmp-6.2.1.tar

找不到freetype2: ackage 'freetype2', required by 'virtual:world', not found

报错信息如下:

checking for freetype2... no
configure: error: Package requirements (freetype2) were not met:

Package 'freetype2', required by 'virtual:world', not found

Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.

Alternatively, you may set the environment variables FREETYPE2_CFLAGS
and FREETYPE2_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.

如果你需要编译带freetype支持的gd库,那么你需要先安装一下:

apt-get install libfreetype-dev

然后在配置php环境的时候指定参数:

--with-freetype

OK, 接着搞就ok了。这你都不会那你可就要学了,兄弟。

gd库已启用, 但不支持jpeg压缩处理, 显示imagecreatefromjpeg函数未定义

一般开发的时候发现是报以下错误

Call to undefined function imagecreatefromjpeg()

使用php --ri gd命令发现gd是已经启用的, 但gd里面没有支持jpeg的说法。怎么办?首先这种情况下, 你需要重新编译php

请在debian/ubuntu系统命令里输入(有可能需要sudo)

apt-get update && apt-get install libjpeg-dev

centos系统里

yum install libjpeg-devel

重启fpm

php7.3以上编译过程中内存不足

通过增加swap分区文件的方式解决1G内存小主机无法通过编译的问题:

1、检查当前的分区情况(使用free -m或cat /proc/swaps ):

[root@db2 root]# free -m
             total       used       free     shared    buffers     cached
Mem:          1006         84        922          0         11         38
-/+ buffers/cache:         35        971
Swap:            0          0          0

2、增加交换分区文件及大小:

检查没有swap,下面就需要增加:

判定新交换文件的大小,将大小乘以1024来判定块的大小。例如,大小为64MB的交换文件的块大小为65536,在 shell 提示下以根用户身份键入以下命令,其中的 count 等于想要的块大小。

[root@db2 root]# dd if=/dev/zero of=/home/swap bs=1024 count=1024000
1024000+0 records in
1024000+0 records out

使用以下命令来设置交换文件:

[root@db2 root]# mkswap /home/swap
Setting up swapspace version 1, size = 1023996 KiB
[root@db2 root]#

3、启用交换分区文件:

要立即启用交换文件而不是在引导时自动启用,使用以下命令:

[root@db2 root]# swapon /home/swap

检查增加后的交换情况:

[root@db2 root]# free -m
             total       used       free     shared    buffers     cached
Mem:          1006        994         12          0          4        929
-/+ buffers/cache:         60        946
Swap:          999          0        999
[root@db2 root]#

要在引导时启用,编辑 /etc/fstab 文件来包含以下行

(/home/swap               swap                    swap    defaults        0 0 ):

[root@db2 root]# vi /etc/fstab
LABEL=/                 /                       ext3    defaults        1 1
LABEL=/boot             /boot                   ext2    defaults        1 2      /home/swap               swap                    swap    defaults        0 0
       none                    /dev/pts                devpts  gid=5,mode=620  0 0
       none                    /proc                   proc    defaults        0 0
       none                    /dev/shm                tmpfs   defaults        0 0
       LABEL=/usr              /usr                    ext3    defaults        1 2
       /dev/sda5               swap                    swap    defaults        0 0
       /dev/cdrom              /mnt/cdrom              iso9660 noauto,owner,kudzu,ro 0 0
       /dev/fd0                /mnt/floppy             auto    noauto,owner,kudzu 0 0
       /home/swap               swap                    swap    defaults        0 0

系统下次引导时,它就会启用新建的交换文件

再次检查添加后的情况:

[root@db2 oracledb]# free -m
                    total       used       free     shared    buffers     cached
       Mem:          1006        979         27          0          6        917
       -/+ buffers/cache:         54        952
       Swap:          999          0        999
[root@db2 oracledb]#

关于减少docker镜像体积之编译后清理无用库

目前韩天峰发布的swoole-cli, 本人还是处于观望状态。

如果是把如此大规模的编译成果, 连同关联的lib都塞进容器里显然是很大的, 这就涉及到了容器编排,说来话长,如果只是想简单粗暴本地交付一下单镜像呢? 这里拿debian/ubuntu的镜像举例:

apt autoremove pkg-config make cmake g++ gcc wget manpages m4 ca-certificates
apt clean

以上命令只是粗暴地删除,有一些成对出现的同名库,名字后面多一个-dev/-devel的是开发库,可以删掉,只保留一个。个别插件的开发库没办法删除。删了php就会报错。

另外把/usr/share/doc和/var/log下的日志和文档删干净

节约点硬盘, php小版本升级需要重新编译的时候再拉。

opcache没有启动

小编发现明明在配置文件php.ini里已经写好了

enable.opache = 1

但实际检查没有启用opcache呢?

原来是少了个配置

zend_extension="opache.so"

另外建议加上opcache的jit配置

opcache.jit = 1255
opcache.jit_buffer_size = 256M

如果已经在用swoole代替php-fpm了还需要用opcache吗?

答案是不用。

网上有公子哥说opcache+jit生命周期300秒的php-fpm和swoole性能差不多。可能这位小哥没实现到数据库连接池,或者没开swoole协程特性。

阅完此文,您的感想如何?
  • 有用

    8

  • 没用

    0

  • 开心

    1

  • 愤怒

    0

  • 可怜

    0

1.如文章侵犯了您的版权,请发邮件通知本站,该文章将在24小时内删除;
2.本站标注原创的文章,转发时烦请注明来源;
3.交流群: PHP+JS聊天群

相关课文
  • mac开发接入微信公众号接口返回报错 cURL error 56: SSLRead() return error -9806

  • pecl安装程序时报错Array and string offset access syntax with curly braces is no longer supported

  • PHP的换行符是什么

  • 由于商家传入的H5交易参数有误,该笔交易暂时无法完成,请联系商家解决

我要说说
网上宾友点评
沙发已空