web-dev-qa-db-de.com

Auslöser 500 Interner Serverfehler in PHP und Apache-Fehlerseite anzeigen

Wie kann ich 500-Serverfehler oder 404-Seite nicht gefunden Apache-Fehler in PHP auslösen?

Für 500 Internal Server Error habe ich folgenden Code ausprobiert:

header("HTTP/1.0 500 Internal Server Error");

Aber es zeigt mir eine leere Seite ... Wie kann ich den Fehler im Standardformat von Apache anzeigen?

Bitte führen Sie ..

36
Vin

Nach so einer wissenswerten Diskussion denke ich, dass es keinen PHP-Code gibt, der standardmäßig den 500 Internal Server Error anzeigen kann. Die Lösung ist:
1. Erstellen Sie einen Ordner mit dem Namen http500 neben der PHP-Datei.
2. Erstellen Sie eine .htaccess-Datei und fügen Sie folgenden Code hinzu:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule ^])(.(*/
    RewriteRule ^])((a-zA
</IfModule>
  1. PHP-Weiterleitungscode: 

header ('location: http500 /');

7
Vin

Sie können die Apache-Fehlerdokumente einfach in Ihr Webstammverzeichnis kopieren (oder mit einem Symlink verknüpfen) und mit header() die Fehlercodes und diese Dokumente als Ausgabe festlegen. Das ist wahrscheinlich am besten, wenn Sie keinen zwingenden Grund haben, dies nicht zu tun. Aber falls das für Sie nicht funktioniert, gibt es einige Alternativen (wenn auch hackige Alternativen).

Bei 500 fügen Sie einfach einen Fehler in Ihren Code ein.

<?php throw new Exception('Nooooooooooooooo!'); ?>

Das Skript PHP löst eine Ausnahme aus und führt zu einer regulären Apache 500-Fehlerseite. (Beachten Sie jedoch die Einschränkung, dass dies nur dann zu einem Apache-Fehler führt, wenn für die Starteinstellung PHP display_errors0 festgelegt ist. In den meisten Entwicklungskonfigurationen ist dies nicht der Fall. In den meisten Produktionskonfigurationen ist dies der Wenn Sie die Einstellungen Ihres Produktionsservers nicht kennen, müssen Sie dies nur testen, um zu sehen, ob es funktioniert.)

Für 404 denke ich, das Beste, was Sie tun können, ist auf eine nicht vorhandene Seite umzuleiten. Es ist nicht genau das Gleiche, kann aber für Ihre Zwecke ausreichen.

<?php header("Location: /i-dont-think-therefore-i-am-not"); ?>

In den meisten Browsern sehen die Benutzer die Weiterleitung nicht wirklich, sie werden lediglich still und schnell auf eine nicht vorhandene Seite umgeleitet, was zu einem regulären Apache 404-Fehler führt. Natürlich hat sich die URL geändert und einige Benutzer könnten dies bemerken. Wenn dies nicht akzeptabel ist, können Sie möglicherweise ähnliche Ergebnisse erzielen, wenn Sie Apache mod_rewrite verwenden, um das URL-Backend an einen nicht vorhandenen Speicherort zu schreiben.

So antworten Sie auf mehrere Kommentare: Das Festlegen des Antwortcodes über header() (oder auf andere Weise) führt nicht zum standardmäßigen Apache-Fehlerdokument. Dieser Antwortcode wird einfach mit Ihrer eigenen Ausgabe zurückgegeben. Dies ist ein vorsätzliches Verhalten, das so konzipiert ist, dass Sie benutzerdefinierte Fehlerdokumente haben oder auf andere Weise Antwortcodes festlegen können, wenn die HTTP-Spezifikation für jede Anforderung vorschreibt. Wenn Sie die Apache - Fehlerdokumente haben möchten, müssen Sie sie entweder fälschen (gemäß meinem ursprünglichen Vorschlag, die Fehlerdokumente einfach in Ihr Webstammverzeichnis zu kopieren), oder Sie müssen Apache dazu bringen, sie zurückzugeben (gemäß mein Sicherungsvorschlag).

11
Ben Lee
function ISE()
{
  header('HTTP/1.1 500 Internal Server Error', true, 500);
  trigger_error('ISE function called.', E_USER_ERROR);//if you are logging errors?
}

Sie müssen jedoch die Ausgabepufferung ON verwenden, um die Funktion php header() verwenden zu können, nachdem Sie eine Ausgabefunktion wie echo verwendet haben.

6
Etherealone

Ich bin wahrscheinlich ziemlich spät, aber diese Lösung sollte funktionieren

header("HTTP/1.0 500 Internal Server Error");
include("/path-to-public-html/errors/500.php");
die();

Dadurch wird eine 500 ISE-Antwort ausgelöst, die standardmäßige 500-Fehlerseite wird angezeigt, und das Skript wird angehalten. Natürlich müssen Sie den Speicherort der enthaltenen Datei ändern

3
Ben Johnson mk2

sie können einfach keine Apache-Fehlerseiten aus PHP-Code auslösen, ohne dass die Hackery-Umleitung wie von Lee Lee vorgeschlagen wird, da die Umleitung von Fehlerdokumenten von einer anderen Schicht des Anwendungsstapels (insbesondere von Apaches mod_core ) behandelt wird.
Wenn Ihr Skript ausgeführt wird, ist es zu spät.

die Schwierigkeit, eine Fehlerseite durch Auslösen einer Ausnahme zu erhalten, hängt stark von den Einstellungen Ihrer php.ini zu Fehlerbehandlung und Ausführlichkeit ab.

http_response_code()currently existiert derzeit nur in svn von php und ist daher in den meisten Produktionsumgebungen, in denen eine offizielle Release-Version laufen soll, nicht verfügbar.

mein Rat ist, einen benutzerdefinierten Fehler- und Ausnahmebehandler über set_error_handler() und set_exception_handler() ordnungsgemäß zu implementieren. Verwenden Sie header(), um dem Client die richtigen http-Statusinformationen zu senden und (falls erforderlich) Fehlerseiten zu generieren.

2
glasz

Ich weiß, dass dies ein alter Thread ist ...

Sie könnten ein iframe-Element in Ihre Ansicht rendern und dann die Höhe und Breite auf 100% festlegen, wenn der Fehler auftritt, den Sie bearbeiten möchten. 

<?php header("HTTP/1.0 500 Internal Server Error"); http_response_code(500); ?>

<iframe src="page_displaying_Apache_screenshot_fullscreen.html"></iframe>

DAS GESAGT

Ich glaube wirklich, dass die beste moderne Lösung so etwas wäre: 

<?php
header("HTTP/1.0 500 Internal Server Error");
http_response_code(500);
?>
<div class="panel-body">
    <h1>Error!</h1>
     <p>
         <?php

         // Then, in the view if your in dev env, print exception and stack trace
         if ($env === 'dev') 
         {
             throw new Exception('Uh oh! Something broke while adding a new user the db.');
         }
         else 
         {
             echo "Hold your butts, an error has occured.";
             die();
         }
         ?>
     </p>
   </div>

Dies würde zu einem korrekten Fehlercode für alle Benutzer und auch zu einem Stack-Trace für dev führen, wenn Sie die Variable $ env in Ihrem dev-Stack auf 'dev' setzen What the user sees with this, using PHP 5.4 installed with yum using CENTOS7 by default

Keine Weiterleitung, kein Hacker, sicher, es sei denn, Sie müssen einen Fehler aufdecken, der nicht erfolgt. :)

1
Alpha G33k

Anscheinend gibt es eine Funktion namens http_response_code , mit der Sie den Antwortcode entsprechend einstellen können. Wenn dies nicht funktioniert (es gibt einen Hinweis in der Dokumentation, dass es möglicherweise nur in SVN ist), kann die header-Funktion ein optionales Antwortcode-Argument annehmen:

header("HTTP/1.0 ...", true, 404);

Dies sollte Apache korrekt signalisieren.

0
Cameron Skinner

Auf PHP 5.5 => "header (" tester.php ", true, 500);" wo tester.php nicht existiert. Es funktioniert und bringt mich zu meiner 500-Seite :)

Leider funktionierte keine der anderen hier aufgeführten Methoden aus dem einen oder anderen Grund.

0
Gavin Simpson

Ich weiß, dass dies ein alter Thread ist, aber wenn ich bei Google gesucht habe, springt er als erste Antwort heraus. Ich habe versucht, herauszufinden, wie es heutzutage funktioniert. Ich denke, ich sollte meine Problemumgehung ab 2018 veröffentlichen.

Wie Sie alle wissen, nein, Sie können die Fehlerseiten von Apache nicht einfach von PHP auslösen. Es gibt keine Möglichkeit, dies zu tun. Die beste Lösung, die ich nach einiger Recherche finden konnte, ist , um die benutzerdefinierten Fehlerseiten, die sowohl von dem, was Sie in Apache angegeben haben, als auch von der Seite aus aufgerufen werden, mit einer Funktion <PHP] anzuzeigen Sie möchten 500 Internal Server Error auslösen.

Hier ist mein conf von Apache:

ErrorDocument 400 /error.php
ErrorDocument 401 /error.php
ErrorDocument 403 /error.php
ErrorDocument 404 /error.php
ErrorDocument 500 /error.php

Wie Sie sehen konnten, werden alle 4xx- und 500-Fehler zu derselben PHP-Datei umgeleitet. Warum ich keine separaten Dateien für jeden Code verwende, ist eine andere Frage, die hier nichts mit Ihrer Frage zu tun hat. Vergessen wir sie also und konzentrieren wir uns jetzt auf error.php.

Hier sind einige Zeilen von 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);
?>

Kurz gesagt, er empfängt über http_response_code() den HTTP-Statuscode von Apache und kategorisiert den Statuscode einfach in zwei Kategorien: Interner Serverfehler und Nicht-Interner Serverfehler. Dann übergibt er die Kategorie an ErrorPage::GenerateErrorPage(), die tatsächlich den Inhalt der Fehlerseite generiert.

In ErrorPage::GenerateErrorPage() mache ich so etwas:

<?php
http_response_code($internal_server_error ? 500 : 404);
?>

am Anfang der Funktion, so dass keine ärgerlichen "Header bereits gesendet" werden. Diese Funktion generiert eine voll funktionsfähige Fehlerseite mit dem richtigen (oder zumindest erwarteten) HTTP-Statuscode. Nachdem Sie den HTTP-Statuscode festgelegt haben, wird, wie Sie sich vorstellen können, einer von zwei vorbereiteten Inhalten erzeugt, indem folgende PHP-Codes verwendet werden, einer für 500 und einer für 404.

Gehen wir jetzt zu Ihrer Frage zurück.

Sie möchten genau dieselbe Fehlerseite auslösen wie Apache, und Sie können jetzt einfach die Funktion ErrorPage::GenerateErrorPage() aufrufen, sofern Sie die richtigen Parameter angeben (TRUE für 500, FALSE für 404 in meinem Fall).

Da die Apache-Fehlerseiten mit der gleichen Funktion ErrorPage::GenerateErrorPage() generiert werden, können wir natürlich garantieren, dass das, was Sie auslösen, genau das ist, was Sie von Apache-Fehlerseiten erwarten würden. 

Hier ist mein Beispiel einer Trigger-Seite:

<?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();
?>

Der Grund, warum ich ob_start() und ob_clean() verwende, ist der, dass ich auf diese Weise alle Ausgaben löschen kann, bevor die Ausnahme auftritt, und eine reine 500 Internal Server Error-Seite senden, die genau so aussieht wie Apache, ohne Inhalt die Triggerseite (in diesem Fall phpInfo()). ob_start() und ob_clean() auch stellen sicher, dass es keine "bereits gesendeten Header" gibt, da nichts gesendet wird, es sei denn, Sie rufen ob_end_flush() auf.

Die obige Lösung ergibt sich aus dem, was ich in diesen Tagen recherchiert habe. Es ist so weit so gut für mich, aber ich bin nicht sicher, ob es der richtige Weg ist. Alle Kommentare, Fragen, Gedanken, Vorschläge und Verbesserungen sind willkommen.

0
ChenZheChina