如何避免在 url 上输入 .php 的需要? [英] How to avoid the need of typing .php on the url?

查看:19
本文介绍了如何避免在 url 上输入 .php 的需要?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 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 用于 DirectoryIndexOptions 用于 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆