代码之家  ›  专栏  ›  技术社区  ›  Beau Simensen

我能捕捉exit()和die()消息吗?

  •  28
  • Beau Simensen  · 技术社区  · 16 年前

    我希望能赶上 die() 和 exit() 信息。这可能吗?我希望有类似的东西 set_error_handler 和 set_exception_handler . 我看过 register_shutdown_function() 但它似乎没有包含冒犯的背景 死亡() 退出() 电话。

    我知道 死亡() 和 退出() 是处理错误的坏方法。我不希望别人告诉我不要这样做。:)我正在创建一个通用系统,希望能够优雅地登录 退出() 和 死亡() 如果出于某种原因某人(不是我)认为这是个好主意。

    7 回复  |  直到 16 年前
        1
  •  12
  •   return true    10 年前

    , ob\u get_内容 , 干净干净 和

    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
    
        2
  •  7
  •   Alex King    16 年前

    根据 PHP manual ,在调用die()或exit()时,仍应通知关闭函数。

    Shutdown functions object destructors

    似乎不可能在exit($status)中发送状态。除非您可以使用输出缓冲来捕获它,但我不确定您如何知道何时调用 ob_start() .

        3
  •  5
  •   Dr.Molle    16 年前

    override_function() 如果有APD的话会很有趣

        4
  •  4
  •   Beau Simensen    15 年前

    据我所知,这是不可能的。这里发布的一些解决方案可能有效,但它们需要大量额外的工作或许多依赖关系。无法轻松可靠地捕获die()和exit()消息。

        5
  •  0
  •   flaab    16 年前

    为什么不改用自定义错误处理呢?如果没有,您可以始终使用ldunpreload和C代码注入来捕获它:)或者使用您的定制重新编译php:P

        6
  •  0
  •   Torge    8 年前

    短版:

    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;
        }
    
        7
  •  -3
  •   JamesM-SiteGen    16 年前

    function kill($msg){
        // Do your logging..
        exit($msg);
    }
    
    推荐文章