curl 用完千万别忘 close !

正常的一天,忙碌的一天,只是,应用中某个 api 频繁报 502 。
这个神奇了,查代码,一路查,最后竟然是一个 curl 错误了导致的,于是开始检查 curl 的代码。
一般的 curl 大概是这样

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$content = curl_exec($ch);
curl_close($ch);
return $content;

看起来一切正常呀。

经过各种尝试,各种断点各种参数各种记日志各种折腾都无果。

然后。。。

睡了一觉想起来了。于是。。

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
try{
    $content = curl_exec($ch);
} finally{
    curl_close($ch);
}

好了。

总结,无论何时,记得关闭curl,不是简单在地 curl_exec 后 curl_close ,记得 try finally 。
那些看到标题没点进来的朋友,嗯,祝你们好运。

本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 5年前 自动加精
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 8
superwen

我觉得标题应该改为 《用完curl你正确close了吗》

6年前 评论

curl_exec执行报错,导致curl_close没有执行,需要通过try来捕捉错误吧。

6年前 评论
superwen

我觉得标题应该改为 《用完curl你正确close了吗》

6年前 评论

可以告知下更详细的架构吗,比如是FPM?还是用SWOOLE?

我过往的使用PHP CURL的时候,调研过CURL细节处理上,即使不CURL_CLOSE,在shutdown之前PHP也会自动curl_close在销毁链接句柄的

6年前 评论

@NicolaBonelli 目前的环境是 nginx + php-fpm 。

5年前 评论

关闭 curl 句柄,加不加 finally 从你这代码看应该没区别。如果是捕获 curl 的错误,最好用 curl_errno/curl_error,比如:

curl_exec($ch);
if(curl_errno($ch)) {
    echo 'Curl error: ' . curl_error($ch);
}
curl_close($ch);

另外,我怀疑你确定是 try catch finally 的问题吗?

5年前 评论

成功时返回 TRUE, 或者在失败时返回 FALSE。 然而,如果 设置了 CURLOPT_RETURNTRANSFER 选项,函数执行成功时会返回执行的结果,失败时返回 FALSE 。文档

这个函数不会抛出异常吧

5年前 评论

这个函数不会抛出异常,所以 catch 不着东西。

要看其报错,从 curl_errno 获得。

5年前 评论

直接用 curl_error()curl_errno() 看看?

标题应该改为 《用完 curl 你正确 close 了吗》

只能说, 好好说话, 别作 ==, 随便搞个帖子都是这种标题党, 审美疲劳了

5年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!