it-swarm.com.de

.htaccess ErrorDocument-Direktive fängt keine 404-Fehler ab, die durch PHP http_response_code (404) ausgelöst wurden

Apache 2.4.10 unter Windows. Ich habe eine stabile Zend Framework 1 PHP Anwendung. Ich habe gerade beschlossen, ErrorDocument zu .htaccess hinzuzufügen. Ich bin völlig verblüfft über die drei verschiedenen Verhaltensweisen, die ich bei 404 erlebe, je nachdem, wie sie ausgelöst werden.

Meine .htaccess-Datei enthält:

ErrorDocument 404 "Page not found"
RedirectMatch 404 /uploads/(.*/)?private/

Wenn ich einfach eine URL für eine nicht vorhandene Seite in die Adressleiste eingebe, wird die von Zend Frameworks ErrorController erstellte Fehlerseite angezeigt.

Wenn ich /uploads/private/foo eingebe (passend zu RedirectMatch), erhalte ich erwartungsgemäß die Ausgabe ErrorDocument.

Aber wenn ich es in meinem PHP Code tue

http_response_code(404);
exit(0);

dann bekomme ich die Standardfehlerseite des Browsers. Dies ist der, den ich überhaupt nicht verstehe. Wenn ich die Registerkarte "Netzwerk" in den Entwicklertools von Chrome verwende, wird angezeigt, dass alle drei Anforderungen den Status "404" haben. Ich schätze, ich kann mir vorstellen, dass das Fehlerbehandlungssetup des Zend Frameworks die nicht vorhandene URL abfängt und seine Sache tut, indem es die ErrorDocument -Verarbeitung umgeht. Aber ich verstehe nicht, wie ein sofortiger exit aus PHP Code mit dem Status 404 über den ErrorDocument hinauskommen würde.

Welchen PHP Code könnte ich schreiben, um die Anweisung ErrorDocument auszulösen?

BEARBEITEN:

Basierend auf der Antwort von Tim Fountain sollte ich mehr Kontext angeben: Wie oben erwähnt, ist meine ZF ErrorController -Seite so eingerichtet, dass sie so aussieht, wie ich es möchte - ich sehe diese Seite, wenn ich eintrete eine URL für eine nicht vorhandene Seite. In dieser speziellen Situation führe ich tatsächlich Code aus einem WordPress mu-plugin aus (WP wird unter dem ZF public -Verzeichnis installiert). Die Datei .htaccess leitet Anforderungen für vorhandene Dateien unterhalb von public natürlich nicht an ZF weiter. Anfragen für etwas unterhalb von public/wp gehen stattdessen zu public/wp/index.php Die mu-plugin Bootstraps ZF (ruft aber nicht die run() Methode des Bootstraps auf) und untersucht dann die Anfrage. Wenn es nicht erlaubt ist (gemäß den Auth-Sitzungsvariablen von ZF), möchte ich eine 404 (nicht 403) angeben. Zuvor habe ich dazu auf eine nicht vorhandene URL umgeleitet, auf der die Seite ErrorController einwandfrei angezeigt wurde. In der Adressleiste wurde jedoch auch die nicht vorhandene URL angezeigt. Ich habe beschlossen, die Anweisung ErrorDocument hinzuzufügen, damit in der Adressleiste weiterhin die vom Benutzer eingegebene URL angezeigt wird. In meinem eigentlichen Code hatte ich keinen einfachen String in der Direktive, sondern diese URL: /default/error/error?error_handler[type]=404. Ich habe es in eine einfache Zeichenfolge geändert, nur um sicherzustellen, dass die URL kein Problem verursacht. Wenn ich eine URL für etwas in einem private -Verzeichnis eingebe, das RedirectMatch auslöst, wird die Seite ZF ErrorController angezeigt, sodass ich weiß, dass die URL selbst kein Problem darstellt. Ich wollte nur die Komplexität für dieses Posting reduzieren.

Tims Antwort besagt, dass mein Problemcode eine leere 404-Seite direkt an den Browser sendet und der Browser sie in erklärenden Text ändert. Das ist klar, was passiert!

Bedeutet dies, dass mein Problem darin besteht, dass ich einen Seiteninhalt ungleich Null erstellen und den Status mit header() festlegen muss, da http_response_code() leere Inhalte direkt an den Browser sendet? In seiner Antwort ist jedoch unklar, warum die Anweisung ErrorDocument umgangen wird.

Die Anforderungs-URL, die dieses Verhalten verursacht, ist http://www.example.com/wp/foo. Das DocumentRoot ist .../public. Dies wird nicht von .htaccess umgeschrieben, um zu ZF zu gelangen, sondern direkt zu public/wp/index.php. In diesem Fall hätte ich gedacht, dass ErrorDocument ausgelöst würde ...

EDIT 2:

Oder warten Sie, vielleicht geht es in Tims Punkt nicht wirklich um die Behandlung von ZF-Fehlern, aber aus der Sicht von Apache wurde die eingehende Anfrage erfüllt (indem Sie public/wp/index.php aufrufen und PHP ausführen), also liegt es am PHP Code, um damit umzugehen, ich kann danach nicht mehr zu Apaches ErrorDocument zurückkehren! Ich glaube, ich hatte ein grundlegendes Missverständnis darüber, wie ErrorDocument funktioniert. Ich muss einen Weg finden, um den Code ErrorController direkt aufzurufen und die gewünschte Seite mit dem Status 404 anzuzeigen! Duh!

Ich nehme an, dass ich Tims Antwort akzeptiere, aber wenn er seinen Standpunkt darüber klarstellen/verallgemeinern möchte, wann die ErrorDocument Verarbeitung ins Spiel kommt, wäre das schön :-)

EDIT 3:

Nur um das zusammenzufassen. Ich habe Tims Antwort akzeptiert, weil sie mein grundlegendes Missverständnis der Funktionsweise der Apache ErrorDocument -Direktive enthüllte. Es hat mir jedoch nicht direkt gezeigt, wie ich das aufgetretene Problem lösen kann, da festgestellt wurde, dass ich auf meiner benutzerdefinierten Zend Framework-Statusseite einen 404-Status zurückgeben wollte, aber ich habe eine WordPress - Abfrage ausgeführt, in der ZF gebootet wurde ohne die MVC-Anwendung gestartet zu haben, die unter dem Bootstrap ausgeführt wird. Ich hatte keine Erfahrung mit dem Front-Controller von ZF, aber nachdem ich ein bisschen in den Dokumenten herumgebastelt hatte, kam ich auf diese Lösung, die genau den gleichen Effekt hat wie die vollständige ErrorDocument -Richtlinie, die ich auslösen wollte.

$error_url = $this->serverUrl() . '/default/error/error?error_handler[type]=404';
$request = new Zend_Controller_Request_Http($error_url);
$front = Zend_Controller_Front::getInstance();
$front->returnResponse(true);
$response = $front->dispatch($request);
$response->setRawHeader('HTTP/1.1 404 Not Found');
$response->sendResponse();
exit(0);
2
sootsnoot

Vermutlich haben Sie in Ihren htaccess-Regeln auch eine Rewrite-Regel, um alle Anfragen an Zend Framework weiterzuleiten. Zu diesem Zeitpunkt ist Apache (und ErrorDocument) nicht wirklich im Bild, da Sie angegeben haben, dass die Anforderungen von PHP verarbeitet werden sollen.

Wenn Sie das tun:

http_response_code(404);
exit(0);

sie senden eine leere 404-Seite an den Browser. Viele Browser sind so eingerichtet, dass sie ihre eigene benutzerfreundliche 404-Seite anzeigen, wenn die Größe der 404-Seite, die sie vom Server erhalten, weniger als X Byte beträgt. (Nur für eine bessere Benutzererfahrung.)

Zend Framework sollte dies abfangen und eine eigene Fehlerseite verwenden, abhängig von where dem PHP Code (und möglicherweise basierend auf einigen Konfigurationsoptionen).

Ich würde vorschlagen, dass Sie die Zend Framework ErrorController-Seite aktualisieren, damit sie so aussieht, wie Sie möchten. Ich glaube nicht, dass es eine Möglichkeit gibt, die Anfrage an Apache zurückzusenden (sozusagen).

2
Tim Fountain