PHP cURL «Неустранимая ошибка: допустимый размер памяти» для больших наборов данных

Я знаю про вариант установки внутренней памяти

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

Но я хотел знать, есть ли лучший подход для запроса данных?

У меня есть WHILE LOOP, который проверяет, нужно ли мне запрашивать еще 1000 записей. используя смещение в качестве начального номера записи и лимит в качестве возвращаемых записей, я ищу все записи, соответствующие моему запросу данных. Я набрал около 100 000 записей, прежде чем получил ошибку.

Теперь во время тестирования я обнаружил, что получаю ошибку «Неустранимая ошибка: разрешенный размер памяти ...». Я читал, установив вышеуказанный ini_set(), чтобы учесть увеличение памяти, но я хотел знать, могу ли я просто лучше закодировать его?

Каждый раз, когда я выполняю приведенный ниже код в цикле WHILE LOOP, использование памяти становится очень большим. Даже если я отключу ($ curl). Я думаю, что это можно было бы уменьшить, если бы я мог отменить переменные $result и $curl после того, как я проанализировал результаты перед следующим запросом 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

person Phill Pafford    schedule 26.08.2010    source источник
comment
Можете ли вы показать нам цикл while, пожалуйста?   -  person Charles    schedule 26.08.2010
comment
У вас установлен xdebug? Это может дать вам полезную информацию.   -  person bogeymin    schedule 26.08.2010
comment
WHILE LOOP в порядке, я делаю memory_get_usage() перед вызовом cURL и после вызова cURL, и именно здесь память становится безумно большой. Цикл while просто проверяет, нужен ли нам повторный запрос. если записи больше, чем возвращаются последние 1000. Анализирует возврат и помещает нужные данные в массив. Я проверил, была ли проблема в массиве, но он очень-очень мал, всего может быть сотня записей с минимальными данными в каждой записи.   -  person Phill Pafford    schedule 26.08.2010
comment
У меня не установлен xDebug, это не мой сервер :(   -  person Phill Pafford    schedule 26.08.2010
comment
Ваша функция выглядит нормально. Что-то в коде цикла поглощает память. Выложи код цикла.   -  person timdev    schedule 26.08.2010
comment
добавлен код WHILE LOOP. Я также пытался отключить все, что мог, и именно cURL getRequest добавляет накладные расходы на память.   -  person Phill Pafford    schedule 26.08.2010


Ответы (2)


Я предполагаю, что вы используете неправильный ключ для $resultsArr. Вы используете одну и ту же строку как ключ и значение.

Попробуйте изменить

$resultsArr["$resultsData"] = $resultsData

to

$resultsArr[$resultsKey] = $resultsData
person codaddict    schedule 26.08.2010

Урегулировано для:

ini_set("memory_limit","30M");
person Phill Pafford    schedule 31.08.2010