如何避免在 url 上输入 .php?

How to avoid the need of typing .php on the url?

我在 MacOs Big Sur 上使用 Apache 和 PHP。我想要的是:不需要将 .php 放在我的文件末尾来加载它。

例如,不要在 URL 上键入:

127.0.0.1/public_html/home.php

我只想输入

127.0.0.1/public_html/home

为了实现这一点,我在 .htaccess:

中使用了这段代码
RewriteEngine On
Options -Indexes 
DirectoryIndex home.php index.php 
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.+)$ .php [L]

上面的代码在我的主机上工作,但由于某种原因,它在我的开发机器上不工作。相反,出现 404 错误。

包含代码的 .htaccess 文件位于 public_html 文件夹的根目录中。

我错过了什么?

通过在 .htaccess 文件的顶部键入一些“废话”并且 不会 得到一个错误(通常你会得到一个 500 内部服务器错误)它会服务器上似乎未启用 .htaccess 覆盖。因此,.htaccess 个文件被有效地禁用了——它们在 Apache 2.4 上是默认的。

要启用 .htaccess 覆盖(允许 .htaccess 覆盖服务器配置),您需要在服务器的适当 <Directory> 容器中设置 AllowOverride 指令配置(或 <VirtualHost> 容器)。 Apache 2.4 上的默认值为 AllowOverride None.

根据发布的指令,您至少需要:

AllowOverride FileInfo Indexes Options

FileInfo 代表 mod_rewrite,Indexes 代表 DirectoryIndexOptions 代表 Options 和相关指令。

虽然通常(也更容易)设置:

AllowOverride All

参考:


RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.+)$ .php [L]

这些指令并不完全正确。虽然它们对于您正在测试的 URLs 可能工作正常,但如果您只是将斜杠附加到 URLs(并且没有目录),它们将导致重写循环(500 错误响应)以那个名字),例如。 /home/(或/home/<anything>)。这是因为测试 .php 文件是否存在的 条件 不一定与要重写的 URL 路径相同。参见 my answer to the following question on ServerFault for a thorough explanation of this issue: https://serverfault.com/questions/989333/using-apache-rewrite-rules-in-htaccess-to-remove-html-causing-a-500-error

此外,无需先检查请求是否映射到目录,然后再检查请求 + .php 扩展名是否映射到文件。如果请求映射到一个文件,那么它不能同时是一个目录,所以如果第二个条件为真,第一个条件也必须为真,因此是多余的。

并且在 RewriteCond TestString 中不需要反斜杠转义文字点 - 这是一个“普通”字符串,而不是正则表达式。

所以,这些指令应该这样写:

RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}.php -f
RewriteRule (.+) .php [L]

(RewriteBase 应该 而不是 在这里使用。)

您可以通过排除已经包含看起来像文件扩展名的请求来进一步优化这一点(假设您需要重写的 URL 不包含 URL 结尾附近的点 -小路)。例如:

RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}.php -f
RewriteRule !\.\w{2,4}$ %{REQUEST_URI}.php [L]

(对于第 2 个版本,是否设置 RewriteBase 并不重要 - 它未被使用。)

DirectoryIndex home.php index.php 

您给出了 /public_html/home 的示例 URL(附加了 .php)。然而,这个 DirectoryIndex 指令允许 home.php 在简单地请求目录 /public_html/ 时也被提供。它应该是一个或另一个,而不是两者。