85 votes

Comment envoyer une erreur 500 Internal Server error à partir d'un script PHP

J'ai besoin d'envoyer des "500 Internal Server Error" à partir d'un script PHP sous certaines conditions. Le script est censé être appelé par une application tierce. Le script contient un couple de die("this happend") de déclarations pour lesquelles j'ai besoin d'envoyer l' 500 Internal Server Error code de réponse au lieu de l'habituel 200 OK. La troisième partie du script de ré-envoyer la demande sous certaines conditions qui ne comprennent pas la réception de l' 200 OK code de réponse.

Deuxième partie de la question: j'ai besoin de configurer mon script comme ceci:

<?php
    custom_header( "500 Internal Server Error" );

    if ( that_happened ) {
        die( "that happened" )
    }

    if ( something_else_happened ) {
        die( "something else happened" )
    }

    update_database( );

    // the script can also fail on the above line
    // e.g. a mysql error occurred

    remove_header( "500" );
?>

J'ai besoin d'envoyer 200 - tête seulement après que la dernière ligne a été exécuté.

Modifier

D'un côté la question: puis-je envoyer étrange 500 les en-têtes comme celles-ci:

HTTP/1.1 500 No Record Found
HTTP/1.1 500 Script Generated Error (E_RECORD_NOT_FOUND)
HTTP/1.1 500 Conditions Failed on Line 23

Ces erreurs se connecté par le serveur web?

173voto

Core Xii Points 3095
header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error', true, 500);

48voto

inxilpro Points 3475

PHP 5.4 a une fonction appelée http_response_code, donc si vous êtes à l'aide de PHP 5.4, tu peux faire:

http_response_code(500);

J'ai écrit un polyfill pour cette fonction (Gist) si vous utilisez une version de PHP sous 5.4.


Pour répondre à votre question de suivi, le HTTP 1.1 RFC dit:

La raison expressions mentionnées ici ne sont que des recommandations, elles POURRONT être remplacés par des équivalents locaux sans affecter le protocole.

Cela signifie que vous pouvez utiliser n'importe quel texte que vous voulez (à l'exclusion des retours chariot ou des retours à la ligne), d'après le code lui-même, et ça marchera. En règle générale, cependant, il ya habituellement une meilleure réponse code à utiliser. Par exemple, au lieu d'utiliser un 500 pour aucun dossier trouvé, vous pouvez envoyer un 404 (non trouvé), et pour quelque chose comme "conditions échec" (je suppose une erreur de validation), vous pouvez envoyer quelque chose comme un 422 (unprocessable entité).

34voto

Andrew Moore Points 49765

Vous pouvez utiliser la fonction suivante pour envoyer un changement de statut:

 function header_status($statusCode) {
    static $status_codes = null;

    if ($status_codes === null) {
        $status_codes = array (
            100 => 'Continue',
            101 => 'Switching Protocols',
            102 => 'Processing',
            200 => 'OK',
            201 => 'Created',
            202 => 'Accepted',
            203 => 'Non-Authoritative Information',
            204 => 'No Content',
            205 => 'Reset Content',
            206 => 'Partial Content',
            207 => 'Multi-Status',
            300 => 'Multiple Choices',
            301 => 'Moved Permanently',
            302 => 'Found',
            303 => 'See Other',
            304 => 'Not Modified',
            305 => 'Use Proxy',
            307 => 'Temporary Redirect',
            400 => 'Bad Request',
            401 => 'Unauthorized',
            402 => 'Payment Required',
            403 => 'Forbidden',
            404 => 'Not Found',
            405 => 'Method Not Allowed',
            406 => 'Not Acceptable',
            407 => 'Proxy Authentication Required',
            408 => 'Request Timeout',
            409 => 'Conflict',
            410 => 'Gone',
            411 => 'Length Required',
            412 => 'Precondition Failed',
            413 => 'Request Entity Too Large',
            414 => 'Request-URI Too Long',
            415 => 'Unsupported Media Type',
            416 => 'Requested Range Not Satisfiable',
            417 => 'Expectation Failed',
            422 => 'Unprocessable Entity',
            423 => 'Locked',
            424 => 'Failed Dependency',
            426 => 'Upgrade Required',
            500 => 'Internal Server Error',
            501 => 'Not Implemented',
            502 => 'Bad Gateway',
            503 => 'Service Unavailable',
            504 => 'Gateway Timeout',
            505 => 'HTTP Version Not Supported',
            506 => 'Variant Also Negotiates',
            507 => 'Insufficient Storage',
            509 => 'Bandwidth Limit Exceeded',
            510 => 'Not Extended'
        );
    }

    if ($status_codes[$statusCode] !== null) {
        $status_string = $statusCode . ' ' . $status_codes[$statusCode];
        header($_SERVER['SERVER_PROTOCOL'] . ' ' . $status_string, true, $statusCode);
    }
}
 

Vous pouvez l'utiliser comme tel:

 <?php
header_status(500);

if (that_happened) {
    die("that happened")
}

if (something_else_happened) {
    die("something else happened")
}

update_database();

header_status(200);
 

16voto

Ruel Points 6140

Vous pouvez simplement mettre:

 header("HTTP/1.0 500 Internal Server Error");
 

dans vos conditions comme:

 if (that happened) {
    header("HTTP/1.0 500 Internal Server Error");
}
 

En ce qui concerne la requête de base de données, vous pouvez simplement le faire comme ceci:

 $result = mysql_query("..query string..") or header("HTTP/1.0 500 Internal Server Error");
 

Vous devez vous rappeler que vous devez mettre ce code avant toute balise HTML (ou sortie).

8voto

David Kuridža Points 2395

Vous pouvez le simplifier comme ceci:

 if ( that_happened || something_else_happened )
{
    header('X-Error-Message: Incorrect username or password', true, 500);
    die;
}
 

Il retournera l'en-tête suivant:

 HTTP/1.1 500 Internal Server Error
...
X-Error-Message: Incorrect username or password
...
 

Ajouté: Si vous avez besoin de savoir exactement ce qui ne va pas, procédez comme ceci:

 if ( that_happened )
{
    header('X-Error-Message: Incorrect username', true, 500);
    die('Incorrect username');
}

if ( something_else_happened )
{
    header('X-Error-Message: Incorrect password', true, 500);
    die('Incorrect password');
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X