Windows上のApache 2.4.10。安定したZend Framework 1 PHPアプリケーションがあります。 .htaccess
にErrorDocument
ディレクティブを追加することにしました。 404で発生する3つの異なる動作に、それらがトリガーされる方法に応じて完全に困惑します。
私の.htaccessファイルには以下が含まれます:
ErrorDocument 404 "Page not found"
RedirectMatch 404 /uploads/(.*/)?private/
アドレスバーに存在しないページのURLを入力すると、Zend FrameworkのErrorController
によって生成されたエラーページが表示されます。
/uploads/private/foo
(RedirectMatch
と一致)を入力すると、期待どおりErrorDocument
出力が得られます。
しかし、私のPHPコードで
http_response_code(404);
exit(0);
その後、ブラウザの標準エラーページが表示されます。これは私が完全に理解できないものです。 Chrome開発者ツールの[ネットワーク]タブを使用すると、3つのリクエストすべてが404ステータスになっていることがわかります。 Zend Frameworkのエラー処理セットアップは、存在しないURLをトラップし、ErrorDocument
処理をバイパスしてそれを行うと想像できると思います。しかし、ステータスが404のPHPコードからの即時exit
がErrorDocument
をどのように通過するかはわかりません。
ErrorDocument
ディレクティブをトリガーするには、どのPHPコードを記述できますか?
編集:
ティムファウンテン からの回答に基づいて、より多くのコンテキストを提供する必要があります。上記のように、ZF ErrorController
ページは希望どおりに設定されています-入力するとそのページが表示されます存在しないページのURL。この特定の状況では、実際にWordPress mu-plugin
からコードを実行しています(WPはZF public
ディレクトリの下にインストールされます)。 .htaccess
ファイルは、当然public
以下の既存のファイルに対するリクエストをZFに送信しません。 public/wp
の下にあるものに対するリクエストは、代わりにpublic/wp/index.php
The mu-plugin
ブートストラップZFに移動し(ただし、ブートストラップのrun()
メソッドを呼び出しません)、リクエストを調べます。許可されていない場合(ZFのAuthセッション変数による)、404(403ではなく)を指定します。以前は、実際には存在しないURLにリダイレクトすることでこれを行いましたが、ErrorController
ページは問題なく表示されましたが、アドレスバーには存在しないURLが表示されたままでした。 ErrorDocument
ディレクティブを追加して、アドレスバーにユーザーが入力したURLが表示されるようにしました。私の実際のコードでは、ディレクティブに単純な文字列はありませんでしたが、このURLは/default/error/error?error_handler[type]=404
です。問題を引き起こしているURLについて何かがないことを確認するために、単純な文字列に変更しました。 private
ディレクトリ内でRedirectMatch
をトリガーするURLを入力すると、ZF ErrorController
ページが表示されるため、URL自体には問題がないことがわかります。この投稿の複雑さを軽減したかっただけです。
ティムの答えは、私の問題のコードが空の404ページを直接ブラウザに送信しており、ブラウザがそれを説明テキストに変更していると言っています。それは明らかに起こっていることです!
header()
は空のコンテンツを直接ブラウザに送信するため、長さがゼロでないページコンテンツを作成し、http_response_code()
を使用してステータスを設定する必要があるということです。しかし、彼の答えで不明確なのは、ErrorDocument
ディレクティブがバイパスされる理由です。
この動作を引き起こすリクエストURLはhttp://www.example.com/wp/foo
です。 DocumentRoot
は.../public
です。これは、.htaccess
によって書き換えられてZFに送られるのではなく、直接public/wp/index.php
に送られます。その場合、ErrorDocument
がトリガーされると思います...
編集2:
または、ティムのポイントは実際にはZFエラー処理に関するものではないかもしれませんが、Apacheの観点からは、(public/wp/index.php
に行きPHPを実行することで)着信リクエストが満たされたので、PHP次第ですコードを処理するために、ApacheのErrorDocument
に戻ることができません! ErrorDocumentがどのように機能するかについて、根本的な誤解があったと思います。 ErrorController
コードを直接呼び出して、必要なページを404ステータスで表示する方法を見つける必要があります。ああ!
ティムの答えを受け入れると思いますが、ErrorDocument
処理が開始されるタイミングについて、彼が自分のポイントを明確化/一般化したい場合、それはいいです:-)
編集3:
これをまとめるだけです。 Apache ErrorDocument
ディレクティブがどのように機能するかについての基本的な誤解を明らかにしたので、私はティムの答えを受け入れました。しかし、Zend Frameworkのカスタムステータスページを使用して404ステータスを返すことを発見したため、発生している問題を解決する方法を直接示しませんでしたが、WordPressクエリで実行しましたブートストラップで実行されているMVCアプリケーションを開始せずにZFをブートストラップしました。 ZFフロントコントローラーをいじくり回した経験はありませんでしたが、ドキュメントを少し掘り下げた後、このソリューションを思い付きました。これは、旅行したかったErrorDocument
ディレクティブとまったく同じ効果があります。
$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);
おそらく、htaccessルールには、すべてのリクエストをZend Frameworkにルーティングするための書き換えルールもあります。この時点で、Apache(およびErrorDocument)は実際には見えません。リクエストをPHPで処理したいと言ったからです。
あなたがするとき:
http_response_code(404);
exit(0);
空の404ページをブラウザに送信しています。多くのブラウザは、サーバーから受信する404ページのサイズがXバイト未満の場合、独自の使いやすい404ページを表示するように設定されています。 (ユーザーエクスペリエンスを向上させるためだけです。)
Zend Frameworkはこれをキャッチし、where PHPコード(および場合によってはいくつかの構成オプションに基づく)に応じて独自のエラーページを使用する必要があります。
Zend Framework ErrorControllerページを更新して、希望どおりに表示することをお勧めします。リクエストの処理をApacheに返す方法があるとは思いません。