首先從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, 不去折騰, 又如何?
論頭禿, 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官方下方評論區留下的謠言可能是真的:
他們和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協程特性。