PHPExcel нужно слишком много памяти для загрузки файла. Я хочу улучшить этот код за счет использования памяти.
Ломается с ошибкой Fatal error: Allowed memory size of 536870912 bytes exhausted
по этому коду:
/* class PHPExcel_Cell
*
* $returnValue = array()
*
*/
$sortKeys = array();
foreach (array_unique($returnValue) as $coord) {
sscanf($coord,'%[A-Z]%d', $column, $row);
$sortKeys[sprintf('%3s%09d',$column,$row)] = $coord;
}
ksort($sortKeys);
return array_values($sortKeys);
$ returnValue = массив («B1», «C12», «C1», «D3», «B2» …)
должен быть отсортирован как массив («B1», «B2», «C1», «C12»)
Первая проблема: Если я правильно понимаю, array_unique используйте один дополнительный массив для хранения результата, поэтому общее использование памяти x2 (если у нас есть массив с уникальными элементами). Но я думаю, что не нужно использовать array_unique, потому что любые дубликаты будут перезаписаны этой строкой:
$sortKeys[sprintf('%3s%09d',$column,$row)] = $coord;
Вторая проблема: Этот код использует два массива: $ returnValue и $ sortKeys (2x памяти), поэтому я переписал его так:
$len = count($returnValue);
for ($i = 0; $i < $len; $i++) {
$val = $returnValue[$i];
unset($returnValue[$i]);
sscanf($val,'%[A-Z]%d', $column, $row);
$returnValue[sprintf('%3s%09d',$column,$row)] = $val;
}
ksort($returnValue);
return array_values($returnValue);
Но снята с охраны () не освобождает память, только удаляет элемент из массива и gc_collect_cycles () тоже не работает.
Как я могу освободить память после снята с охраны?
Может быть, вы знаете другой способ, как улучшить этот код за счет использования памяти?
Постскриптум Я не могу использовать xlsx2csv и другие инструменты Bash.
Ваш код выглядит довольно странно, вы удаляете элемент из массива, а затем добавляете новый в один цикл.
Когда я использовал PHPExcel, я использовал деструкторы для освобождения памяти, и это работало очень хорошо
function __destruct()
{
if ($this->phpExcelObj) {
\PHPExcel_Calculation::unsetInstance($this->phpExcelObj);
if ($this->phpExcelObj) {
$this->phpExcelObj->disconnectWorksheets();
unset($this->phpExcelObj);
}
}
}
Другой способ — создать шаблоны с Word и загрузить этот шаблон с PHPExcel, тогда вы не будете использовать операции потребления памяти для разметки вашего документа.
Эти методы помогли мне загрузить миллион строк, используя PHPExcel, с не такой большой памятью.
Других решений пока нет …