如何避免在 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选项 - 索引DirectoryIndex home.php index.phpRewriteCond %{REQUEST_FILENAME} !-dRewriteCond %{REQUEST_FILENAME}\.php -f重写规则 ^(.+)$ $1.php [L]
上面的代码适用于我的主机,但由于某种原因,它不适用于我的开发机器.相反,会出现 404 错误.
带有代码的 .htaccess
文件位于 public_html
文件夹的根目录.
我错过了什么?
通过输入一些废话"在 .htaccess
文件的顶部并且 没有 得到错误(通常你会得到一个 500 Internal Server Error)看起来 .htaccess
服务器上未启用覆盖.因此,.htaccess
文件被有效地禁用了 - 它们在 Apache 2.4 上是默认的.
要启用 .htaccess
覆盖(以允许 .htaccess
覆盖服务器配置),您需要在适当的位置设置 AllowOverride
指令
服务器配置中的容器(或
容器).Apache 2.4 上的默认值是 AllowOverride None
.
根据发布的指令,您至少需要:
AllowOverride FileInfo 索引选项
FileInfo
用于 mod_rewrite,Indexes
用于 DirectoryIndex
和 Options
用于 Options
和相关指令.
虽然只是设置很常见(也更容易):
AllowOverride All
参考:
<块引用>
RewriteCond %{REQUEST_FILENAME} !-dRewriteCond %{REQUEST_FILENAME}\.php -f重写规则 ^(.+)$ $1.php [L]
这些指令并不严格正确.虽然它们可能适用于您正在测试的 URL,但如果您只是在 URL 中附加一个斜杠(并且没有该名称的目录),它们将导致重写循环(500 错误响应),例如./home/
(或 /home/
).这是因为您用于测试 .php
文件是否存在的条件不一定与您要重写的 URL 路径相同.请参阅我的回答对 ServerFault 上的以下问题的详细说明: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 -fRewriteRule (.+) $1.php [L]
(RewriteBase
应该不在这里使用.)
您可以通过排除已经包含看起来像文件扩展名的请求来进一步优化此功能(假设您需要重写的 URL 在 URL 路径末尾附近不包含点).例如:
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}.php -f重写规则 !\.\w{2,4}$ %{REQUEST_URI}.php [L]
(对于第二个版本,是否设置了 RewriteBase
无关紧要 - 它没有被使用.)
DirectoryIndex home.php index.php
您给出了 /public_html/home
的示例 URL(附加了 .php
).但是,这个DirectoryIndex
指令允许在简单地请求目录/public_html/
时也可以提供home.php
.应该是其中之一,而不是两者.
I'm on MacOs Big Sur, using Apache and PHP. What I want is: not needing to put .php
on the end of my files to load it.
For instance, instead of typing this on the URL:
127.0.0.1/public_html/home.php
I want just to type
127.0.0.1/public_html/home
To achieve this, I'm using this code in .htaccess
:
RewriteEngine On
Options -Indexes
DirectoryIndex home.php index.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.+)$ $1.php [L]
The code above works on my hosting, but for some reason, it does not work on my development machine. Instead, a get a 404 error.
The .htaccess
file with the code is on the root of public_html
folder.
What am I missing?
By typing some "nonsense" at the top of the .htaccess
file and not getting an error (ordinarily you would get a 500 Internal Server Error) it would seem that .htaccess
overrides were not enabled on the server. So, .htaccess
files were effectively disabled - which they are by default on Apache 2.4.
To enable .htaccess
overrides (to allow .htaccess
to override the server config) you need to set the AllowOverride
directive in the appropriate <Directory>
container in the server config (or <VirtualHost>
container). The default on Apache 2.4 is AllowOverride None
.
With the directives as posted you would need a minimum of:
AllowOverride FileInfo Indexes Options
FileInfo
for mod_rewrite, Indexes
for DirectoryIndex
and Options
for Options
and related directives.
Although it is common (and easier) to just set:
AllowOverride All
Reference:
RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME}\.php -f RewriteRule ^(.+)$ $1.php [L]
These directives are not strictly correct. Whilst they may work OK for the URLs you are testing, they would result in a rewrite-loop (500 error response) if you simply append a slash to your URLs (and there is no directory by that name), eg. /home/
(or /home/<anything>
). This is because your condition that tests for the presence of the .php
file is not necessarily the same as the URL-path you are rewriting to. See 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
Also, there's no need to check that the request does not map to a directory to then check if the request + .php
extension maps to a file. If the request maps to a file then it can not also be a directory, so if the 2nd condition is true, the 1st condition must also be true and is therefore superfluous.
And there's no need to backslash-escape literal dots in the RewriteCond
TestString - this is an "ordinary" string, not a regex.
So, these directives should be written like this instead:
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}.php -f
RewriteRule (.+) $1.php [L]
(RewriteBase
should not be used here.)
You can further optimise this by excluding requests that already contain what looks like a file extension (assuming your URLs that need rewriting do not contain a dot near the end of the URL-path). For example:
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}.php -f
RewriteRule !\.\w{2,4}$ %{REQUEST_URI}.php [L]
(With this 2nd version, it does not matter if RewriteBase
is set - it is not used.)
DirectoryIndex home.php index.php
You gave an example URL of /public_html/home
(to which .php
is appended). However, this DirectoryIndex
directive allows home.php
to also be served when simply requesting the directory /public_html/
. It should be one or the other, not both.
这篇关于如何避免在 url 上输入 .php 的需要?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!