webentwicklung-frage-antwort-db.com.de

Wie kann ich erreichen, dass PHP 500 bei einer fatalen Ausnahme zurückkommt?

Schwerwiegende PHP-Fehler werden als Statuscode 200 an den HTTP-Client zurückgegeben. Wie kann ich einen Statuscode 500 (Interner Serverfehler) zurückgeben lassen?

47
Mike
header("HTTP/1.1 500 Internal Server Error");
49

Dies ist genau das Problem, das ich gestern hatte und ich habe die Lösung wie folgt gefunden:

1) Zuerst müssen Sie schwerwiegende PHP Fehler abfangen. Dies ist der Fehlertyp E_ERROR. Wenn dieser Fehler auftritt, wird das Skript gespeichert und die Ausführung abgebrochen. Sie können den gespeicherten Fehler abrufen, indem Sie die Funktion error_get_last () aufrufen.

2) Bevor das Skript beendet wird, wird immer eine Callback-Funktion register_shutdown_function () aufgerufen. Sie müssen also einen Fehlerbehandler mit dieser Funktion registrieren, um das zu tun, was Sie möchten. In diesem Fall geben Sie den Header 500 und eine angepasste interne Fehlerseite (optional) zurück.

function my_error_handler()
{
  $last_error = error_get_last();
  if ($last_error && $last_error['type']==E_ERROR)
      {
        header("HTTP/1.1 500 Internal Server Error");
        echo '...';//html for 500 page
      }
}
register_shutdown_function('my_error_handler');

Anmerkung: Wenn Sie einen benutzerdefinierten Fehlertyp abfangen möchten, der mit E_USER * beginnt, können Sie die Funktion set_error_handler () verwenden, um den Fehlerhandler zu registrieren und den Fehler über die Funktion trigger_error auszulösen. Dieser Fehlerhandler kann jedoch den E_ERROR-Fehlertyp nicht verarbeiten. siehe Erklärung auf php.net über Fehlerbehandlung

22
fuyi

Ich habe "set_exception_handler" verwendet, um nicht erfasste Ausnahmen zu behandeln.

function handleException($ex) {
      error_log("Uncaught exception class=" . get_class($ex) . " message=" . $ex->getMessage() . " line=" . $ex->getLine());
      ob_end_clean(); # try to purge content sent so far
      header('HTTP/1.1 500 Internal Server Error');
      echo 'Internal error';
    }

set_exception_handler('handleException');
4
Matti Haavikko

Es ist nicht möglich, mit PHP E_ERROR auf irgendeine Weise gemäß der PHP -Dokumentation zu verfahren: http://www.php.net/manual/de/function.set-error- handler.php

Es ist auch nicht möglich, "E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING und die meisten E_STRICT" entsprechend diesem Link zu behandeln.

Sie können zwar einen Handler für die anderen Fehler, Warnungen und Hinweise einschließlich E_USER_ERROR bereitstellen, aber das ist wirklich nicht so nützlich, wie es sich anhört, da dieser Fehler nur vom Programmierer absichtlich mit trigger_error () ausgelöst wird.

Und natürlich können Sie jede Ausnahme (auch die von den nativen PHP - Funktionen geworfenen) fangen.

Ich stimme zu, dass dies ein Problem ist. Server sollten NICHT 200 OK zurückgeben, wenn der Anwendungscode abstürzt und brennt.

3
Jonathan Hanson

Standard PHP Konfiguration gibt zurück, wenn ein Fehler auftritt! Stellen Sie einfach sicher, dass Ihre display_errors = aus ist. Sie können es simulieren mit:

ini_set('display_errors', 0); 
noFunction();

Bei der Produktion ist die Direktive display_errors standardmäßig deaktiviert.

3
lukyer

Beim Umgang mit schwerwiegenden Fehlern (Kompilierfehler, z. B. fehlendes Semikolon) ist es schwierig, dass das Skript nicht ausgeführt wird. Daher kann der Statuscode in diesem Skript nicht festgelegt werden. Wenn Sie jedoch ein Skript einschließen oder anfordern, wird das aufrufende Skript unabhängig von Fehlern im enthaltenen Skript ausgeführt. Damit komme ich zu dieser Lösung:

rock-solid-script.php:

// minimize changes to this script to keep it rock-solid
http_response_code(500); // PHP >= 5.4
require_once("script-i-want-to-guard-for-errors.php");

script-i-want-to-guard-for-errors.php:

// do all the processsing
// don't produce any output
// you might want to use output buffering

http_response_code(200); // PHP >= 5.4

// here you can produce the output

Richten Sie Ihren Anruf an die rock-solid-script.php und Sie können loslegen.

Es wäre mir lieber gewesen, wenn ich den Standardstatuscode in .htaccess auf 500 gesetzt hätte. Das erscheint mir eleganter, aber ich finde keinen Weg, es zu schaffen. Ich habe das RewriteRule-R-Flag ausprobiert, aber dies verhindert die vollständige Ausführung von PHP, so dass es keinen Sinn macht. 

1
Remco Nijhuis

Sie können PHP-Fehlerbehandlung verwenden 

http://www.w3schools.com/php/php_error.asp

0
Xinus

Vergessen Sie niemals, header("HTTP/1.1 200 OK", true, 200); als letzte Zeile eines Ausführungspfads festzulegen:

//first things first:
header("HTTP/1.1 500 Internal Server Error", true, 500);


//Application code, includes, requires, etc. [...]


//somewhere something happens
//die();
throw new Exception("Uncaught exception!");


//last things last, only reached if code execution was not stopped by uncaught exception or some fatal error
header("HTTP/1.1 200 OK", true, 200);

In PHP 5.4 können Sie die header-Funktion oben durch die wesentlich bessere http_response_code(200) oder http_response_code(500) ersetzen.

0

Sie müssten den geworfenen Fehler mit try/catch abfangen und dann diesen catch-Block verwenden, um einen header () mit dem 500-Fehler zu senden.

try {
    ...badcode...
    throw new Exception('error');

} catch (Exception $e) {

    header("Status: 500 Server Error");
    var_dump($e->getMessage());
}

Wenn die schwerwiegende Ausnahme nicht von try {} catch-Blöcken umgeben ist, müssen Sie einen globalen Handler registrieren und mithilfe von register_shutdown_function() am Ende des Skripts nach einem Fehler suchen.

0
Xeoncross