Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: Апач вешается
Форумы портала PHP.SU » Серверное администрирование » Apache и другие веб-серверы » Апач вешается

Страниц (1): [1]
 

1. mark2009 - 15 Сентября, 2009 - 14:25:21 - перейти к сообщению
В общем требуется прочитать эксельку размером 4 метра в массив Улыбка в файле 8000 строк и 8 столбцов.

Наваял вот такой код:
PHP:
скопировать код в буфер обмена
  1.  
  2. require ('excel_reader2.php');
  3.  
  4. $data = new Spreadsheet_Excel_Reader('price.xls');
  5. $strings_array = array();
  6. $current_string = "";
  7.  
  8. /* echo $data->rowcount() ~7980 */
  9. /* echo $data->colcount() 8 */
  10.  
  11. for ($i = 3; $i <= $data->rowcount(); $i++)
  12. {
  13.     for ($j = 1; $j <= $data->colcount(); $j++)
  14.     {
  15.         if ($j !== $data->colcount())
  16.         {
  17.             $current_string.=$data->value($i, $j).",";
  18.         }
  19.         else
  20.         {
  21.             $current_string.=$data->value($i, $j);
  22.         }
  23.     }
  24.     $current_string.="<br>";
  25.     $strings_array[] = $current_string;
  26. }
  27.  
  28.  


В результате выполнения этого кода начал вешаться сервер. Просто вылетает с системным сообщением об ошибке. В логах сообщения следующего плана:

Цитата:

[Tue Sep 15 17:19:10 2009] [error] [client 127.0.0.1] PHP Fatal error: Out of memory (allocated 1795424256) (tried to allocate 601760 bytes) in D:\\Server\\www\\xls\\test.php on line 17
[Tue Sep 15 17:19:16 2009] [notice] Parent: child process exited with status 3221225477 -- Restarting.


Добавил в код следующую строчку:


В принципе ничего не изменилось. Надо прочитать именно весь файл сразу, не частями. Дело в том что пишется универсальная система и файлы могут быть больше чем этот. Что можно ещё сделать для оптимизации?
2. Viper - 15 Сентября, 2009 - 14:33:58 - перейти к сообщению
читать файлы кусками. я не думаю что оптимальный вариант заливаьт в массив по 10 метров данных.
3. chaynyk - 15 Сентября, 2009 - 14:57:07 - перейти к сообщению
н
4. mark2009 - 15 Сентября, 2009 - 19:34:01 - перейти к сообщению
В том то и дело что файл всего один...
5. Maxim.Format - 27 Сентября, 2009 - 11:59:01 - перейти к сообщению
Скрипт хоть раз отработал? Вы видели какие данные он получил? Либо меня прет, либо Вы не очищаете $current_string.
6. Stierus - 28 Сентября, 2009 - 10:03:34 - перейти к сообщению
А есть возможность сохранит эксельку как csv ? Если есть - переведите и построчно обрабатывайте - это позволить вам не хранить весь файл в памяти.
Цитата:
ini_set('memory_limit', '3G');
Поставьте лимит в 50 метров (куда скрипту больше) и уберите лимит на время выполнение скрипта. Поставьте Xdebug - увидите более полную картину происходящего (в том числе и по памяти). Сделайте лимит на запуск этого скрипта (если скрипт уже запущен - больше запустить нельзя, вдруг сервер дохнет из-за того, что вы запустили этот скрипт 10 раз (ну или не вы, мало ли кто к нему может обращаться))
Цитата:
$strings_array[] = $current_string;
для чего вы результат записываете в массив (опять же забивая память) ? надо выводить пользователю - выводите (что было бы странным, вешать пользователю браузер - не лучшая затея), нужно сохранить в файл - записывайте налету, в базу данных - формируйте пакеты по 20 команд и выполняйте опять же сразу ... много вариантов, пробуйте Улыбка

ps
опять раритет подняли Недовольство, огорчение
7. Enjoy - 08 Декабря, 2009 - 22:30:40 - перейти к сообщению
Доброго времени суток! Та же тема, только файл у меня вообще 46мб Огорчение
Скрипт работает только если в файле оставить немного строк, около 1000.

Пробовал убрать любое накопление результата, просто выводил echo - тот же финал, кончается память.
8. valenok - 09 Декабря, 2009 - 10:41:11 - перейти к сообщению
ini_set('memory_limit','512M');
А посмотрите сколько скрипту нужно памяти, он пишет в ошибке tried to allocate x
9. Enjoy - 20 Января, 2010 - 19:31:36 - перейти к сообщению
valenok пишет:
ini_set('memory_limit','512M');
А посмотрите сколько скрипту нужно памяти, он пишет в ошибке tried to allocate x

Прошу прощения за такой долгий ответ - отчаялся Улыбка

Ставил предел памяти(правда в конфигах) до 512мб, занимало и этот объем с легкостью. Такое ощущение, что дело в алгоритме, который задумывали на файлы в несколько сотен строчек. Если что, то проблема все еще актуальна в вялотекущей стадии
(Добавление)
Viper пишет:
читать файлы кусками. я не думаю что оптимальный вариант заливаьт в массив по 10 метров данных.

Кстати, кажется от excel нельзя отрезать кусок и начать читать с какого-то nn-ого смещения по строкам. Только перебирать от начала одну за другой. По этим же причинам кажется нельзя обратиться к nn-ой строке прямо, вместо этого нужно до нее последовательно дойти.
10. valenok - 21 Января, 2010 - 13:45:19 - перейти к сообщению
http://code[dot]google[dot]com/p/php-exc[dot][dot][dot]sues/detail?id=1
Попробуй обновить класс. Судя по всему новый исправился.
11. Enjoy - 21 Января, 2010 - 22:18:11 - перейти к сообщению
2.21 вроде самый новый, апрель 2009.
12. JustUserR - 24 Января, 2010 - 12:49:57 - перейти к сообщению
Enjoy пишет:
Такое ощущение, что дело в алгоритме, который задумывали на файлы в несколько сотен строчек
Представление файла в памяти занимает всегда значительно больше чем на жестком диске (Поэтому файл в 512 МБ никогда не влезет полностью даже в 1024 МБ памяти - все дело в особом распределении по сегментам памяти и изоляции данных от кода Улыбка
И в вашеми случае лучше использовать PHP_CGI так как он будет работать отдельной программой и не вешать Apache - а вот при использовании как модуля Apache не тольлко все вешает но и ограничен лимитами памяти apache

 

Powered by ExBB FM 1.0 RC1