Неожиданное относительное поведение ErrorDocument.htaccess
В корень документа я положил.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 ответ
Я думаю, что ваше недоразумение здесь - относительный путь.
.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>