PHP — Как вернуть управляемый контент при критической ошибке PHP (E_ERROR, E_PARSE)?
register_shutdown_function(function () {
   $error = error_get_last();
   if ($error && ($error['type'] == E_ERROR || $error['type'] == E_PARSE || $error['type'] == E_COMPILE_ERROR)) {
       if (strpos($error['message'], 'Allowed memory size') === 0) { // если кончилась память
           ini_set('memory_limit', (intval(ini_get('memory_limit'))+64)."M"); // выделяем немножко что бы доработать корректно
           Log::error("PHP Fatal: not enough memory in ".$error['file'].":".$error['line']);
	} else {
           Log::error("PHP Fatal: ".$error['message']." in ".$error['file'].":".$error['line']);
        }
        // ... завершаемая корректно ....
    }
})



Ловит так же падения при отсутствии свободной памяти, ошибки парсинга, и прочего
Коллеги. 
Во-первых, согласен с тем, что говорилось выше. Это тоже правильно. Сам делал аналогичные вещи, перекрывал ошибки, писал в лог, слал на почту и т.п. 

Во-вторых, если бы меня попросили сделать такую фичу в хорошем добротном проекте, то я бы не стал изобретать велосипед, а воспользовался решением из коробки. 
Популярные фреймворки Symfony2, Yii — уже поддерживают это из коробки, причем достаточно давно. 
Переполнение по памяти не проверял, остальное ловит без проблем и отдает 500 ошибку, то есть как надо(поправка выше, не обязательно отдавать 503-ю. можно любую 5хх, этот жест скажет поисковику — «Ой, спроси меня позже...», 404 — в таком случае лучше не отдавать, оно может повлиять на позиции сайта в поиске — если для вас это важно.). 

Единственное ограничение к стилю кода, пишите без варингов и нотисов, они тоже ловятся. Иначе рискуете сделать проект, которые будет работать только в продакшен-режиме, то есть при выключенных ошибках. Отлаживать такие веши — не самое приятное занятие. К тому же, количество ошибок в таком коде выше на порядок. 

В-третьих, на проблему нужно смотреть шире. 
То, что код на php вываливается, когда случается ошибка синтаксического рода или нехватка памяти — это мега плохо. Решение — перекрывать функции обработки ошибок — ихмо, костыль, но иногда без него никуда. 

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

Пример с ошибками и статусами HTTP — не единственный. Возможны и другие варианты.

Идея вот в чем. Что и как нужно делать — зависит от вашего проекта. Это может быть не сложный сайт, который отдает информацию, а может быть достаточно сложный комплекс, в котором заложена бизнес-логика, она может отрабатывать как при получении страниц, так и при выполнении фоновых заданий(например, скрипты в CronTab). 

Если в двух словах, то я думаю так:
 — разбить код логики на блоки (желательно независимые, они могут быть ирерархичными). 
 — запускать эти блоки как бы «в песочнице» (вопрос как — зависит от самого приложение, у кого-то может и не получиться, или придется ради этого менять структуру БД, какие-то алгоритмы внутри приложения и т.п.)
 — по успешному выполнению блока, применяем результат. Что-то сломалось, уведомляем админа о критичной ситуации. 

Критичные ситуации лучше всего ловить Unit-тестами, а если это не возможно, то всеми видами тестирования.

Вот, как-то так.