Comment renvoyer un code HTTP 500 en cas d'erreur, quoi qu'il arrive

J'écris un script d'authentification en PHP, à appeler en tant QU'API, qui doit retourner 200only in the case that it approves the request, and403(Forbidden) or500` sinon.

Le problème que je rencontre est que php retourne 200 dans le cas de conditions d'erreur, en sortant l'erreur en html à la place. Comment puis-je m'assurer absolument que php retournera un code HTTP 500 sauf si je retourne explicitement le HTTP 200 ou HTTP 403 moi-même? En d'autres termes, je veux transformer toutes les conditions d'avertissement ou d'erreur en 500 s, Non exceptions, de sorte que le cas par défaut rejette la demande d'authentification et que l'exception l'approuve avec un code 200.

J'ai bricolé avec set_error_handler() et error_reporting(), mais jusqu'à présent aucune chance. Par exemple, si le code sort quelque chose avant que j'envoie le code de réponse HTTP, PHP signale naturellement que vous ne pouvez pas modifier les informations d'en-tête après avoir sorti quoi que ce soit. Cependant, ceci est rapporté par PHP comme un code de réponse 200 avec html expliquant le problème. J'ai besoin de ce genre de chose être transformé en un code 500.

Est-ce possible en PHP? Ou dois-je le faire à un niveau plus élevé comme utiliser mod_rewrite d'une manière ou d'une autre? Si c'est le cas, une idée de comment j'aurais mis ça en place?

44
demandé sur gturri 2010-06-16 15:11:12

7 réponses

Il suffit d'envoyer le code d'état comme une réponse header():

header('HTTP/1.1 500 Internal Server Error');

Rappelez-vous que lors de l'envoi de ceci, ne doit pas être une sortie avant. Cela signifie aucun appel echo et aucun HTML ou espace.

70
répondu BoltClock 2010-06-16 11:12:35

J'ai vérifié Les docs PHP pour header () , et c'est plus simple que ce que je faisais - si le deuxième paramètre est vrai, il remplacera un en-tête similaire. la valeur par défaut est true. Donc, le comportement correct est header ('HTTP/1.1 403 Forbidden');, puis faites la logique d'authentification, puis s'il s'authentifie, faites header ('HTTP/1.1 200 OK'). Il remplacera la réponse 403, et garantira que 403 est la valeur par défaut.

20
répondu Jake 2013-10-14 14:16:38

Depuis PHP 5.4.0, il y a une fonction spezialized pour cela http_response_code() c'est-à-dire:

<?php
  http_response_code(404);
?>

Voir http://www.php.net/manual/en/function.http-response-code.php

13
répondu Martin M 2013-11-27 07:13:12

Sur la page php pour set_error_handler () vous pouvez trouver un commentaire de smp à ncoastsoft dot com Posté le 08-Sep-2003 10: 28 qui explique comment même attraper des erreurs fatales (que vous ne pouvez normalement pas attraper avec un gestionnaire d'erreur personnalisé. J'ai changé le code pour vos besoins:

error_reporting(E_ALL);
ini_set('display_errors', 'on');

function fatal_error_handler($buffer) {
    header('HTTP/1.1 500 Internal Server Error');
    exit(0);
}

function handle_error ($errno, $errstr, $errfile, $errline){
    header('HTTP/1.1 500 Internal Server Error');
    exit(0);
}

ob_start("fatal_error_handler");
set_error_handler("handle_error");

//would normally cause a fatal error, but instead our output handler will be called allowing us to handle the error.
somefunction();
ob_end_flush();

Ce shold capture l'erreur fatale de la fonction non existante. Il renvoie un 500 et arrête l'exécution du reste du script.

11
répondu 2ndkauboy 2010-06-16 19:40:47
header($_SERVER['SERVER_PROTOCOL'] . ' 403 Forbidden');

Vous ne devez pas utiliser 500, ce qui indique une erreur de serveur interne.

Ceci (et d'autres en-têtes) doit être envoyé avant toute sortie, sauf si la mise en mémoire tampon de sortie est activée.

5
répondu Artefacto 2010-06-16 11:13:13

Curieux si vous avez déjà compris comment obtenir que PHP retourne 500 sur les erreurs D'analyse... J'ai exactement le même besoin... API affiche sur notre application et attend un 200 seulement si tout a été traité correctement...

Dans le cas d'une erreur D'analyse, PHP renvoie une erreur 200 et j'ai utilisé ces deux fonctions:

Register_shutdown_function() set_error_handler()

Et ceux-ci ne sont pas touchés quand une erreur "parse/syntax" se produit dans le code...

Donc c'est un niveau bas Fonction PHP qui devrait être définie dans le PHP.INI ou quelque part... Je suis à l'aide de PHP 5.3.10...

2
répondu Patrick Steil 2013-01-05 16:42:13

Utilisez la mise en mémoire tampon de sortie pour vous permettre de modifier les en-têtes après avoir écrit dans le corps de la page. Vous pouvez définir cela dans le fichier ini plutôt que de mettre à jour chaque script.

(notez que l'appel header () échouera toujours si vous videz explicitement le tampon de sortie)

C.

1
répondu symcbean 2010-06-16 16:28:24