Не могу разобраться со следующей проблемой. Требуется выгрузить из базы данных большую таблицу в 40к строк, но столкнулся с проблемой:
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 32 bytes) line 58
Выгрузить нужно в html, таблица должна быть отображена и потом должна быть возможность сохранения в Excel. Для отображения использую Vue + axios.
Использование ini_set('memory_limit', '-1') помогло, но я всё таки думаю, что я что то не так делаю с памятью, прошу помощи более опытных людей. Ошибка проявляется на цикле while
Пример кода:
$c = oci_parse($oci_connect, $query);
$data = array();
$data = file_get_contents("php://input");
json_encode($data, true);
$json = json_decode($data, true);
/*$id1 = $json['sel1'];
$id2 = $json['sel2'];
$id3 = $json['sel_ch'];*/
$id1 = null;
$id2 = 201906;
$id3 = 143729749;
oci_bind_by_name($c, ':filial_ID', $id1);
oci_bind_by_name($c, ':period', $id2);
oci_bind_by_name($c, ':sale_channel_id', $id3);
oci_execute($c);
/*if ( ! oci_execute($c)) {
$oci_error = oci_error($c);
die($oci_error["message"]);
}*/
//ini_set('memory_limit', '-1');
$stack = array();
echo memory_get_usage();
while (($row = oci_fetch_row($c)) != false) {
array_push($stack, $row);
//echo json_encode($row, true);
/*print_r ($row);
unset($row);*/
}
echo json_encode($stack, true);
echo memory_get_usage();
/*oci_fetch_all($c, $res);
echo json_encode($res, true);*/
oci_close($oci_connect);
Данные занимают память, если данных много, они занимают много памяти. Как получить большой объём данных, не загружая их все в оперативную память? Можно выводить (в файл, стандартный вывод, в html-таблицу в браузере пользователя) данные кусками. Загрузить, скажем, 1000 строк, вывести, снова 1000 и так далее, пока не получится 40к.
В конкретно вашем случае вы взаимодействуете со своим пхп-скриптом по HTTP и можно отправить один запрос на 1000 строк, следующий запрос на следующую 1000! Это и называют пагинацией (постраничным выводом).
В результате можно напихать пользователю в браузер все 40к строк. И тут вы удивитесь. Теперь память начнёт жрать браузер! Кроме того ни один нормальный человек не сможет изучать все 40к строк и делать какие-то полезные выводы. Выходит, что и в браузер не надо совать все 40к, а надо нарисовать пользователю кнопочку "Показть ещё" или список страниц.
Если вы решите создать excel-файл из 40к строк, то заметите что и экселю может стать плоховато. Но если вы всё-таки решитесь, то вам опять-таки не надо вытаскивать сразу 40к, пишите файл строка за строкой (csv, например) и не сохраняйте сроки из базы в массив.
Переменная $stack
занимает слишком много места в памяти. Попробуйте вывести данные без предварительной записи в массив. Как-то так:
ob_start();
echo "[";
$isFirst = true;
while (($row = oci_fetch_row($c)) != false) {
echo ($isFirst ? '' : ','), json_encode($row, true);
$isFirst = false;
}
echo "]";
ob_end_flush();
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
При загрузке изображений и публикации записей миниатюры не создаютсяПри попытке получить миниатюру - получаю фулл сайз
Пытаюсь создать свой bundle для многократного использованияСовершенно непредсказуемым образом вылетает ошибка:
На странице магазина /shop выводится список всех товаровКак сделать, чтобы выводилось сначала определённое количество товаров, допустим 4, и ниже...