You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP7.4依赖双版本libssl,咨询ld.so同名符号处理行为

在AlmaLinux 9编译带PostgreSQL支持的PHP 7.4:OpenSSL版本符号冲突疑问

背景

我需要在AlmaLinux 9上编译带有PostgreSQL模块支持的PHP 7.4。由于mysql-devel依赖系统的openssl-devel(3.0版本)RPM包,但PHP 7.4无法与OpenSSL 3.x编译兼容,因此我从源码编译了OpenSSL 1.1.x并安装到默认前缀路径/usr/local。

编译步骤

通过以下命令完成了PHP 7.4的编译:

$ cd php-7.4.33
$ ./configure PKG_CONFIG_PATH='/usr/local/lib64/pkgconfig:/usr/lib64/pkgconfig' OPENSSL_LIBS="-L/usr/local/lib64/ -lssl -lcrypto" --with-apxs2 --with-pgsql --with-external-pcre --enable-mbstring --sysconfdir=/etc --with-config-file-path=/etc --enable-pdo --with-pdo-pgsql --with-zlib --with-zip --with-jpeg --with-pear --with-curl --enable-opcache --with-openssl --with-freetype --with-xpm --with-libdir=lib64 --with-ldap --with-mysqli --with-pdo-mysql --enable-soap --enable-gd --without-sqlite3 --without-pdo-sqlite --with-curl
$ make -j $(nproc)

编译警告

编译过程中出现如下警告:

/usr/bin/ld: ext/openssl/.libs/openssl.o: in function `php_openssl_load_cipher_mode':
php-7.4.33/ext/openssl/openssl.c:6499: undefined reference to `EVP_CIPHER_flags'

依赖冲突现状

问题核心在于系统的libpq.so依赖libssl.so.3,而编译后的PHP依赖libssl.so.1.1,导致ld.so需要同时加载两个版本的OpenSSL库:

$ ldd sapi/cli/php | egrep "ssl|crypto|pq"
        libpq.so.5 => /lib64/libpq.so.5
        libssl.so.1.1 => /usr/local/lib64/libssl.so.1.1
        libcrypto.so.1.1 => /usr/local/lib64/libcrypto.so.1.1
        libssl.so.3 => /lib64/libssl.so.3
        libcrypto.so.3 => /lib64/libcrypto.so.3
$ ldd /usr/lib64/libpq.so
        libssl.so.3 => /lib64/libssl.so.3
        libcrypto.so.3 => /lib64/libcrypto.so.3

疑问

当libssl.so.1.1和libssl.so.3中存在同名符号时,ld.so会如何处理?目前php-cli看似运行正常,但我尚未测试PostgreSQL连接功能。


解答

  1. 符号解析优先级规则
    ld.so(动态链接器)会按照库的加载顺序解析符号:
  • 先加载直接链接到PHP二进制的库(即libssl.so.1.1、libcrypto.so.1.1),这些库的符号会被优先注册到全局符号表。
  • 后续加载libpq.so及其依赖的libssl.so.3时,若遇到同名符号,动态链接器会直接使用已注册的全局符号(来自OpenSSL 1.1.x),不会加载OpenSSL 3.x中的同名符号。
  1. 潜在风险
    这种场景存在严重稳定性隐患:
  • libpq.so是基于OpenSSL 3.x编译的,它调用的符号行为与OpenSSL 1.1.x的同名符号可能存在差异(比如参数结构、返回值、内部逻辑变化)。强行用1.1.x的符号替代3.x的符号,极易导致libpq在运行时崩溃、出现内存错误或逻辑异常,尤其是在PostgreSQL SSL连接这类加密操作中。
  • 你遇到的编译警告undefined reference to EVP_CIPHER_flags已经是信号:PHP 7.4的OpenSSL扩展依赖的符号在OpenSSL 3.x中已被移除/重命名,两者符号集不兼容。
  1. 解决方案建议
  • 编译独立libpq库:从PostgreSQL源码编译,指定链接到你安装的OpenSSL 1.1.x,替换系统默认的libpq.so,确保PHP和libpq依赖同一版本OpenSSL。
  • 调整PHP编译参数:编译PHP时,用--with-pgsql指定自己编译的PostgreSQL库路径,避免链接系统的libpq.so。
  • 容器隔离环境:使用Docker等容器工具,基于兼容PHP 7.4的基础镜像(如CentOS 8、旧版AlmaLinux)构建环境,从根源规避OpenSSL版本冲突。

内容的提问来源于stack exchange,提问作者lp64

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 07:05:41