Вобщем пару топиков на Винграде натолкнули на следующую мысль. Изоляция модулей от системы с применением перехвата фатальных ошибок по котерову. Вот что получилось. http://simpliest.co.cc/consumer.php Исходники http://simpliest.co.cc/provider.phps http://simpliest.co.cc/consumer.phps Надо обругать недостатки подхода
Пока вижу один недостаток: это не фича, это баг. Он не документирован, значит его могут исправить в любой момент Ну а во-вторых существует очень удобной механизм Exception'ов, зачем городить огород?
Это не баг, это фича: если включено отображение ошибок, то сначала происходит output, а потом - завершение работы скрипта (иначе кто будет делать output?) Если поток вывода передается пользователькой функции, то логично, что она будет выполнена. Экспешены рулят, но фаталы они не перехватывают. Вопрос в другом - зачем перехватывать фаталы, если есть удобные логи?
1. фатальные ошибки не ловятся обычными методами. 2. Exception да, но речь идет именно о изоляции разнородных модулей, т.е. тех же плагинов сторонних разработчиков Я бы не сильно доверял людям. Да бог с ним с логом. Если собирать монолитную систему то из-за одного модуля (например, погоды) у тебя упадет вся страница. Хотя показать есть что А так, тут основной момент не столько в обработке именно ob_handler'ом, сколько изолированное выполнение части системы. Т.е. тот же AJAX, SOAP, RPC дадут ровно такую же возможность. Естественно за счет деградации производительности.
На то они и фатальные, это не E_NOTICE. Если уж мы стараемся E_NOTICE не допускать то что же скажем о fatal error? Перехватка фатальной ошибки не поможет, например: 1. Запускаем головную программу, лимитированную скажем 8мб-ми. 2. Подключаем плагин, который, зараза съедает все 8мб. 3. Вызывается Fatal-error 4. Перехватываем его. Теперь вопрос, сколько у нас осталось оперативной памяти и что мы можем с ней сделать? Возможно гибридный вариант будет подходящим решением. Есть доверенные плагины, подключаемые инклудом, есть "защищенный режим" (SOAP и все остальное)
Ты не обратил внимания (блин, посмотри код ). Плагину выделяются все 8мб минус немного на обработку (собственно надо всего лишь запомнить информацию об ошибке). В основную программу мы вернемся через редирект и ей опять будут доступны все 8мб, а уж она разберет что запустилось, что не запустилось, что какие ошибки выдало и что со всем этим делать дальше. Вопрос в том что при наличии 20 модулей это будут 20 редиректов С другой стороны аякс запросов тоже было бы 20 как я и говорил производительность деградирует.
Угу, чтобы рухнул один какой-нибудь модуль-партизан и мы вообще нихрена не получили бы Тогда уж все инклюдами в основном файле и идею в топку
у меня есть некоторая изоляция. Из шаблонов могу дергать блоки. Если в этом блоке будет фатальная ошибка - основная страница отрендерится, но без этого блока. Но думаю, что этого недостаточно. А делать серьезней - лень.
Simpliest Блин, а как WordPress со своей тучей плагинов работает? Ничего? Хорошо? вот и ладненько. Если кто вдруг хочет изолированный процесс, то вариант один: fork, и не важно как он будет сделан. И быстродействия можно добиться нормального, конечно не так шелково как несколько инклудов, но достаточно оперативно. У нас уже есть прослойки nginx + apache + fastcgi, потери между общением этих процессов ( по сравнению с общей производительностью скриптов ) минимальны А абьюзить баги (фичи) в php это не выход. Они на корню могут убить проект при переходе на очередную версию. При этом получим мифическое быстродействие, кучу головной боли в виде разруливания архитектуры и псевдобезопасность кода.
Что ты делаешь в своих шаблонах, что может вызвать фатальную ошибку? Наркотики перевозишь? Чушь Извините за категоричность. Далее: модуль паразит может съесть 7.5 мб оперативной памяти следующий по списку модуль вылетает с ошибкой мы редиректим страницу с именем второго модуля модуль паразит опять съедает 7.5 мб памяти ...
ну, например, из шаблона я вызываю показ менюшки на основе структуры страниц. Там че-то пошло не так и... Вообще я не знаю, у меня все нормально, фаталов в продакшене нету. Ха-ха!
PHP: <?php error_reporting(E_ALL); ini_set('display_errors', 0); function shutdown(){ $isError = false; if ($error = error_get_last()){ switch($error['type']){ case E_ERROR: case E_CORE_ERROR: case E_COMPILE_ERROR: case E_USER_ERROR: $isError = true; break; } } if ($isError){ echo "Script execution halted ({$error['message']})"; } else { echo "Script completed"; } } register_shutdown_function('shutdown'); ?> Перехватывает фатальные ошибки https://php.ru/manual/function.set-error-handler.html#88401 PS> 80% моих аргументов растворились
Мда. еще один способ. В принципе - любопытно. Впрочем, вопрос был не только в перехвате Upd: надо будет ее помучать на досуге
Simpliest Имхо спокойно перехватывай фатальные ошибки. С отключением модуля вызвавшего ошибку, логированием её и посылкой письма. Первый клиент, который сгенерирует может увидеть 500 (хотя и не обязательно это будет 500, вполне вероятно что был вызов неопределенной функции, без которой остальные модули продолжат выполнять свои действия). Остальные пользователи ничего не почувствуют, кроме отсутствующего информера о погоде. Сложнее дело обстоит когда модуль является основным контентом
ну, идеальных решений не бывает впрочем я не работаю с плагинами сторонних разработчиков, так что данный топик был больше разминкой для ума
а зачем вообще перехватывать фатальные ошибки? из-за плагинов? так нафиг такие плагины нужны тогда... я лично юзаю такую штуку для фатальных ошибок: PHP: <?php error_reporting(E_ALL); ini_set('display_errors', 'off'); ini_set('html_errors', 'off'); ini_set('log_errors', 'on'); ini_set('error_log', LOG_FILE); ini_set('ignore_repeated_errors', 'off'); ini_set('ignore_repeated_source', 'on'); Всё остальное ловлю "перехватчиками"
Гм. Выдумывать "зачем" - можно бесконечно Например тот же ресайз картинок может обломаться даже если ты проверяешь размер изображения, только потому, что, как справедливо заметил выше topas, какая-то другая часть приложения съела нужную память Т.е. если у тебя отдельные части не изолированы друг от друга и выполняются в одном адресном пространстве тебе таки надо что-то делать с фатальными ошибками, которые могут возникнуть как результат синергии Но речь, вобщем-то, не столько о перехвате я уже писал. Просто мысль родилась как раз из топиков о перехвате фатальных ошибок. Но сама мысль - о изоляции отдельных процессов в приложении
говнокод какой то почему переносов так мало, отступы непонятно как стоят. читать код невозможно и вообще, где ЗендФреймвок?
использовал идею автора, теперь крит.ошибки выводятся нормальным сообщением. кст, не в курсе, если в этом операторе освободить часть памяти, по-unset-ив некоторые классы - туда вызов функции можно будет впихнуть?
Я впихивал. Но не факт что это всегда сработает. Ты почитай весь топик, там topas нашел более кошерный вариант.