Я пытаюсь загрузить Не перечислить список xml-файлов в MySql DB. Размер файла – 256 МБ. Он загружается, но когда он начинает обработку, зацикливание телефонных номеров и объединение 1000 телефонных номеров в переменную. Когда он достигает предела 1000, я создаю запрос INSERT и выполняю запрос. Проблема заключается в том, что после вставки 3,50,000 записей он говорит: « Неустранимая ошибка: допустимый размер памяти 2097152000 байт исчерпан (пытался выделить 24 байта) в / var / domains / htdocs / aim / lead / 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')); }
Заранее большое спасибо.
Я думаю, что он имеет в виду не то, как расширить пределы, но почему, черт возьми, это выделяет 2 ГБ ОЗУ?
По внешнему виду, я предполагаю, что вы используете simplexml
для загрузки данных. SimpleXML – это излишний объем памяти, и он не может использоваться для больших файлов без этого. Вместо этого вы должны попробовать:
FYI, я использовал SAX для загрузки около 200 МБ файла XML с максимальным объемом памяти около 5 МБ, так что да, потребление памяти несравнимо.
из-за ограничения памяти по умолчанию, установленного в 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
Разбор 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()); }
в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()); }