PHP cURL '致命错误:允许的内存大小'适用于大型数据集

b1payxdu  于 2022-11-13  发布在  PHP
关注(0)|答案(3)|浏览(150)

我知道设置内存的选项

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

但是我想知道是否有更好的方法来查询数据?
我有一个WHILE LOOP,它检查我是否需要查询另外1000条记录。使用偏移量作为起始记录号,使用限制作为返回的记录,我搜索与我的数据请求匹配的所有记录。在我得到错误之前,我在记录中找到了大约100 K。
现在在测试过程中,我发现我得到了“致命错误:允许的内存大小...'错误。我已经阅读了设置上述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
  • 保留所需数据
  • 转储我不需要的数据
  • 下一个LOOP迭代
  • 呼叫前内存使用量:2084128
  • 呼叫后内存使用量:2574952
hvvq6cgz

hvvq6cgz1#

我 * 猜 * 您对$resultsArr使用了不正确 key 您使用了相同字符串作为key和value
试试换

$resultsArr["$resultsData"] = $resultsData

$resultsArr[$resultsKey] = $resultsData
fafcakar

fafcakar2#

结算金额:

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

zpqajqem3#

这是对楼主问题的回应,“我能写得更好吗?"。你问对了问题!很好。
我也遇到过类似的问题,我有一个循环,循环中的一些东西正在消耗内存。我发现,我想,因为我把我想“保留”的数据保存到一个对象(stdClass)中,这就是减慢速度的原因。我把它改成这样,而不是像这样:

$payloadObject->someNewAttribute = $data_i_want_to_keep;

我使用了一个索引数组:

$payload_array[] = $data_i_want_to_keep;

这对我很管用。
我在哪里看到一个测试(我自己也试了一下,发现我的结果和我看到的一致),用于获取/设置stdClass对象、关联数组和索引数组。我忘记了是速度还是内存,但在stdClass上设置比设置关联数组键/值要使用更多的内存/更慢,这比仅仅添加新的索引数组项要慢/使用更多的内存。即:

//  slowest / most memory intensive
$some_stdClass_object->some_new_attribute = $data_I_want_to_keep;

//  slower / still memory intensive
$some_array["some_new_key"] = $data_I_want_to_keep;

//  optimal / fastest
$some_array[] = $data_I_want_to_keep;

在重新查看代码后,我注意到了这一行(为了可读性,注解被移动了):

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

看起来你把xml设置为一个类的属性(不管$this是什么类)。这很可能就是占用你内存的地方。也许可以看看那个函数(ParseXMLConfig),看看你是否可以把数据保存到对象中,如果需要的话,可以把它保存到索引数组或关联数组中。

相关问题