我如何为 Apache 编写 .htaccess 文件以附加 PHP(如果未提供)并使用编写良好的 404 页面
How can I write an .htaccess file for Apache to append PHP (if not supplied) AND use a well-written 404 page
在 Apache 中,我有一个工作的 .htaccess 文件,它将 .php 扩展名附加到请求的网站页面,例如:https://{{domain}}/sales -> serves来自 https://{{domain}}/sales.php 的内容,而对于访问者来说它看起来像 https://{{domain}}/sales
它运行完美。
但是,我无法解决如何同时使用来自服务器的精美 404.php 页面。
这是我当前的 .htaccess 文件内容:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^\.]+)$ \.php [NC,L]
证据:如果我关闭我的 .htaccess 文件(重命名),根据我的 httpd.conf 设置,404 页面运行良好。所以,我几乎肯定是这个不成熟的 .htaccess 文件阻止我在找不到 sales.php 页面时提供精美的 404 页面。
What are the exact lines in httpd.conf:
DocumentRoot "/var/www/html/"
ErrorDocument 404 "/404.php"
此外,我已经尝试了每一个:(并在之后重新加载了 httpd)
ErrorDocument 404 "/var/www/html/{{virtualHostDir}}/404.php"
ErrorDocument 404 "/404.php"
ErrorDocument 404 "404.php"
我什至尝试将 ErrorDocument 直接添加到 virtualHost 设置中,但无济于事。
And what actually happens when you get a 404 and the .htaccess file is in place?
我得到一个没有 html 的页面,它只是说 "File not found."
DocumentRoot "/var/www/html/"
ErrorDocument 404 "/404.php"
看起来正确。如果 404 错误文档位于 /var/www/html/404.php
,则没有明显的原因(根据给定的信息)为什么它没有按预期工作。它似乎不是 .htaccess
文件的内容 - 尽管您可以尝试其他方法(见下文)。
提供给 ErrorDocument
指令的路径应该是文档根目录相关的 URL 路径 - 以斜杠开头。 (为了触发对相应错误文档的内部子请求。)
I've even tried to add the ErrorDocument directly to the virtualHost settings
但是,如果您使用的是 VirtualHost 容器,那么这些设置实际上应该在各自的 vHost 中。 vHost 中的任何内容都会覆盖主服务器配置。
显然,如果您对服务器配置/虚拟主机进行了任何更改,则需要重新启动 Apache。
既然你正在使用 .htaccess
,你也可以在 .htaccess
中设置 ErrorDocument
- 这将反过来覆盖虚拟主机/服务器配置。
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^\.]+)$ \.php [NC,L]
这没有什么特别的问题...您正在匹配一个不包含点的请求 URL-路径,并且假设它还没有映射到文件或目录,您正在附加一个 .php
扩展。
关于此的一些注释:
无论文件 "with a .php
extension" 是否实际存在,您都附加 .php
扩展名。这不一定是错误的,只是 404 然后在 /does-not-exist.php
而不是 /does-not-exist
上触发。您可以改为检查目标文件是否存在。这将避免检查请求是否已经映射到文件或目录。
检查请求是否映射到文件的第一个条件可能是不必要的,除非你有没有文件扩展名的文件(我认为这不太可能)。
[^\.]
- 不需要反斜杠转义正则表达式字符 class 中的文字点。 (虽然这样做没有坏处,除了可读性 IMO。)
\.php
- 无需反斜杠转义 RewriteRule
替换 中的文字点。这个参数是一个 "ordinary" 字符串(不是正则表达式),点在这里没有特殊含义。 (尽管如此,除了可读性之外,这样做没有任何坏处。)
此处不需要 RewriteRule
上的 NC
标志,因为您正在匹配 所有内容 除了正则表达式中的一个点,无论如何自然包括大写和小写字母。
如果这就是您使用 mod_rewrite 的全部目的,那么您可以改用 MultiViews 来处理无扩展的 URL。这就是 MultiViews(mod_negotiation 的一部分)所做的。给定 /path/to/foo
的请求,如果 /path/to/foo.php
存在,mod_negotiation 将提供该文件。您需要删除现有的 mod_rewrite 指令(因为它们实际上会发生冲突并被忽略),然后在 .htaccess
文件的顶部启用 MultiViews:
Options +MultiViews
或者,考虑到我在上面提出的要点,请尝试以下操作:
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}/.php -f
RewriteRule ^([^.]+)$ .php [L]
注意:我假设您的 .htaccess
文件位于文档根目录中,即。 /var/www/html/.htaccess
?
在 Apache 中,我有一个工作的 .htaccess 文件,它将 .php 扩展名附加到请求的网站页面,例如:https://{{domain}}/sales -> serves来自 https://{{domain}}/sales.php 的内容,而对于访问者来说它看起来像 https://{{domain}}/sales
它运行完美。
但是,我无法解决如何同时使用来自服务器的精美 404.php 页面。
这是我当前的 .htaccess 文件内容:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^\.]+)$ \.php [NC,L]
证据:如果我关闭我的 .htaccess 文件(重命名),根据我的 httpd.conf 设置,404 页面运行良好。所以,我几乎肯定是这个不成熟的 .htaccess 文件阻止我在找不到 sales.php 页面时提供精美的 404 页面。
What are the exact lines in httpd.conf:
DocumentRoot "/var/www/html/"
ErrorDocument 404 "/404.php"
此外,我已经尝试了每一个:(并在之后重新加载了 httpd)
ErrorDocument 404 "/var/www/html/{{virtualHostDir}}/404.php"
ErrorDocument 404 "/404.php"
ErrorDocument 404 "404.php"
我什至尝试将 ErrorDocument 直接添加到 virtualHost 设置中,但无济于事。
And what actually happens when you get a 404 and the .htaccess file is in place?
我得到一个没有 html 的页面,它只是说 "File not found."
DocumentRoot "/var/www/html/" ErrorDocument 404 "/404.php"
看起来正确。如果 404 错误文档位于 /var/www/html/404.php
,则没有明显的原因(根据给定的信息)为什么它没有按预期工作。它似乎不是 .htaccess
文件的内容 - 尽管您可以尝试其他方法(见下文)。
提供给 ErrorDocument
指令的路径应该是文档根目录相关的 URL 路径 - 以斜杠开头。 (为了触发对相应错误文档的内部子请求。)
I've even tried to add the ErrorDocument directly to the virtualHost settings
但是,如果您使用的是 VirtualHost 容器,那么这些设置实际上应该在各自的 vHost 中。 vHost 中的任何内容都会覆盖主服务器配置。
显然,如果您对服务器配置/虚拟主机进行了任何更改,则需要重新启动 Apache。
既然你正在使用 .htaccess
,你也可以在 .htaccess
中设置 ErrorDocument
- 这将反过来覆盖虚拟主机/服务器配置。
RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^([^\.]+)$ \.php [NC,L]
这没有什么特别的问题...您正在匹配一个不包含点的请求 URL-路径,并且假设它还没有映射到文件或目录,您正在附加一个 .php
扩展。
关于此的一些注释:
无论文件 "with a
.php
extension" 是否实际存在,您都附加.php
扩展名。这不一定是错误的,只是 404 然后在/does-not-exist.php
而不是/does-not-exist
上触发。您可以改为检查目标文件是否存在。这将避免检查请求是否已经映射到文件或目录。检查请求是否映射到文件的第一个条件可能是不必要的,除非你有没有文件扩展名的文件(我认为这不太可能)。
[^\.]
- 不需要反斜杠转义正则表达式字符 class 中的文字点。 (虽然这样做没有坏处,除了可读性 IMO。)\.php
- 无需反斜杠转义RewriteRule
替换 中的文字点。这个参数是一个 "ordinary" 字符串(不是正则表达式),点在这里没有特殊含义。 (尽管如此,除了可读性之外,这样做没有任何坏处。)此处不需要
RewriteRule
上的NC
标志,因为您正在匹配 所有内容 除了正则表达式中的一个点,无论如何自然包括大写和小写字母。如果这就是您使用 mod_rewrite 的全部目的,那么您可以改用 MultiViews 来处理无扩展的 URL。这就是 MultiViews(mod_negotiation 的一部分)所做的。给定
/path/to/foo
的请求,如果/path/to/foo.php
存在,mod_negotiation 将提供该文件。您需要删除现有的 mod_rewrite 指令(因为它们实际上会发生冲突并被忽略),然后在.htaccess
文件的顶部启用 MultiViews:Options +MultiViews
或者,考虑到我在上面提出的要点,请尝试以下操作:
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}/.php -f
RewriteRule ^([^.]+)$ .php [L]
注意:我假设您的 .htaccess
文件位于文档根目录中,即。 /var/www/html/.htaccess
?