Память PHP исчерпана при использовании тысяч записей

Я запускаю следующий код по набору из 5000 результатов. Он не работает из-за исчерпания памяти.

foreach ($data as $key => $report) { $data[$key]['data'] = unserialize($report['serialized_values']); } 

Я знаю, что могу ограничить память, но я бы хотел запустить это без проблем. Я не смогу постоянно поддерживать память.


РЕДАКТИРОВАТЬ

Данные $data в этом формате:

 [1] => Array ( [0] => 127654619178790249 [report_id] => 127654619178790249 [1] => 1 [user_id] => 1 [2] => 2010-12-31 19:43:24 [sent_on] => 2010-12-31 19:43:24 [3] => [fax_trans_id] => [4] => 1234567890 [fax_to_nums] => 1234567890 [5] => ' long html string here', [html_content] => 'long html string here', [6] => 'serialization_string_here', [serialized_values] => 'serialization_string_here', [7] => 70 [id] => 70 ) 

Solutions Collecting From Web of "Память PHP исчерпана при использовании тысяч записей"

Помимо проблем for и foreach, вам необходимо перестроить свое решение. Вы попадаете в пределы памяти, потому что законно используете слишком много памяти. Каждый раз, когда вы несериализуете содержимое столбца базы данных и храните его в массиве

 $data[$key]['data'] 

PHP должен отложить кусок памяти для хранения этих данных, чтобы впоследствии получить доступ. Когда ваш массив становится слишком большим, вы потеряли память. На простом английском языке вы говорите PHP

Возьмите все 5000 строк данных и сохраните их в памяти, я собираюсь что-то с ними сделать позже.

Вам нужно подумать о другом способе подхода к вашей проблеме. Ниже приведены две быстрые мысли о проблеме.

Вы не могли хранить элементы в памяти и просто выполнять любые действия, которые вы хотели в цикле, что позволяет php отбрасывать элементы по мере необходимости

 foreach ($data as $key => $report) { $object = unserialize($report['serialized_values']); //do stuff with $object here } 

Вы также можете хранить информацию, которая вам нужна, из несериализованного объекта, а не хранить весь объект

 foreach ($data as $key => $report) { $object = unserialize($report['serialized_values']); $data = array(); $data['foo'] = $object->foo; $data[$key]['data'] = $data; } 

Короче говоря: вы нажимаете ограничения памяти, потому что на самом деле вы используете слишком много памяти. Здесь нет магического решения. Хранение сериализованных данных и попытка загрузить их все в одной программе – это интенсивный подход к памяти, независимо от языка / платформы.

В foreach будет загружено все 5000 результатов в память. См. Многочисленные жалобы в документах . Используйте цикл for получайте доступ к каждому результату по мере необходимости.

Что такое $data и откуда вы его получаете? Если это файл, вы не можете fgets () по одной строке за раз анализировать, и если это база данных, вы не можете обрабатывать одну запись за раз (за счет MySQL, ожидающей закрытия набора результатов) , Я думаю, вы должны пересмотреть загрузку всего $data в память сразу, а затем зациклиться на нем.

попробуйте этот путь

 foreach ($data as $key => &$report) { } 

Это приведет к назначению ссылки вместо копирования значения.

На самом деле это причина, по которой многие сайты делят результаты на страницах.

Предположим, у меня есть 5000 результатов (скажем, пользователей, чтобы упростить), и у меня есть страница, которая должна отображать все эти 5000 результатов. Я бы разделил эти 5000 результатов на 500 на страницу, так что на одной странице 1 отобразится 1 – 500, страница 2 отображает 501 – 1000, стр. 3 отображает 1001 – 1500 и так далее. Таким образом, память сохраняется.

Если вам действительно нужно отобразить все 5000 результатов на одной странице, вам действительно нужно увеличить лимит памяти. Или используйте вместо этого цикл.

Я не знаю точно, но вы можете использовать:

  • gzip (набор данных $) для сжатия данных в безопасную память и дефлирования их на лету.
  • предел (данные).
  • создать кеш-систему. вырезать наименее недавно используемые (LRU) данные из кеша при использовании слишком большого объема памяти.

Я думаю, что эти ошибки еще не закрыты:

«При несериализации внутри цикла одного и того же сериализованного объекта общее потребление памяти увеличивается каждые пару итераций»