【问题标题】:PHP cURL 'Fatal error: Allowed memory size' for large data sets大型数据集的 PHP cURL“致命错误:允许的内存大小”
【发布时间】:2011-04-04 10:44:46
【问题描述】:

我知道设置内部存储器的选项

ini_set("memory_limit","30M");

但我想知道是否有更好的方法来查询数据?

我有一个 WHILE LOOP 来检查我是否需要查询另外 1000 条记录。 使用偏移量作为起始记录编号,使用限制作为返回记录,我搜索与我的数据请求匹配的所有记录。在我收到错误之前,我的记录达到了大约 100K。

现在在测试过程中,我发现我收到“致命错误:允许的内存大小...”错误。我已经通过设置上面的 ini_set() 来增加内存,但我想知道我是否可以更好地编写代码?

每次我在 WHILE LOOP 中执行下面的代码时,内存使用量都会变得非常大。即使我取消设置($ curl)。我认为如果在下一次 cURL 查询之前解析出结果后取消设置 $result 和 $curl 变量,它可能会减少。

function getRequest($url,$user,$pwd) {

    $curl = curl_init();

    curl_setopt($curl, CURLOPT_VERBOSE, 1);
    curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 2);
    curl_setopt($curl, CURLOPT_HEADER, 0);
    curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_USERPWD, "$user:$pwd");
    curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
    curl_setopt($curl, CURLOPT_ENCODING, '');
    curl_setopt($curl, CURLOPT_URL, $url);

    $result = curl_exec($curl);

    $httpResponseCode = (int)curl_getinfo($curl, CURLINFO_HTTP_CODE);

    switch ($httpResponseCode) {
        case 500:
            // Send problem email
            break;
        case 200:
            // GET was good
            break;
        default:
            // Send problem email
            break;
    }    
    curl_close($curl);
    return $result;
} 

WHILE LOOP(精简版)

while($queryFlag) { // $queryFlag is TRUE

        // Check if we have more records to query, if not set $queryFlag to FALSE

        // Build cURL URL

        echo "Before Call Memory Usage: ".memory_get_usage()."\n";
        $resultXML  = getRequest($query,$user,$pass);
        echo "After Call Memory Usage: ".memory_get_usage()."\n";

        $results        = new ParseXMLConfig((string)$resultXML); // This is basically a class for $this->xml = simplexml_load_string($xml);

        // Loop through results and keep what  I'm looking for
        foreach($results as $resultsKey => $resultsData) {
            if(preg_match('|^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$|i', $resultsData)) {
                $resultsArr["$resultsData"] = $resultsData;
            }
        }

    }

一些记忆数字

  • 调用内存使用前:1819736
  • 调用后内存使用情况:2285344
  • 保留我需要的数据
  • 转储我不需要的数据
  • 下一个循环迭代
  • 调用内存使用前:2084128
  • 调用后内存使用情况:2574952

【问题讨论】:

  • 能否也向我们展示一下while循环?
  • 你安装了xdebug吗?它可能会给你一些有用的信息。
  • WHILE LOOP 很好,我在 cURL 之前和 cURL 调用之后执行 memory_get_usage(),这就是内存变得非常大的地方。 while 循环只是检查我们是否需要再次查询。如果记录大于返回的最后 1000 个。解析返回并将所需数据推送到数组中。我检查了数组是否是问题所在,但它非常小,只有一百条记录,每条记录中的数据最少。
  • 我没有安装 xDebug,它不是我的服务器 :(
  • 你的函数看起来不错。循环代码中的某些内容正在占用内存。发布循环代码。

标签: php memory-leaks curl large-data-volumes


【解决方案1】:

你为$resultsArr使用了不正确的。您使用相同的字符串作为键和值。

尝试改变

$resultsArr["$resultsData"] = $resultsData

$resultsArr[$resultsKey] = $resultsData

【讨论】:

    【解决方案2】:

    入驻:

    ini_set("memory_limit","30M");
    

    【讨论】:

      猜你喜欢
      • 2015-04-22
      • 2023-03-20
      • 2017-12-13
      • 2015-09-18
      • 2023-04-03
      • 1970-01-01
      • 2015-02-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多