CURLOPT_SSL_VERIFYHOST 必须设为2且与CURLOPT_SSL_VERIFYPEER=true配合使用,指定绝对路径CA证书;Laravel HTTP客户端默认启用完整TLS校验,推荐优先使用。

在 Laravel 10 中使用 cURL(比如通过 curl_init() 手动发起请求)时,CURLOPT_SSL_VERIFYHOST 是 libcurl 的底层选项,PHP 的 cURL 扩展直接支持它。但要注意:Laravel 本身不封装或管理这个选项,你需要在调用原生 cURL 函数时显式设置。
关键点是:CURLOPT_SSL_VERIFYHOST 必须与 CURLOPT_SSL_VERIFYPEER 配合使用,且取值逻辑固定——只接受 2(推荐且唯一有效值),1 已被弃用,0 表示关闭校验(不安全)。
如何正确设置 CURLOPT_SSL_VERIFYHOST
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.example.com');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// ✅ 必须同时开启证书链验证
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
// ✅ 主机名校验必须设为 2(严格匹配 SAN 或 CN)
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
// ✅ 指定可信 CA 证书路径(否则 VERIFYPEER 会失败)
curl_setopt($ch, CURLOPT_CAINFO, __DIR__ . '/certs/cacert.pem');
$response = curl_exec($ch);
if ($response === false) {
throw new RuntimeException('cURL error: ' . curl_error($ch));
}
curl_close($ch);常见错误与避坑提示
不要设为
1CURLOPT_SSL_VERIFYHOST => 1在现代 libcurl(≥7.28.0)中已无效,会被静默降级为0,失去主机名校验能力。不能只开 VERIFYHOST、不开 VERIFYPEER
即使VERIFYHOST=2,若VERIFYPEER=false,libcurl 会跳过整个证书验证流程,主机名比对无意义。CA 证书路径必须是绝对路径
CURLOPT_CAINFO不接受相对路径或./certs/xxx.pem。建议用realpath(__DIR__ . '/certs/cacert.pem')确保可靠。-
开发环境临时绕过?谨慎对待
若对接本地自签名服务(如https://localhost:8001),可临时设:curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
但仅限调试,生产环境禁止。更安全的做法是把自签名证书加入
cacert.pem。
Laravel 中的替代方案(推荐)
如果你不是必须手写 cURL,建议优先使用 Laravel 自带的 HTTP 客户端,它默认启用完整 TLS 校验:
use Illuminate\Support\Facades\Http;
$response = Http::get('https://api.example.com');它底层自动设置:
CURLOPT_SSL_VERIFYPEER = trueCURLOPT_SSL_VERIFYHOST = 2- 并尝试加载系统 CA 包(Linux/macOS)或 fallback 到内置证书(Windows)
如需自定义 CA 路径,可用:
Http::withOptions([
'verify' => __DIR__ . '/certs/cacert.pem',
])->get('https://api.example.com');verify => true(默认)即启用校验;verify => false 才禁用。
不复杂但容易忽略。


















