Tôi phải thiếu điều gì đó trong sự hiểu biết của mình về việc xử lý lỗi PHP, đặc biệt loại bỏ đầu ra của chúng. Khi một lỗi nghiêm trọng xảy ra, tôi mong đợi chức năng xử lý tắt máy của tôi xử lý nó một cách duyên dáng và chấm dứt thực thi tập lệnh. Điều này hoạt động như mong đợi. Tuy nhiên, tôi không thể ngăn chặn PHP xuất ra thông tin về lỗi nghiêm trọng.Ngăn chặn đầu ra traceback lỗi gây tử vong PHP khi sử dụng trình xử lý tắt tùy chỉnh
file php.ini của tôi chứa các chỉ dẫn sau:
error_reporting = E_ALL | E_STRICT
display_errors = Off
tôi đặt error_reporting
báo cáo tất cả mọi thứ và tôi sử dụng một lỗi xử lý tùy chỉnh để ném ngoại lệ. Kỳ vọng của tôi là display_errors = Off
sẽ ngăn chặn bất kỳ thông báo lỗi nào được hiển thị.
Dù sao, khi xảy ra lỗi nghiêm trọng, trình xử lý lỗi tùy chỉnh bị bỏ qua (vì thực thi tập lệnh dừng ngay lập tức) và trình xử lý tắt sẽ thực thi.
Bây giờ, trên mã đơn giản của tôi:
error_reporting(E_ALL | E_STRICT);
ini_set('display_errors', 'Off');
function shutdown_handler()
{
$err = error_get_last();
$fatal = array(E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR);
if ($err && in_array($err['type'], $fatal)) {
echo "\n\ntest fatal error output\n\n";
}
exit();
}
register_shutdown_function('shutdown_handler');
Để kiểm tra nó, tôi tạo ra một "kích thước bộ nhớ phép kiệt sức" lỗi nghiêm trọng như vậy:
// max out available memory
$data = '';
while(true) {
$data .= str_repeat('#', PHP_INT_MAX);
}
Bởi vì tôi có display_errors = Off
Tôi hy vọng điều này để chỉ tạo ra kết quả sau (theo trình xử lý tắt máy):
test fatal error output
Nhưng thay vào đó, tôi tiếp tục nhận được:
PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 2147483648 bytes) in /home/daniel/mydev/php/test0.php on line 24
PHP Stack trace:
PHP 1. {main}() /home/daniel/mydev/php/test0.php:0
PHP 2. str_repeat() /home/daniel/mydev/php/test0.php:24
test fatal error output
Tôi thiếu điều gì sẽ ngăn chặn lỗi này khi xuất ra?
KẾT LUẬN
Có vẻ như @Cthos sagely lưu ý, rằng "E_ERROR và display_errors không chơi độc đáo với nhau."
Đây cũng là trường hợp của E_PARSE (và tôi giả định E_CORE_ERROR/E_COMPILE_ERROR, nhưng tôi đã không ngắt cài đặt PHP của mình để kiểm tra nó). Tôi cho rằng nó có ý nghĩa rằng PHP sẽ buộc các traceback lỗi vào STDOUT trong những trường hợp này bởi vì nếu nó không bạn có thể không bao giờ biết nếu/tại sao mọi thứ đã đi sai.
Vì vậy, một giải pháp trong trường hợp này sẽ là:
- Như @Cthos gợi ý, im lặng E_ERROR thông báo trong php.ini:
error_reporting = (E_ALL & ~ E_ERROR)
hoặc khi chạy bằngerror_reporting(E_ALL & ~ E_ERROR);
- Cập nhật xử lý tắt máy để kiểm tra xem cuối cùng lỗi là loại E_ERROR và thực hiện các hành động thích hợp nếu có.
Đối với các phần tử gây tử vong khác như E_PARSE, E_CORE_ERROR, v.v. bạn chỉ cần đảm bảo mã của bạn là chính xác và PHP của bạn hoạt động. Nếu bạn cố gắng im lặng E_PARSE lỗi và xử lý chúng trong chức năng tắt máy của bạn nó sẽ không hoạt động vì lỗi phân tích cú pháp ngăn chặn PHP từ bao giờ nhận được rằng đến nay.
Vì vậy, một cập nhật/xử lý tắt máy làm việc trông như thế này:
error_reporting(E_ALL & ~ E_ERROR);
function shutdown_handler()
{
$err = error_get_last();
if ($err && $err['type'] == E_ERROR) {
$msg = 'PHP Fatal Error: '.$err['message'].' in '.$err['file'].
' on line '.$err['line'];
echo $msg, PHP_EOL;
}
exit();
}
Mayhap bạn nên có trình xử lý lỗi tùy chỉnh thay thế? http://www.php.net/manual/en/function.set-error-handler.php – Cthos
@Cthos - khi trạng thái câu hỏi, tôi đã sử dụng trình xử lý lỗi tùy chỉnh. Khi một lỗi nghiêm trọng xảy ra, việc thực thi tập lệnh dừng ngay lập tức và trình xử lý lỗi tùy chỉnh không được gọi. Tuy nhiên, trình xử lý tắt máy tùy chỉnh vẫn có thể chạy. – rdlowrey
Hrm, tôi đã thất bại trong việc đọc hiểu rồi, tuy nhiên tôi đã nghĩ Fatals vẫn sẽ đi đến xử lý nói. Thời gian thử nghiệm. – Cthos