PHP HTTPS 请求失败主因是环境缺失或配置错位,需检查 OpenSSL/cURL 扩展启用、证书路径正确及 CA 证书链有效,禁用证书验证仅限临时调试。
PHP 默认支持 HTTPS 请求,但前提是底层 cURL 或 OpenSSL 扩展已正确编译并链接到可用的 OpenSSL 库,且运行时能加载可信 CA 证书链。问题往往不出在 PHP 代码本身(比如 file_get_contents('https://...') 或 curl_exec()),而在于环境缺失或配置错位。
检查 PHP 是否已启用 OpenSSL 和 cURL 支持
直接运行 php -m | grep -E '^(openssl|curl)$'。若无输出,说明对应扩展未启用;若只有 curl 没有 openssl,cURL 可能是用系统自带的 NSS 或 GnuTLS 编译的,不支持标准 PEM 证书路径,也无法验证 HTTPS 证书链。
- 确认
extension=openssl在php.ini中未被注释,且extension_dir指向正确的 .so/.dll 路径 - 运行
php -r "print_r(openssl_get_cert_locations());"查看 PHP 认为的默认证书路径 —— 这个路径必须存在且包含有效的 CA bundle(如ca-bundle.crt或ca-certificates.crt) - 如果输出中
default_cert_file是空或指向不存在的文件,后续 HTTPS 请求会因“unable to get local issuer certificate”失败
重新编译 PHP 以链接自建 OpenSSL(非必要勿动)
仅当系统 OpenSSL 版本过旧(如 CentOS 7 默认 1.0.2)、或需启用 FIPS/国密等特殊特性时,才需手动编译 OpenSSL 并让 PHP 链接它。多数现代发行版(Ubuntu 22.04+、CentOS 8+)自带的 OpenSSL 1.1.1+ 已足够安全且兼容 PHP 7.4+ / 8.x。
- 编译 OpenSSL 时加
--prefix=/usr/local/openssl,安装后确保/usr/local/openssl/bin/openssl version可执行 - 编译 PHP 时指定
--with-openssl=/usr/local/openssl,而非--with-openssl-dir(后者已被弃用) - 编译后运行
ldd $(php-config --extension-dir)/openssl.so | grep ssl,确认链接的是你刚装的 OpenSSL 库,而非系统旧版 - 注意:PHP 8.2+ 不再支持 OpenSSL 1.0.x,强行链接会导致启动报错
undefined symbol: OPENSSL_sk_num
正确配置 CA 证书链(最常出问题的环节)
PHP 不读取系统级的 /etc/ssl/certs/ca-certificates.crt(除非你显式设置),也不自动从 curl.cainfo 或 openssl.cafile 加载 —— 它只认自己编译时硬编码的路径,或运行时通过 ini 配置覆盖。