предел памяти php 2000M исчерпан - PullRequest
0 голосов
/ 28 июня 2011

Пытаюсь загрузить Не вызывать список xml файл в MySql DB.Размер файла составляет 256 МБ.Он загружается, но когда начинается его обработка, я зацикливаю телефонные номера и объединяю 1000 телефонных номеров в переменную.Когда он достигает предела 1000, я создаю запрос INSERT и выполняю запрос.Но проблема заключается в том, что после вставки 3,50000 записей написано "Неустранимая ошибка: допустимый объем памяти 2097152000 байтов исчерпан (попытка выделить 24 байта) в / var / domains / htdocs / aim / приводит / dnc в строке 1308)«.

Ниже приведен фрагмент кода.

                    if(($fp = fopen($destination,"r"))) {

                        $buffer = fgets($fp);
                        $objXml = new XML($buffer);
                        $lists = Set::reverse($objXml);

                        $buffer = fgets($fp);
                        $objXml = new XML($buffer);
                        $acc = Set::reverse($objXml);

                        try {
                            while(!feof($fp)){
                                $counter = 0;
                                $phonesNo = "";

                                while(!feof($fp) && ($buffer = fgets($fp)) && $counter != 1000){

                                    $objXml = "";
                                    $arrXml = "";

                                    $objXml = new XML($buffer);

                                    $arrXml = Set::reverse($objXml);


                                    $counter++;
                                    if(isset($arrXml['Ph']['val']))
                                        $phonesNo .= "(".$acc['Ac']['val'].$arrXml['Ph']['val']."),";

                                }

                                $phonesNo = substr($phonesNo,0,-1);
                                $sql = "INSERT INTO do_not_call_lists (`phone`) VALUES " .$phonesNo;

                                unset($phonesNo);
                                $this->Lead->query($sql);
                            }
                        }catch (Exception $ex){
                            trigger_error("ERROR: ". $ex->getMessage(). "  Trace: ".$ex->getTrace());
                        }

                        $this->Session->setFlash('File imported successfully.','default',array('class'=>'sucessMsg'));

                     }

Заранее большое спасибо.

Ответы [ 3 ]

4 голосов
/ 28 июня 2011

Я думаю, что он имеет в виду не то, как расширить пределы, а зачем, черт возьми, выделять 2 ГБ ОЗУ?

Судя по всему, я предполагаю, что вы используете simplexml для загрузки данных. SimpleXML - это излишняя память, и он не может быть использован для больших файлов без этого. Вместо этого вы должны попробовать:

  1. на основе событий SAX-парсер (меньше памяти, чем во втором, но намного сложнее в работе)
  2. на основе извлечения XMLReader

Кстати, я использовал SAX для загрузки около 200 МБ XML-файла с пиковым использованием памяти около 5 МБ, так что да, потребление памяти несопоставимо.

1 голос
/ 28 июня 2011

из-за ограничения памяти по умолчанию, установленного в ur ini. Вы можете увеличить его с помощью .htaccess или ini_Setнекоторые дополнительные параметры также требуются, поскольку ваш код также требует загрузки.Я дал вам метод, чтобы решить его через .htaccess.Вы также можете использовать его как ini_set, просто заменив php_value на ini_set на своей странице php.надеюсь, это поможет вам

php_value post_max_size 1000M
php_value upload_max_filesize 2500M
php_value max_execution_time 6000000
php_value max_input_time 6000000
php_value memory_limit 2500M
0 голосов
/ 28 июня 2011

Разбор XML с множеством данных - довольно сложная задача, поэтому, возможно, здесь будет лучше использовать регулярные выражения. Попробуйте изменить ваш цикл следующим образом:

try {
    while(!feof($fp)){
        $counter = 0;
        $buffer = '';
        while(!feof($fp) && ($buffer .= fgets($fp)) && $counter++ < 1000);
        // read 1000 rows into buffer
        $matches = array();
        if (preg_match_all('/<Ph[^>]*>(\d+)</Ph>/i', $buffer, $matches) > 0) {
            $sql = 'INSERT INTO do_not_call_lists (`phone`) VALUES (' . implode('), (', $matches[1]) . ')';
            $this->Lead->query($sql);
        }
    }
}catch (Exception $ex){
    trigger_error("ERROR: ". $ex->getMessage(). "  Trace: ".$ex->getTrace());
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...