web-dev-qa-db-fra.com

Comment envoyer une erreur 500 Internal Server error depuis un script PHP

Je dois envoyer "500 Internal Server Error" à partir d'un script PHP dans certaines conditions. Le script est censé être appelé par une application tierce. Le script contient quelques die("this happend") déclarations pour lesquelles je dois envoyer le 500 Internal Server Error code de réponse au lieu du code habituel 200 OK. Le script tiers enverra de nouveau la demande sous certaines conditions, notamment la non réception du message 200 OK Code de réponse.

Deuxième partie de la question: Je dois configurer mon script comme suit:

<?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 en-tête seulement après que la dernière ligne a été exécutée.

Modifier

Une question secondaire: puis-je envoyer d’étranges 500 en-têtes tels que ceux-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 seront-elles enregistrées par le serveur Web?

71
Salman A
header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error', true, 500);
161
Core Xii

PHP 5.4 a une fonction appelée http_response_code , donc si vous utilisez PHP 5.4, vous pouvez simplement 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 suivante, le RFC HTTP 1.1 indique:

Les expressions de raison énumérées ici ne sont que des recommandations - elles PEUVENT être remplacées par des équivalents locaux sans affecter le protocole.

Cela signifie que vous pouvez utiliser le texte de votre choix (à l'exception des retours à la ligne ou des sauts de ligne) après le code lui-même, et cela fonctionnera. En général, cependant, il existe généralement un meilleur code de réponse à utiliser. Par exemple, au lieu d’utiliser un 500 pour aucun enregistrement trouvé, vous pouvez envoyer un 404 (non trouvé), et pour quelque chose comme "conditions échouées" (je devine une erreur de validation), vous pourriez envoyer quelque chose comme un 422 (entité non traitable).

38
inxilpro

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);
33
Andrew Moore

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).

15
Ruel

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');
}
8
David Kuridža

Votre code devrait ressembler à:

<?php
if ( that_happened ) {
    header("HTTP/1.0 500 Internal Server Error");
    die();
}

if ( something_else_happened ) {
    header("HTTP/1.0 500 Internal Server Error");
    die();
}

// Your function should return FALSE if something goes wrong
if ( !update_database() ) {
    header("HTTP/1.0 500 Internal Server Error");
    die();
}

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


header('HTTP/1.1 200 OK');
?>

Je suppose que vous arrêtez l'exécution si quelque chose ne va pas.

2
Sébastien VINCENT