首先从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, 不去折腾, 又如何?
论头秃, 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协程特性。