linux下安裝php7或php8 以及編譯時各種故障bug排除

字號+ 編輯: 种花家 修訂: 种花家 來源: 原创 2025-04-16 我要說兩句(1)

寫爬蟲的時候不想用和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

(Debian/Ubuntu可選)用gcc12代替操作默認的編譯器依賴

apt-get update && apt-get install wget autoconf gcc-12 g++-12 openssl 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 make m4 lzip libc-ares-dev libbrotli-dev libmpfr-dev libgmp-dev
update-alternatives --install /usr/bin/cc cc   /usr/bin/gcc-12 100
update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++-12 100
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 100
update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-12 100

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到現在, 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協程特性。

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

    917

  • 沒用

    32

  • 開心

    14

  • 憤怒

    6

  • 可憐

    8

1.如文章侵犯了您的版權,請發郵件通知本站,該文章將在24小時内刪除;
2.本站標注原創的文章,轉發時煩請注明來源;
3.交流群: 2702237 13835667

相關課文
  • mac開發接入微信公衆號接口返回報錯 cURL error 56: SSLRead() return error -9806

  • PHP的換行符是什麽

  • pecl安裝程序時報錯Array and string offset access syntax with curly braces is no longer supported

  • 由於商家傳入的H5交易參數有誤,該筆交易暫時無法完成,請聯繫商家解決

我要說說
網上賓友點評
1 樓 IP 136.48.***.5 的嘉賓 说道 : 1个月前
麻烦的要死