Могу ли я перехватить сообщения exit () и die ()?

Я хотел бы быть в состоянии пойматьdie() а такжеexit() Сообщения. Это возможно? Я надеюсь на что-то похожее наset_error_handler а такжеset_exception_handler, Я смотрел наregister_shutdown_function() но, похоже, не содержит контекста для обидчикаdie() а такжеexit() звонки.

Я понимаю чтоdie() а такжеexit() плохие способы обработки ошибок. Я не ищу, чтобы мне сказали не делать этого. :) Я создаю общую систему и хочу иметь возможность изящно войтиexit() а такжеdie() если по какой-то причине кто-то (не я) решит, что это хорошая идея.

Ответы на вопрос(7)

написать функцию и использовать ее вместо этого.

function kill($msg){
    // Do your logging..
    exit($msg);
}
 JamesM-SiteGen01 окт. 2010 г., 07:36
я знаю, но это самое близкое, что вы можете получить к нему, только одна новая функция и простой поиск и замена из выхода и умереть, чтобы убить ..
 Beau Simensen01 окт. 2010 г., 07:22
Я ценю ответ, но это не помогает вообще. Я хочу поймать exit () и die () в случае, если какой-то код, который я не написал, вызывает их.

ок? Если нет, вы всегда можете использовать LD_PRELOAD и внедрение кода C, чтобы поймать его :) Или перекомпилировать php с вашими настройками: P

Да можно, но нужноob_start, ob_get_contents, ob_end_clean а такжеregister_shutdown_function

function onDie(){
    $message = ob_get_contents(); // Capture 'Doh'
    ob_end_clean(); // Cleans output buffer
    callWhateverYouWant();
}
register_shutdown_function('onDie');
//...
ob_start(); // You need this to turn on output buffering before using die/exit
@$dumbVar = 1000/0 or die('Doh'); // "@" prevent warning/error from php
//...
ob_end_clean(); // Remember clean your buffer before you need to use echo/print

Руководство по PHP, функции завершения должны по-прежнему уведомляться при вызове die () или exit ().

Функции выключения а такжедеструкторы объекта всегда будет выполняться, даже если вызывается exit ().

Кажется, невозможно получить статус, отправленный при выходе ($ status). Если вы не можете использовать буферизацию вывода, чтобы захватить его, но я не уверен, как вы узнаете, когда вызыватьob_start().

 casablanca01 окт. 2010 г., 06:35
Я предполагаю, что проблема ОП заключается в том, что он хотел бы получить сообщение об ошибке из функции выключения.
 Beau Simensen01 окт. 2010 г., 07:24
Вызывается функция выключения, но я не уверен, смогу ли я / как получить контекст exit / die в этой точке. В этом отношении, было неясно, если бы я даже знал, является ли выход / die причиной вызова функции shutdown. (похоже, что функция shutdown вызывается на die, но вызывается, когда процесс завершается и после успешного запуска ...)
Решение Вопроса

это на самом деле невозможно. Некоторые из представленных здесь решений могут работать, но они требуют много дополнительной работы или многих зависимостей. Нет способа легко и надежно перехватить сообщения die () и exit ().

 user113594022 мар. 2017 г., 20:36
Ну, это возможно, переписав сценарий, пока вы его читаете. В следующем примере токенизируется ввод и переписывается выход ($ code) и умирает $ code в php_exit ($ code): EDIT: stackoverflow не позволяет мне добавлять код здесь, см. Этот пост для вдохновения:stackoverflow.com/questions/31182968/...

override_function () может быть интересно, если APD доступен

 J.D.22 мар. 2014 г., 22:42
Я не думаю, что это сработает.die а такжеexit являются языковыми конструкциями, а не функциями.
 Beau Simensen01 окт. 2010 г., 07:27
Это интересная идея! Надеясь на лучшее решение без APD, все же.

ендовать это для вашей обработки ошибок:

Укороченная версия:

ob_start();
register_shutdown_function('shutdownHandler');

include('something');

define(CLEAN_EXIT, true);

function shutdownHandler() {
    if(!defined("CLEAN_EXIT") || !CLEAN_EXIT) {
        $msg = "Script stopped unexpectedly: ".ob_get_contents();
        //Handle premature die()/exit() here
    }
}

Дополнительные шаги и более подробно:

Примерно мой способ сделать это. У меня даже больше, чем я показываю здесь (обработка транзакций базы данных / откат / отправка электронной почты / запись журналов / отображение дружественных сообщений об ошибках / отчеты об ошибках пользователей / и т. Д.), Но это основная идея, лежащая в основе всего этого).
Надеюсь, это кому-нибудь поможет.

<?php

    //Some initialization

    //starting output buffering. (fatalErrorHandler is optional, but I recommend using it) 
    ob_start('fatalErrorHandler');

    //Execute code right at the end. Catch exit() and die() here. But also all other terminations inside PHPs control
    register_shutdown_function('shutdownHandler');

    //handling other errors: Also optional
    set_error_handler('errorHandler');



    try {
        //Include of offensive code
        include(...);
    }
    catch (Exception $ex) {
        //Handling exception. Be careful to not raise exceptions here again. As you can end up in a cycle. 
    }

    //Code reached this point, so it was a clean exit.
    define(CLEAN_EXIT, true);


    //Gets called when the script engine shuts down.
    function shutdownHandler() {

        $status = connection_status();

        $statusText = "";

        switch ($status) {
            case 0:
                if (!defined("CLEAN_EXIT") || !CLEAN_EXIT) {
                                    $msg = "Script stopped unexpectedly: ".ob_get_contents();
                    //Handle premature die()/exit() here
                }
                else {
                    //Clean exit. Just return
                    return;
                }
            case 1: $statusText = "ABORTED (1)"; break;
            case 2: $statusText = "TIMEOUT (2)"; break;
            case 3: $statusText = "ABORTED & TIMEOUT (3)"; break;

            default : $statusText = "UNKNOWN ($status)"; break;
        }

        //Handle other exit variants saved in $statusText here ob_get_contents() can have additional useful information here
    }

    // error handler function  (This is optional in your case)
    function errorHandler($errno, $errstr, $errfile, $errline) {

        $msg = "[$errno] $errstr\nOn line $errline in file $errfile";

        switch ($errno) {
            case E_ERROR:               $msg = "[E_ERROR] ".$msg;               break;
            case E_WARNING:             $msg = "[E_WARNING] ".$msg;             break;
            case E_PARSE:               $msg = "[E_PARSE] ".$msg;               break;
            case E_NOTICE:              $msg = "[E_NOTICE] ".$msg;              break;
            case E_CORE_ERROR:          $msg = "[E_CORE_ERROR] ".$msg;          break;
            case E_CORE_WARNING:        $msg = "[E_CORE_WARNING] ".$msg;        break;
            case E_COMPILE_ERROR:       $msg = "[E_COMPILE_ERROR] ".$msg;       break;
            case E_COMPILE_WARNING:     $msg = "[E_COMPILE_WARNING] ".$msg;     break;
            case E_USER_ERROR:          $msg = "[E_USER_ERROR] ".$msg;          break;
            case E_USER_WARNING:        $msg = "[E_USER_WARNING] ".$msg;        break;
            case E_USER_NOTICE:         $msg = "[E_USER_NOTICE] ".$msg;         break;
            case E_STRICT:              $msg = "[E_STRICT] ".$msg;              break;
            case E_RECOVERABLE_ERROR:   $msg = "[E_RECOVERABLE_ERROR] ".$msg;   break;
            case E_DEPRECATED:          $msg = "[E_DEPRECIATED] ".$msg;         break;
            case E_USER_DEPRICIATED:    $msg = "[E_USER_DEPRICIATED] ".$msg;    break;
            default:                    $msg = "[UNKNOWN] ".$msg;               break;
        }

        //Handle Normal error/notice/warning here. 
        $handled = ...

        if ($handled)
            return true; //handled. Proceed execution
        else
            throw Exception($msg); //Be careful. this might quickly become cyclic. Be sure to have code that catches and handles exceptions. Else die() here after logging/reporting the error.

    }

    function fatalErrorHandler(&$buffer) {

        $matches = null;
        //Checking if the output contains a fatal error
        if (preg_match('/<br \/>\s*<b>([^<>].*)error<\/b>:(.*)<br \/>$/', $buffer, $matches) ) {

            $msg = preg_replace('/<.*?>/','',$matches[2]);

            //Handle Fatal error here

            return "There was an unexpected situation that resulted in an error. We have been informed and will look into it."
         }

         //No fatal exception. Return buffer and continue
         return $buffer;
    }

Ваш ответ на вопрос