源码编译php必须预装系统依赖:ubuntu需build-essential等,centos需development tools及oniguruma-devel、libzip-devel等;--prefix与--with-config-file-path等参数须配对设置;php-fpm启动失败多因路径权限、端口占用或缺失systemd服务文件;extension加载失败需检查extension_dir路径、格式及依赖。

PHP 源码编译安装:哪些依赖不装就直接报错
源码编译 PHP 不是复制粘贴命令就能跑起来的事。缺一个开发包,./configure 就会停在“checking for xxx… not found”,甚至不报具体错误,只显示 configure: error: Please reinstall the libxxx development package。
常见必须提前装的系统级依赖(以 Ubuntu/Debian 和 CentOS/RHEL 为例):
- Ubuntu:
sudo apt install build-essential autoconf bison re2c libxml2-dev libsqlite3-dev libonig-dev libcurl4-openssl-dev libfreetype6-dev libjpeg-dev libpng-dev libwebp-dev libzip-dev - CentOS:
sudo yum groupinstall "Development Tools"+sudo yum install autoconf bison re2c sqlite-devel oniguruma-devel libxml2-devel curl-devel freetype-devel libjpeg-devel libpng-devel libwebp-devel libzip-devel
libonig-dev(或 oniguruma-devel)最容易被漏掉——PHP 7.3+ 默认用 Oniguruma 替代旧版 regex 库,没它连 configure 都过不去;libzip-dev 缺失会导致 zip 扩展编译失败,但 configure 可能不报错,直到运行时抛出 Class 'ZipArchive' not found。
configure 参数怎么选:--prefix 和 --with-config-file-* 的实际影响
--prefix 决定整个 PHP 安装路径,不是随便指定的。一旦设成 /usr/local/php84,后续所有扩展、配置、二进制文件都按这个根目录组织。改错位置,php -v 可能找得到,但 php-fpm 启动时读不到 php.ini,或者 extension_dir 指向不存在的目录。
立即学习“PHP免费学习笔记(深入)”;
关键配置路径参数必须配对使用:
-
--with-config-file-path=/usr/local/php84/etc:指定php.ini主配置文件所在目录(注意是目录,不是文件路径) -
--with-config-file-scan-dir=/usr/local/php84/etc/conf.d:指定额外加载的 ini 片段目录,比如 opcache、redis 扩展的独立配置
如果只设 --with-config-file-path 却没手动创建该目录并放好 php.ini,PHP 会静默回退到内置默认配置(相当于没配),而你完全看不出异常——直到发现 memory_limit 没生效、date.timezone 报 Warning: Unknown: It is not safe to rely on the system's timezone settings。
make install 后 php-fpm 启动失败的三个高频原因
编译安装完,make install 成功不代表服务能跑。最常卡在 php-fpm 启动阶段,现象通常是 systemctl start php-fpm 无响应,或日志里反复出现 ERROR: unable to bind listening socket for address '127.0.0.1:9000': Address already in use 或更隐蔽的 ERROR: failed to post process the configuration。
检查顺序建议:
- 确认
php-fpm.conf里pid和error_log路径的父目录存在且权限可写(比如/usr/local/php84/var/run和/usr/local/php84/var/log) - 检查
www.conf中listen地址是否被占用,或权限不对(Unix socket 模式下,listen.owner/listen.group必须匹配运行用户,否则 Nginx 连不上) - 运行
/usr/local/php84/sbin/php-fpm -t测试配置语法,它比 systemctl 启动反馈更快、错误更直白
特别注意:php-fpm 默认不自带 init script 或 systemd unit 文件,得自己写或从源码 sapi/fpm/php-fpm.service.in 复制修改,漏这步,systemctl enable php-fpm 会报 Failed to enable unit: Unit file php-fpm.service does not exist。
php.ini 里 extension=xxx.so 加载失败的定位方法
写进 php.ini 的 extension=redis.so 不生效?别急着重装扩展。先执行 php -m | grep redis 看是否列出来;没列,再用 php --ini 确认当前加载的是哪个 php.ini,然后检查三件事:
-
extension_dir值是否指向真实存在的目录(如/usr/local/php84/lib/php/extensions/no-debug-zts-20220829/),且该目录下真有redis.so -
extension=redis.so这行前面不能有空格,也不能写成extension = redis.so(等号两边有空格在某些 PHP 版本会解析失败) - 扩展是否依赖其他 so(比如
redis.so依赖igbinary.so),如果依赖项没加载,redis 也会静默失败
最省事的验证方式:php -d extension=redis.so -m | grep redis。如果这条能出来,说明扩展本身没问题,问题一定出在 php.ini 路径、extension_dir 或加载顺序上。
源码安装的 PHP,每个版本的 extension_dir 路径名都带编译时的时间戳(如 no-debug-zts-20220829),换 PHP 小版本就得重新核对,这点很容易被忽略——尤其当你同时维护多个 PHP 版本时。











