Comment envoyer 500 Erreur D'erreur de serveur interne à partir d'un script PHP

J'ai besoin d'envoyer "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 quelques instructions die("this happend") pour lesquelles j'ai besoin d'envoyer le code de réponse 500 Internal Server Error au lieu de l'habituel 200 OK. Le script tiers enverra à nouveau la requête sous certaines conditions, notamment en ne recevant pas le code de réponse 200 OK.

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

<?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 l'en-tête 200 seulement après l'exécution de la dernière ligne.

Modifier

Une question secondaire: puis-je envoyer des en-têtes 500 étranges 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

De telles erreurs seront-elles enregistrées par le serveur web?

64
demandé sur pnuts 2010-11-12 09:40:38

6 réponses

header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error', true, 500);
150
répondu Core Xii 2010-11-12 06:47:40

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 de suivi, la RFC HTTP 1.1 dit:

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

, ce Qui signifie que vous peut utiliser le texte que vous voulez (à l'exclusion des retours chariot ou des flux de ligne) après le code lui-même, et cela fonctionnera. En général, cependant, il y a généralement un meilleur code de réponse à utiliser. Par exemple, au lieu d'utiliser un 500 pour aucun dossier trouvé, vous pouvez envoyer un 404 (pas trouvé), et pour quelque chose comme "conditions échec" (je suppose une erreur de validation), vous pouvez envoyer quelque chose comme un 422 (unprocessable entité).

34
répondu inxilpro 2014-02-26 12:41:58

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);
31
répondu Andrew Moore 2010-11-12 06:47:19

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

14
répondu Ruel 2010-11-12 06:48:21

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 a mal tourné, faites quelque chose 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
répondu David Kuridža 2013-01-08 10:27:18

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.

1
répondu Sébastien VINCENT 2010-11-12 06:48:09