简体   繁体   English

php curl 内存使用情况

[英]php curl memory usage

I have this function that gets the html from a list of pages and once I run it for two hours or so the script interrupts and shows that memory limit has been exceeded, Now i've tried to unset/set to null some variables hopefully to free up some memory but it's the same problem.我有这个函数可以从页面列表中获取 html,一旦我运行它两个小时左右,脚本就会中断并显示已超出内存限制,现在我尝试取消设置/设置为空一些变量,希望能释放一些内存,但这是同样的问题。 Can you guys please take a look at the following piece of code?大家可以看看下面的一段代码吗? :

{
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    if ($proxystatus == 'on'){
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, TRUE);
        curl_setopt($ch, CURLOPT_PROXY, $proxy);
    }
    curl_setopt($ch, CURLOPT_COOKIEFILE, "cookie.txt");
    curl_setopt($ch, CURLOPT_URL, $site);
    ob_start();
    return curl_exec($ch); // the line the script interrupts because of memory
    ob_end_clean();
    curl_close($ch);

    ob_flush();
    $site = null;
    $ch = null;

}

Any suggestion is highly appreciated.任何建议都受到高度赞赏。 I've set the memory limit to 128M, but before increasing it (doesnt seem like the best option to me) I would like to know if there's anything I can do to use less memory/free up memory while running the script.我已将内存限制设置为 128M,但在增加它之前(对我来说似乎不是最好的选择)我想知道在运行脚本时是否有什么可以使用更少的内存/释放内存的方法。

Thank you.谢谢你。

You are indeed leaking memory.你确实在泄漏内存。 Remember that return immediately ends execution of the current function, so all your cleanup (most importantly ob_end_clean() and curl_close() ) is never called.请记住, return立即结束当前函数的执行,因此永远不会调用所有清理(最重要的是ob_end_clean()curl_close() )。

return should be the very last thing the function does. return应该是函数所做的最后一件事。

I know it's been a while, but others might run into a similar issue, so in case it helps anyone else... To me the problem here is that curl is set to save the output to a string.我知道已经有一段时间了,但其他人可能会遇到类似的问题,所以如果它可以帮助其他人......对我来说,这里的问题是 curl 设置为将输出保存为字符串。 [That's what happens with curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); [这就是curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); ] If the output gets too long, the script will run out of allowed memory for that string. ] 如果输出太长,脚本将耗尽该字符串允许的内存。 [That returns an error like FATAL ERROR: Allowed memory size of 134217728 bytes exhausted (tried to allocate 130027520 bytes) ] The way around this is to use one of the other output methods offered by curl: output to standard output, or output to file. [返回一个错误,如FATAL ERROR: Allowed memory size of 134217728 bytes exhausted (tried to allocate 130027520 bytes) ] 解决这个问题的方法是使用 curl 提供的其他输出方法之一:输出到标准输出,或输出到文件. In either case, ob-start shouldn't be needed at all.无论哪种情况,都根本不需要 ob-start。

Hence you could replace the content of the braces with either option below:因此,您可以使用以下任一选项替换大括号的内容:

OPTION 1: Output to standard output:选项 1:输出到标准输出:

$ch = curl_init();
if ($proxystatus == 'on'){
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
    curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, TRUE);
    curl_setopt($ch, CURLOPT_PROXY, $proxy);
}
curl_setopt($ch, CURLOPT_COOKIEFILE, "cookie.txt");
curl_setopt($ch, CURLOPT_URL, $site);
curl_exec($ch);
curl_close($ch);

OPTION 2: Output to file:选项 2:输出到文件:

$file = fopen("path_to_file", "w"); //place this outside the braces if you want to output the content of all iterations to the same file
$ch = curl_init();
if ($proxystatus == 'on'){
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
    curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, TRUE);
    curl_setopt($ch, CURLOPT_PROXY, $proxy);
}
curl_setopt($curl, CURLOPT_FILE, $file);    
curl_setopt($ch, CURLOPT_COOKIEFILE, "cookie.txt");
curl_setopt($ch, CURLOPT_URL, $site);
curl_exec($ch);
curl_close($ch);
fclose($file);  //place this outside of the braces if you want to output the content of all iterations to the same file

For sure this is not a cURL issue.当然,这不是 cURL 问题。 Use tools like xdebug to detect which part of your script is consuming memory.使用诸如 xdebug 之类的工具来检测脚本的哪一部分正在消耗内存。

Btw I would also change it not to run for two hours, I will move it to a cronjob that runs everyminute, check what it needs and then stops.顺便说一句,我也会将它更改为不运行两个小时,我会将它移动到每分钟运行一次的 cronjob,检查它需要什么然后停止。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM