對接支付接口(如財付通、微信支付、支付寶)時,PHP cURL 請求 HTTPS 接口失敗,而 HTTP 正常,經典報錯:
cURL error 60: SSL certificate problem: unable to get local issuer certificate
cURL error 77: error setting certificate verify locations
cURL error 35: OpenSSL SSL_connect: SSL_ERROR_SYSCALL
PHP cURL 依賴 OpenSSL 庫進行 SSL/TLS 握手。若 PHP 編譯時未正確鏈接 OpenSSL,或 OpenSSL 版本過舊、CA 證書缺失、路徑錯誤,就會導致 HTTPS 請求失敗。
# 下載最新穩定版
wget https://www.openssl.org/source/openssl-3.0.13.tar.gz
tar xzf openssl-3.0.13.tar.gz
cd openssl-3.0.13
# 編譯安裝到自定義目錄
./config --prefix=/usr/local/openssl-3.0 shared zlib-dynamic
make -j$(nproc)
make install
# 更新動態鏈接庫緩存
echo "/usr/local/openssl-3.0/lib" > /etc/ld.so.conf.d/openssl.conf
ldconfig
cd /path/to/php-src
# 清理舊編譯
make clean 2>/dev/null; make distclean 2>/dev/null
# 配置(根據實際需求調整其他參數)
./configure \
--prefix=/usr/local/php-8.2 \
--with-openssl=/usr/local/openssl-3.0 \
--with-curl \
--enable-fpm \
--with-mysqli=mysqlnd \
--with-pdo-mysql=mysqlnd \
# ... 其他參數
make -j$(nproc)
make install
/usr/local/php-8.2/bin/php -i | grep -i "openssl.*support"
# 輸出應包含:OpenSSL support => enabled
# OpenSSL Library Version => OpenSSL 3.0.13 ...
# 測試 HTTPS 請求
/usr/local/php-8.2/bin/php -r '
$ch = curl_init("https://www.alipay.com");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
$result = curl_exec($ch);
echo curl_error($ch) ?: "HTTPS 請求成功,長度: " . strlen($result);
curl_close($ch);
'
若不想重編譯 PHP,可下載 Mozilla CA 證書束,配置 curl.cainfo 和 openssl.cafile:
# 1. 下載最新 CA 證書
wget -O /etc/ssl/certs/cacert.pem https://curl.se/ca/cacert.pem
# 2. 修改 php.ini
curl.cainfo = /etc/ssl/certs/cacert.pem
openssl.cafile = /etc/ssl/certs/cacert.pem
# 3. 重啟 PHP-FPM
systemctl restart php-fpm
某些系統缺少 libmcrypt、mhash、mcrypt 也會間接影響 OpenSSL 功能(特別是老版本 PHP):
# CentOS/RHEL
yum install -y libmcrypt-devel mhash-devel mcrypt-devel
# Ubuntu/Debian
apt-get install -y libmcrypt-dev libmhash-dev libmcrypt-dev
# 然後重新編譯 PHP 並加入 --with-mcrypt --with-mhash
| 現象 | 可能原因 | 排查命令 |
|---|---|---|
| cURL error 60 | CA 證書缺失或路徑錯誤 | php -i | grep -E "curl.cainfo|openssl.cafile" |
| cURL error 77 | OpenSSL 庫版本不匹配 / 未正確鏈接 | php -i | grep "OpenSSL Library Version" |
| cURL error 35 | TLS 版本不支持 / 握手失敗 | curl -v https://example.com --tlsv1.2 |
| PHP 啟動警告 OpenSSL | 編譯時 --with-openssl 路徑錯誤 | ldd /usr/local/php/bin/php | grep ssl |
yum install php php-openssl php-curl 或 apt install php8.2-openssl php8.2-curl,自動處理依賴與安全更新。yum update ca-certificates / apt update ca-certificates。CURLOPT_SSL_VERIFYPEER => false,這會導致中間人攻擊風險。PHP cURL 無法訪問 HTTPS 90% 以上是 OpenSSL 配置問題。重新編譯 PHP 指定正確 OpenSSL 路徑是徹底方案;配置 cacert.pem 是快速臨時方案。建議採用系統包管理器維護 PHP 環境,避免手動編譯帶來的依賴地獄。