php内存限制2000M耗尽

时间:2011-06-28 12:55:01

标签: php cakephp

我尝试将不调用列表 xml文件上传到MySql DB。文件大小为256MB。它被上传,但是当它开始处理时,循环电话号码并连接变量中的1000个电话号码。当它达到1000的限制时,我创建一个INSERT查询并执行查询。问题是在插入3,50,000条记录后,它说“致命错误:允许内存大小为2097152000字节耗尽(试图分配24字节)在/ var / domains / htdocs / aim / leads / 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 个答案:

答案 0 :(得分:4)

我认为他的意思不是如何扩展限制,但为什么分配2GB内存呢?

从它的外观来看,我假设您正在使用simplexml来加载数据。 SimpleXML是一种内存矫枉过正,如果不发生这种情况,它就无法用于大型文件。您应该尝试使用:

  1. 基于事件的SAX parser(内存使用量少于第二个,但操作起来要困难得多)
  2. pull based XMLReader
  3. 仅供参考,我一直在使用SAX来加载大约200MB的XML文件,峰值内存使用量约为5MB,所以是的,内存消耗是无法比拟的。

答案 1 :(得分:1)

由于ur ini默认设置的内存限制, 您可以通过.htaccess或通过ini_Set增加它。 由于您的代码也需要上传部分,因此还需要一些其他参数。 我已经给你通过.htaccess解决它的方法。 您也可以将它用作ini_set,只需将php_value替换为php页面中的ini_set即可。 希望它可以帮到你

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

答案 2 :(得分:0)

使用大量数据解析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());
}