Je sais qu'il s'agit d'un vieux fil de discussion, mais lorsque j'ai fait une recherche sur Google, cette réponse est apparue en premier. J'essayais de comprendre comment le faire ces jours-ci, alors je pense que je devrais poster ma solution de contournement de 2018.
Comme vous le savez tous, non, vous ne pouvez pas simplement déclencher les pages d'erreur d'Apache à partir de PHP . Il n'y a pas moyen de le faire. Donc la meilleure solution que j'ai trouvée, après quelques recherches, est la suivante d'utiliser une fonction PHP pour afficher les pages d'erreur personnalisées qui est appelé à partir de ce que vous avez spécifié dans Apache, et de la page qui doit déclencher l'erreur 500 Internal Server Error.
Voici mon conf
d'Apache :
ErrorDocument 400 /error.php
ErrorDocument 401 /error.php
ErrorDocument 403 /error.php
ErrorDocument 404 /error.php
ErrorDocument 500 /error.php
Comme vous pouvez le constater, toutes les erreurs 4xx et 500 sont redirigées vers un même fichier php. Pourquoi je n'utilise pas des fichiers séparés pour chaque code est une autre question, qui n'a rien à voir avec votre question ici, donc oublions-la et concentrons-nous sur error.php
pour l'instant.
Voici quelques lignes de error.php
:
<?php
require_once("error_page.php");
$relative_path = "";
$internal_server_error = FALSE;
if (isset($_SERVER['REDIRECT_URL']) && $_SERVER['REDIRECT_URL'] != "")
{
$relative_path = $_SERVER['REDIRECT_URL'];
$internal_server_error = (http_response_code() >= 500);
}
else if (isset($_SERVER['REQUEST_URI']))
{
$relative_path = $_SERVER['REQUEST_URI'];
}
ErrorPage::GenerateErrorPage($internal_server_error, $relative_path);
?>
En bref, il reçoit le code d'état HTTP d'Apache via http_response_code()
et simplement classer le code d'état en deux catégories : Erreur interne du serveur et Erreur non interne du serveur. Il transmet ensuite la catégorie à ErrorPage::GenerateErrorPage()
qui génère en fait le contenu de la page d'erreur.
Sur ErrorPage::GenerateErrorPage()
je fais quelque chose comme ça :
<?php
http_response_code($internal_server_error ? 500 : 404);
?>
au début de la fonction, afin qu'il n'y ait pas d'ennuyeux "en-têtes déjà envoyés". Cette fonction générera une page d'erreur entièrement fonctionnelle avec un code d'état HTTP correct (ou ce que nous attendions, du moins). Après avoir défini le code d'état HTTP, comme vous pouvez le deviner, l'un des deux contenus préparés sera généré par les codes php suivants, un pour 500, un autre pour 404.
Maintenant, revenons à votre question.
Vous voulez déclencher exactement la même page d'erreur qu'Apache, et maintenant vous pouvez simplement appeler la fonction ErrorPage::GenerateErrorPage()
d'où vous voulez, tant que vous lui donnez des paramètres corrects ( TRUE
pour 500, FALSE
pour 404 dans mon cas).
Évidemment, parce que les pages d'erreur d'Apache sont générées par la même fonction ErrorPage::GenerateErrorPage()
nous pouvons vous garantir que ce que vous déclenchez partout est exactement ce que vous attendez des pages d'erreur Apache.
Voici mon exemple de page de déclenchement :
<?php
ob_start();
require_once("error_page.php");
try
{
// Actual contents go here
phpInfo();
throw new Exception('test exception');
}
catch (Exception $e)
{
ob_clean();
ErrorPage::GenerateErrorPage(TRUE);
ob_end_flush();
exit();
}
ob_end_flush();
?>
La raison pour laquelle j'utilise ob_start()
y ob_clean()
est que, de cette manière, je peux effacer toute sortie avant que l'exception ne se produise, et envoyer une pure page d'erreur de serveur interne 500 qui ressemble exactement à celle qu'Apache donne sans aucun contenu sur la page de déclenchement ( phpInfo()
dans ce cas). ob_start()
y ob_clean()
également s'assurer qu'il n'y aura pas de "headers already sent". car rien ne sera jamais envoyé si vous n'appelez pas. ob_end_flush()
.
La solution ci-dessus est la conclusion de ce que j'ai recherché ces jours-ci. Elle me convient jusqu'à présent, mais je ne suis pas sûr que ce soit la bonne façon de procéder. Tous les commentaires, questions, réflexions, suggestions et améliorations sont les bienvenus.