PHP Ölümcül Hata Yakalamak

5 Cevap php

Ben etkin dinlendirici bir web hizmeti sitesi var, bu nedenle diğer web siteleri / ajax script / set veri almak için siteye bir arama yapabilirsiniz. Web hizmeti sitesi nasılsa bir PHP ölümcül hata, döndürülen HTTP durumunu döndürür zaman Ancak, yerine 500 200'dür. Mı orada ölümcül bir hata oluştuğunda, 200 yerine 500 döndürür böylece bunu düzeltmek için bir yol? Bu mümkün değilse ya da, nasıl ben webcoder tarafından döndürülen ölümcül hata tanımak müvekkilimi değiştirebilirim?

5 Cevap

Mümkün bir yol (tehlikeli, denenmemiş) her şeyi başarıyla 200 tepkisini ayarlamak yürütür, 500 varsayılan yanıtı ayarlamak olacaktır

PHP does send a HTTP 500 on a Fatal error.
Let me cite a comment in this PHP bug-report (a xdebug bug prevents this behavior):

Oluyor. Bu gerektirir:

1) display_errors = off
2) No headers have been sent yet by the time the error happens
3) Status is 200 at that time.

<?
    ini_set('display_errors', 0); 
    foobar();
    // This will return a http 500
?>

Bir shutdown function ile ölümcül hataları yakalamak ve error_get_last yapabilirsiniz:

register_shutdown_function(function() {
    $lastError = error_get_last();

    if (!empty($lastError) && $lastError['type'] == E_ERROR) {
        header('Status: 500 Internal Server Error');
        header('HTTP/1.0 500 Internal Server Error');
    }
});

Bir özel hata işleyicisi (set_error_handler) ve çağrı oluşturma header("HTTP/1.0 500 Service not available");.

Edit:

Benim cevap için ilk yorum başına, tuzak doğru ölümcül hatalar olamaz. Çıktı tamponlama devre dışı bırakılır ve hatalar ekrana görüntülenen değilseniz Ancak, PHP ölümcül hataları bir 500 hata kodu ayarı için varsayılan olacaktır.

<?php
        $x = y();
?>

Hiçbir şey ekrana gönderildi eğer yukarıdaki kodu 500 hata kodu dönecektir.

Yani bu tür bir hata kendi tamponlama, doğru kod ayarlamak isterseniz:

<?php
        $buffer = 'blah';
        $x = y();  // will trigger 500 error
        echo $buffer;
?>

PHP tüm hata tipleri (hemen hemen tüm) yakalamak için bir yol geliştirdi! (Ben bu hata için çalışır olmayacağını düşünüyorum) E_CORE_ERROR konusunda hiç emin var! Ancak, diğer ölümcül hatalar (E_ERROR, E_PARSE, E_COMPILE ...) için bir hata işleyicisi işlevini sadece kullanmadan çalışıyor! Benim çözüm oraya gider:

Ana dosyası (index.php) bu aşağıdaki kodu koyun:

<?php

define('E_FATAL',  E_ERROR | E_USER_ERROR | E_PARSE | E_CORE_ERROR | 
        E_COMPILE_ERROR | E_RECOVERABLE_ERROR);

define('ENV', 'dev');

//Custom error handling vars
define('DISPLAY_ERRORS', TRUE);
define('ERROR_REPORTING', E_ALL | E_STRICT);
define('LOG_ERRORS', TRUE);

register_shutdown_function('shut');

set_error_handler('handler');

//Function to catch no user error handler function errors...
function shut(){

    $error = error_get_last();

    if($error && ($error['type'] & E_FATAL)){
        handler($error['type'], $error['message'], $error['file'], $error['line']);
    }

}

function handler( $errno, $errstr, $errfile, $errline ) {

    switch ($errno){

        case E_ERROR: // 1 //
            $typestr = 'E_ERROR'; break;
        case E_WARNING: // 2 //
            $typestr = 'E_WARNING'; break;
        case E_PARSE: // 4 //
            $typestr = 'E_PARSE'; break;
        case E_NOTICE: // 8 //
            $typestr = 'E_NOTICE'; break;
        case E_CORE_ERROR: // 16 //
            $typestr = 'E_CORE_ERROR'; break;
        case E_CORE_WARNING: // 32 //
            $typestr = 'E_CORE_WARNING'; break;
        case E_COMPILE_ERROR: // 64 //
            $typestr = 'E_COMPILE_ERROR'; break;
        case E_CORE_WARNING: // 128 //
            $typestr = 'E_COMPILE_WARNING'; break;
        case E_USER_ERROR: // 256 //
            $typestr = 'E_USER_ERROR'; break;
        case E_USER_WARNING: // 512 //
            $typestr = 'E_USER_WARNING'; break;
        case E_USER_NOTICE: // 1024 //
            $typestr = 'E_USER_NOTICE'; break;
        case E_STRICT: // 2048 //
            $typestr = 'E_STRICT'; break;
        case E_RECOVERABLE_ERROR: // 4096 //
            $typestr = 'E_RECOVERABLE_ERROR'; break;
        case E_DEPRECATED: // 8192 //
            $typestr = 'E_DEPRECATED'; break;
        case E_USER_DEPRECATED: // 16384 //
            $typestr = 'E_USER_DEPRECATED'; break;

    }

    $message = '<b>'.$typestr.': </b>'.$errstr.' in <b>'.$errfile.'</b> on line <b>'.$errline.'</b><br/>';

    if(($errno & E_FATAL) && ENV === 'production'){

        header('Location: 500.html');
        header('Status: 500 Internal Server Error');

    }

    if(!($errno & ERROR_REPORTING))
        return;

    if(DISPLAY_ERRORS)
        printf('%s', $message);

    //Logging error on php file error log...
    if(LOG_ERRORS)
        error_log(strip_tags($message), 0);

}

ob_start();

@include 'content.php';

ob_end_flush();

>

Bu birçok kişi yardımcı olur umarım! Ben bu çözüm çok uzun zamandır arıyor ve bulamadık! Sonra geliştirdi!

Ben çoğu kod hataları beri kayıp tüm geliştirme hataları, olmayan nesneleri içerir, uygulamayı dağıtmadan önce tüm Ölümcül hataları yakalamak ve düzeltmek isterdim düşünürdüm. Hatta out-of-bellek hatalarının bellek (büyük kazançlarından biri tamponsuz sorguları kullanarak ve veri işleme ve resultset yerine etrafında büyük diziler atma, döndürülür olarak çıktı yayan) tutumlu kodlama teknikleri ile karşı minimize edilebilir.