web-dev-qa-db-fra.com

Comment renvoyer un code HTTP 500 en cas d'erreur, peu importe ce que

J'écris un script d'authentification en PHP, à appeler comme une API, qui doit renvoyer 200 only in the case that it approves the request, and 403 (Forbidden) or 500` sinon.

Le problème que je rencontre est que php renvoie 200 Dans le cas de conditions d'erreur, produisant l'erreur à la place en html. Comment puis-je être absolument sûr que php renverra un code HTTP 500 À moins que je ne 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, sans exception, afin que le cas par défaut rejette la demande d'authentification et que l'exception l'approuve avec un 200 code.

J'ai joué avec set_error_handler() et error_reporting(), mais jusqu'à présent, pas de chance. Par exemple, si le code génère quelque chose avant d'envoyer 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, cela est signalé par PHP comme code de réponse 200 Avec html expliquant le problème. J'ai même besoin de ce genre de chose pour être transformé en un code 500.

Est-ce possible en PHP? Ou dois-je le faire à un niveau supérieur, comme utiliser mod_rewrite D'une manière ou d'une autre? Si tel est le cas, avez-vous une idée de la façon dont je procéderais?

45
Jake

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

20
Jake

Envoyez simplement le code d'état comme réponse header() :

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

N'oubliez pas que lors de l'envoi, il ne doit y avoir aucune sortie avant. Cela signifie pas d'appels echo et pas de HTML ni d'espace.

75
BoltClock

Depuis PHP 5.4.0 il y a une fonction spécialisée:

<?php http_response_code( 500 ); ?>

Assurez-vous simplement qu'il est appelé avant toute autre sortie.

Référence:

15
Martin M

Sur la page php de set_error_handler (), vous pouvez trouver un commentaire de smp sur ncoastsoft dot com posté le 08-Sep-2003 10:28 qui explique comment même détecter les erreurs fatales (que vous ne pouvez normalement pas détecter 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 attrape l'erreur fatale de la fonction inexistante. Il retourne alors un 500 et arrête l'exécution du reste du script.

11
2ndkauboy
header($_SERVER['SERVER_PROTOCOL'] . ' 403 Forbidden');

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

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

4
Artefacto

Curieux si vous avez déjà compris comment obtenir PHP pour renvoyer 500 sur les erreurs d'analyse ... J'ai le même besoin exact ... L'API publie sur notre application et attend 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 lorsqu'une erreur "d'analyse/syntaxe" se produit dans le code ...

Il s'agit donc d'une fonction de bas niveau PHP qui devrait être définie dans PHP.INI ou quelque part ... J'utilise PHP 5.3.10 ...

2
Patrick Steil

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
symcbean