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 协议》,转载必须注明作者和本文链接
本帖由系统于 2年前 自动加精
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 8
superwen

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

2年前 评论

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

2年前 评论
superwen

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

2年前 评论

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

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

2年前 评论

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

2年前 评论

关闭 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 的问题吗?

2年前 评论

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

这个函数不会抛出异常吧

2年前 评论

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

要看其报错,从 curl_errno 获得。

2年前 评论

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

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

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

2年前 评论

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