Вы знаете какое-либо решение для восстановления после фатальной ошибки PHP: « Разрешенный размер памяти … исчерпан »
У меня есть функция выключения, которая вызывается, когда появляется фатальная ошибка. Эта функция создает для него исключение ErrorException и регистрирует его.
Проблема в том, что, когда памяти больше нет, она не может зарегистрировать ошибку (я вхожу в Firebug через FirePHP с Zend Framework).
Итак, что я подразумеваю под « как восстановить из него », как выполнить основной журнал ошибок, и пусть Zend Framework отправляет заголовки, чтобы ошибка регистрировалась (в Firebug в моем случае), как и любая другая ошибка?
благодаря
Эта ошибка является фатальной ошибкой – это означает, что вы не можете ее восстановить. Если PHP достигнет предела памяти, он не сможет выделить больше памяти для создания своего исключения и любой другой памяти, необходимой для ее выполнения.
Существует еще одна ошибка: «захватывающая фатальная ошибка», которая, как следует из названия, может быть обнаружена в try / catch, но, к сожалению, распределение размера памяти не является одним из них.
if((memory_get_usage() / 1024 /1024) < 70)
Я просто разделил memory_get_usage на квадрат 1024, чтобы сравнить его с нормальным мегабайтом «70».
Я столкнулся с проблемами памяти с php внутри цикла for и написал этот простой оператор if, чтобы предотвратить запуск сценария фатальной ошибкой. Кроме того, сервер, на котором я работал, не позволял мне изменять пределы памяти (это часто бывает в некоторых облачных предложениях, таких как openhift или крупные веб-хосты, такие как dreamhost.) Я действительно не заметил серьезных ухудшений производительности ( в php 5.3, который может обрабатывать такие функции несколько иначе, чем php 4.x или 5.x … во всяком случае, последствия производительности скрипта, дающего фатальную ошибку, перевешивают любые накладные расходы, вызванные вызовом функции, а также предотвращают сценарий бегства от потребления всего доступного плунжера.
Многие могут возразить; о, ваше программное обеспечение не оптимизировано. Да. Возможно Вы правы; но со сложными наборами данных вы можете только выжать так много производительности, прежде чем вам нужно будет залить больше памяти; и поиск ошибок памяти в потоке ajax может быть очень расстраивающим; особенно если вы не знаете, где находятся ваши файлы журналов.
Регулярный способ настройки обработки ошибок
set_error_handler
– устанавливает пользовательскую функцию обработчика ошибок
Документы для этой функции ( основное внимание ):
Следующие типы ошибок не могут быть обработаны с помощью определенной пользователем функции: E_ERROR , E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING и большая часть E_STRICT, поднятых в файле, где вызывается set_error_handler ().
Таким образом, он не будет работать регулярно, но вы можете попробовать
register_shutdown_function
Начиная с PHP7, ошибки и исключения являются Throwables, поэтому вы можете попробовать / поймать их:
Ошибки PHP отправляются по умолчанию в ваш журнал ошибок apache /path/to/apache/logs/error.log
и вы можете видеть его там.
Получил идею непроверенного трюка, и я был бы рад узнать, помогло ли это. Выделите некоторую глобальную переменную, когда вы сначала зарегистрируете функцию выключения и отпустите ее, когда сначала выполняется код функции завершения работы. Тогда у вас может быть достаточно памяти для создания объекта Exception. Дайте мне знать, если это сработает и, пожалуйста, опубликуйте здесь код.
Это работало отлично для меня:
try { ini_set('memory_limit', (ini_get('memory_limit')+1).'M'); } catch(Exception $e) {}
Это предполагает, что ваш предел памяти находится в формате 123M
.
Один из них, о котором я могу думать, заключается в том, что вы, когда выполняете свою интенсивную работу с памятью, вручную запрашиваете memory_get_usage()
на регулярной основе (например, каждую итерацию цикла) и выгружаете свои заголовки / ошибки, когда они переходят на некоторое отказоустойчивое значение, которое ниже предел сценария. Это замедлит ваш скрипт, но, по крайней мере, вы что-то получите.
Или, возможно, вы не сможете этого сделать, запустите интенсивный объем памяти как скрипт на основе CLI, вызванный из вашего веб-материала, используя exec. Часть CLI может упасть, но веб-часть сможет сообщить об этом.