web-dev-qa-db-ja.com

予期しない.htaccessの相対的なErrorDocumentの動作

ドキュメントルートに、次のように.htaccessを配置します。

ErrorDocument 404 /error.php

これは.htaccessファイルにあるため、Apacheは相対パスでerror.phpを検索します。そのため、さまざまなサブフォルダーにさまざまなerror.phpファイルを配置して、さまざまなerror.phpを実行することができます。

request /app1/not-exists.txt : yields /app1/error.php
request /app2/not-exists.txt : yields /app2/error.php
request /not-exists/not-exists.txt : yields /error.php

これは望ましい動作です。しかしながら、

request /not-exists/app1/not-exists.txt : yields /app1/error.php
request /app2/app1/not-exists.txt : yields /app1/error.php

これは期待される動作ではないようです。私は期待しました:

request /not-exists/app1/not-exists.txt : yields /error.php
request /app2/app1/not-exists.txt : yields /app2/error.php (or maybe /error.php)

または最悪の場合、いくつかの一般的なApacheエラー処理。 Apacheがここで何をすることになっているのか誤解していますか?ドキュメントはこれを明確にしていないようです。

1
dlo

ここでのあなたの誤解は相対的な経路だと思います。

.htaccessファイルには、パスを相対的なものにする特別な動作はありません。これらは、構成動作の点で<Directory>ブロックと本質的に同じものです。

ErrorDocumentにはコンテキストの概念がありません。 /error.phpのようなパスを入力すると、構成されている場所に関係なく、常にドキュメントルートに相対的であると見なされます。 mod_rewriteブロックまたは<Directory>ファイルの.htaccess構成は、相対パスを使用します。これは、おそらくその動作について考えていることです。

これを実装する方法についてのいくつかのオプション..リクエストパスに応じてアプリごとのエラーファイルからコンテンツをプルする単一のerror.phpを持つことができますか?

または、mod_rewriteを使用して、目的のエラーページピッキング動作を取得することもできます(ただし、探しているものに一致するロジックを取得することは、少し複雑な混乱です)。

<Directory /path/to/docroot>
    # First, we'll have a rule that will handle looking for an error.php in
    # the app directory that the request is in...
    # Not a file or a directory that exists:
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    # Capture the application directory that we're trying to load from (if
    # there is one) for use in the next rule:
    RewriteCond %{REQUEST_FILENAME} ^/path/to/docroot/([^/]+)/
    # Check if an error.php exists in that directory;
    RewriteCond /path/to/docroot/%1/error.php -f
    # Send the response to the error page.  It should set the 404 response code.
    RewriteRule ^([^/]+)/.*$ $1/error.php [L]

    # Ok, the previous pile of rules didn't apply;  if the user's requesting 
    # a nonexistent resource, then either the user's not in an app subdirectory,
    # or they're in a subdirectory that didn't have an error.php.
    # So, this is a lot simpler:
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^ error.php [L]
</Directory>
1
Shane Madden