2010-10-01 16 views
23

Tôi muốn có thể xem các thông báo die()exit(). Điều này có thể không? Tôi đang hy vọng cho một cái gì đó tương tự như set_error_handlerset_exception_handler. Tôi đã xem register_shutdown_function() nhưng có vẻ như không chứa ngữ cảnh cho các cuộc gọi die()exit() vi phạm.Tôi có thể nhận các thông báo thoát() và die() không?

Tôi nhận thấy rằng die()exit() là những cách xấu để xử lý lỗi. Tôi không muốn được bảo không làm điều này. :) Tôi đang tạo một hệ thống chung và muốn có thể đăng nhập một cách duyên dáng exit()die() nếu vì lý do nào đó mà một người nào đó (không phải tôi) quyết định đây là một ý tưởng hay để làm.

Trả lời

4

Tốt nhất là tôi có thể nói điều này là không thực sự có thể. Một số giải pháp được đăng ở đây có thể hoạt động nhưng chúng yêu cầu nhiều công việc bổ sung hoặc nhiều phụ thuộc. Không có cách nào để dễ dàng và đáng tin cậy bẫy các thông điệp die() và exit().

+0

Vâng, nó có thể bằng cách viết lại kịch bản trong khi bạn đọc nó. Ví dụ sau tokenizes đầu vào và viết lại lối ra ($ code) và chết $ code để php_exit ($ code): EDIT: stackoverflow không cho phép tôi thêm mã ở đây, xem bài đăng này cho cảm hứng: http://stackoverflow.com/questions/31182968/token-get-all-back-to-php-source-how-to – user1135940

7

Theo PHP manual, các chức năng tắt máy sẽ vẫn được thông báo khi die() hoặc exit() được gọi.

Shutdown functionsobject destructors sẽ luôn được thực thi ngay cả khi exit() được gọi.

Dường như không thể nhận trạng thái được gửi khi thoát (trạng thái $). Trừ khi bạn có thể sử dụng bộ đệm đầu ra để nắm bắt nó, nhưng tôi không chắc chắn làm thế nào bạn sẽ biết khi nào để gọi ob_start().

+3

Tôi đoán vấn đề của OP là anh ấy muốn có thể truy xuất thông báo lỗi từ chức năng tắt máy. – casablanca

+0

Chức năng tắt máy đang được gọi, nhưng tôi không chắc chắn liệu/làm thế nào tôi có thể nhận được bối cảnh thoát/chết tại thời điểm đó. Cho rằng vấn đề, nó không rõ ràng nếu tôi thậm chí biết nếu lối ra/chết là lý do cho chức năng tắt máy được gọi. (nó trông giống như chức năng tắt máy được gọi là chết, nhưng nó được gọi khi quá trình chấm dứt sau khi chạy thành công ...) –

5

lẽ override_function() có thể là thú vị, nếu APD có sẵn

+0

Đây là một ý tưởng thú vị! Hy vọng cho một giải pháp không APD tốt hơn, mặc dù. –

+0

Tôi không nghĩ rằng nó sẽ hoạt động. 'die' và' exit' là các cấu trúc ngôn ngữ, không phải các hàm. –

-2

yes: viết một chức năng và sử dụng thay thế.

function kill($msg){ 
    // Do your logging.. 
    exit($msg); 
} 
+7

Tôi đánh giá cao phản hồi, nhưng điều này không hữu ích chút nào. Tôi muốn bắt exit() và die() trong trường hợp một số mã tôi đã không viết cuộc gọi cho họ. –

+0

tôi biết nhưng đó là gần nhất bạn có thể nhận được nó, chỉ cần một chức năng mới và tìm kiếm đơn giản và thay thế từ lối ra và chết để giết .. –

0

Tại sao không sử dụng xử lý lỗi tùy chỉnh thay thế? Nếu không, bạn luôn có thể sử dụng LD_PRELOAD và C Mã tiêm để bắt nó :) Hoặc biên dịch lại php với các tùy chỉnh của bạn: P

7

Có bạn có thể, nhưng bạn cần ob_start, ob_get_contents, ob_end_cleanregister_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 
0

Nếu bạn sử dụng các điểm duy nhất của phương pháp nhập cảnh. (Index.php) Tôi có thể đề nghị này để xử lý lỗi của bạn:

phiên bản ngắn:

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 
    } 
} 

Các bước bổ sung và chi tiết hơn:

Khoảng cách của tôi làm việc đó. Tôi thậm chí còn có nhiều thứ đang diễn ra ở đây (xử lý các giao dịch cơ sở dữ liệu/rollback/gửi e-mail/viết nhật ký/hiển thị thông báo lỗi thân thiện/báo cáo lỗi người dùng/etc), nhưng đây là ý tưởng cơ bản đằng sau tất cả).
Hy vọng nó sẽ giúp ai đó.

<?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 
    } 

    // 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; 
    } 
Các vấn đề liên quan