curl_exec() 总是返回 false

149

我写了这个简单的代码片段:

$ch = curl_init();

//Set options
curl_setopt($ch, CURLOPT_URL, "http://www.php.net");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$website_content = curl_exec ($ch);
在我的情况中,$website_content 的值是 false。有人能够建议或者提供一些可能出错的原因吗?

12
请查看curl_error()获取错误详情,并在此处发布。 - Linus Kleen
@LinusKleen 如果您将curl_error()发布为答案,我会点赞,因为它让我看到了我的问题所在。 - Giles Roberts
问题到底是什么?curl_error()显示了什么错误? - showdev
3个回答

300

错误检查和处理是程序员的朋友。检查初始化和执行cURL函数的返回值。curl_error()curl_errno() 在失败的情况下将包含更多信息:

try {
    $ch = curl_init();

    // Check if initialization had gone wrong*    
    if ($ch === false) {
        throw new Exception('failed to initialize');
    }

    // Better to explicitly set URL
    curl_setopt($ch, CURLOPT_URL, 'http://example.com/');
    // That needs to be set; content will spill to STDOUT otherwise
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    // Set more options
    curl_setopt(/* ... */);
    
    $content = curl_exec($ch);

    // Check the return value of curl_exec(), too
    if ($content === false) {
        throw new Exception(curl_error($ch), curl_errno($ch));
    }

    // Check HTTP return code, too; might be something else than 200
    $httpReturnCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

    /* Process $content here */

} catch(Exception $e) {

    trigger_error(sprintf(
        'Curl failed with error #%d: %s',
        $e->getCode(), $e->getMessage()),
        E_USER_ERROR);

} finally {
    // Close curl handle unless it failed to initialize
    if (is_resource($ch)) {
        curl_close($ch);
    }
}

* curl_init()函数的手册中指出:

成功时返回cURL句柄,出错时返回FALSE

我观察到当你使用$url参数并且无法解析域名时,该函数会返回FALSE。如果未使用该参数,则该函数可能永远不会返回FALSE。不过,由于手册没有明确说明“错误”是什么,请始终进行检查。


10
在PHP中,当curl_exec返回FALSE时,简单而直接的解决方案是进行故障排除。可以使用Curl Verbose Mode在PHP中打印更多详细信息,以下链接提供了示例:Curl Verbose Mode in PHP example - hakre
请执行 curl_close($ch); 并关闭连接。 - Rafik Bari
在我的情况下,我在调用curl_exec()之前调用了curl_close()。这个答案让我明白了,在多次检查代码后。 - Valkay
@Valkay 关闭之前执行完毕?你是否在循环中运行该代码? - Linus Kleen
1
在我的情况下,错误与HTTP 2.0有关 - HTTP/2流未干净地关闭:PROTOCOL_ERROR(err 1)。 cURL突然停止工作,我不知道为什么 - 在我的端点上没有任何更改,也没有在远程端点上进行更改。使用curl_error($ch)有助于调试。 - FiddlingAway
显示剩余3条评论

42

在我的情况下,我需要将VERIFYHOSTVERIFYPEER设置为false,如下所示:

curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);

在调用curl_exec($ch)之前。

因为我在两个开发环境之间工作,这些环境使用了自签名证书。如果有有效的证书,则无需将VERIFYHOSTVERIFYPEER设置为false,因为curl_exec($ch)方法会正常工作并返回您期望的响应。


1
你是一个救星。 - rootleet
你帮我省下了15个小时的眼泪。 - James Bondze

3
昨天我遇到了这个问题,我的情况是因为我在按照PDF手册开发与API通信的模块时,直接从手册中复制链接,但由于某种奇怪的原因,被复制的链接中的连字符使用了不同的编码方式,因此curl_exec()一直返回false,因为它无法与服务器通信。
花了几个小时才终于理解以下字符之间的差异:
https://www.e‐example.com/api
https://www.e-example.com/api

每次我直接从浏览器访问链接,它都会转换成像https://www.xn--eexample-0m3d.com/api这样的东西。可能看起来它们是相等的,但是如果你在这里检查“连字符”的编码,你会看到第一个“连字符”是一个Unicode字符U+2010,而另一个则是U+002D。希望这可以帮助某些人。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接