/** * @function getSplitCache 對excelId基礎資料進行分區緩衝 * @param type $excelId excel檔案id tax_excel的id * @param type $beforeAndAfterInsertid details_excel 插入前後的id * @return 無 統一excel的快取檔案標準為: EXCEL_ID_NUM */ public function getSplitCache($excelId, $beforeAndAfterInsertid){ processTip( '100%', 'Excel資料分區開始.....................'); $where['id'] = array('gt', $beforeAndAfterInsertid['beforeId']); $where['excel_id'] = array('eq', $excelId); //是否可能存在兩個表同時插入情況,如果無可省略此項 $allExcelData = $this->modelDetailsExcel->where($where)->group('nsrsbh,id')->select(); $totalNum = count($allExcelData); $this->_setAllRow($totalNum);// $interval = ceil( ($beforeAndAfterInsertid[1]-$beforeAndAfterInsertid[0])/$this->excelDataCacheNum);//多個人同時出現操作插入檔案是可能錯誤 $interval = ceil($totalNum/$this->excelDataCacheNum); for($i = 0; $i< $this->excelDataCacheNum; $i++ ){ $excelData[$i] = array_slice($allExcelData, $i*$interval, $interval); } unset($allExcelData); //1一個在開頭一個在結尾利用時間差可以不再細分 //2必須分在一起以下為分在一起的 $i = 0; for($i; $i< $this->excelDataCacheNum-1; $i++ ){ if($excelData[$i][$interval-1]['nsrsbh'] === $excelData[$i+1][0]['nsrsbh']){ $j = 0; while( $excelData[$i][$interval-1]['nsrsbh'] === $excelData[$i+1][$j]['nsrsbh']){ $excelData[$i][] = $excelData[$i+1][$j++]; P($j); } array_splice($excelData[$i+1], 0, $j); } //輸出前台展示進度 processTip( ($i/$this->excelDataCacheNum*100), 'Excel資料分區'.$i.'.....................'); //Thinkphp的F緩衝方法 指定位置和名稱 F('Excel_'.$excelId.'/'.$i , $excelData[$i]); } F('Excel_'.$excelId.'/'. $i , $excelData[$i]); processTip( '100%', 'Excel資料分區結束.....................'); return $this->excelDataCacheNum; }
基本原理是 將資料庫資料按照nsrsbh 和 id排序 讀取出來,然後將資料按照分區資料 分割指定數目的檔案(用於前台ajax請求,類比多線程操作,js發送請求後端接收後處理傳過來的資料分區的檔案name,然後處理改檔案內的資料)
系統內容 apche php 分配的memoryliimit win(win10 64bit 4G記憶體)為2g linux(ubuntu14.04 64位 8g記憶體)為4g
經過測試當資料量在3500條時分區1000正常執行。
當資料量在11770條時,linux下和win下開始出現這個問題
到978片緩衝產生時就進行不下去,php程式自動跳出 效果如下 然後進程就退出了。
當分區為500的時候出現到488 就會卡 然後到了過個2分鐘左右才會輸出489 然後沒有然後了 進程跳出了
回複內容:
/** * @function getSplitCache 對excelId基礎資料進行分區緩衝 * @param type $excelId excel檔案id tax_excel的id * @param type $beforeAndAfterInsertid details_excel 插入前後的id * @return 無 統一excel的快取檔案標準為: EXCEL_ID_NUM */ public function getSplitCache($excelId, $beforeAndAfterInsertid){ processTip( '100%', 'Excel資料分區開始.....................'); $where['id'] = array('gt', $beforeAndAfterInsertid['beforeId']); $where['excel_id'] = array('eq', $excelId); //是否可能存在兩個表同時插入情況,如果無可省略此項 $allExcelData = $this->modelDetailsExcel->where($where)->group('nsrsbh,id')->select(); $totalNum = count($allExcelData); $this->_setAllRow($totalNum);// $interval = ceil( ($beforeAndAfterInsertid[1]-$beforeAndAfterInsertid[0])/$this->excelDataCacheNum);//多個人同時出現操作插入檔案是可能錯誤 $interval = ceil($totalNum/$this->excelDataCacheNum); for($i = 0; $i< $this->excelDataCacheNum; $i++ ){ $excelData[$i] = array_slice($allExcelData, $i*$interval, $interval); } unset($allExcelData); //1一個在開頭一個在結尾利用時間差可以不再細分 //2必須分在一起以下為分在一起的 $i = 0; for($i; $i< $this->excelDataCacheNum-1; $i++ ){ if($excelData[$i][$interval-1]['nsrsbh'] === $excelData[$i+1][0]['nsrsbh']){ $j = 0; while( $excelData[$i][$interval-1]['nsrsbh'] === $excelData[$i+1][$j]['nsrsbh']){ $excelData[$i][] = $excelData[$i+1][$j++]; P($j); } array_splice($excelData[$i+1], 0, $j); } //輸出前台展示進度 processTip( ($i/$this->excelDataCacheNum*100), 'Excel資料分區'.$i.'.....................'); //Thinkphp的F緩衝方法 指定位置和名稱 F('Excel_'.$excelId.'/'.$i , $excelData[$i]); } F('Excel_'.$excelId.'/'. $i , $excelData[$i]); processTip( '100%', 'Excel資料分區結束.....................'); return $this->excelDataCacheNum; }
基本原理是 將資料庫資料按照nsrsbh 和 id排序 讀取出來,然後將資料按照分區資料 分割指定數目的檔案(用於前台ajax請求,類比多線程操作,js發送請求後端接收後處理傳過來的資料分區的檔案name,然後處理改檔案內的資料)
系統內容 apche php 分配的memoryliimit win(win10 64bit 4G記憶體)為2g linux(ubuntu14.04 64位 8g記憶體)為4g
經過測試當資料量在3500條時分區1000正常執行。
當資料量在11770條時,linux下和win下開始出現這個問題
到978片緩衝產生時就進行不下去,php程式自動跳出 效果如下 然後進程就退出了。
當分區為500的時候出現到488 就會卡 然後到了過個2分鐘左右才會輸出489 然後沒有然後了 進程跳出了
你去php.ini檔案中看看有沒有配置最大變數長度的那個設定項,找到它,修改後伺服器重啟即可。
我以前恰好遇到過這個問題
開啟 error_reporting
可在指令碼最上方添加
phperror_reporing(E_ALL);ini_set('display_errors');
監控資料量多的情況下,是不是記憶體使用量超出限制
如果確認是記憶體溢出
改造你的程式,降低記憶體使用量
比如使用generator
具體根據你的業務,盡量不要取太多資料放入記憶體
保證你程式啟動並執行時候不要隨著處理資料量的增大而記憶體也跟著增大
理想的情況是處理資料量的增長不會導致程式運行記憶體的暴增
set_time_limit(0),設定逾時時間,不是記憶體的問題可能是逾時了