为什么 WAMP 运行 脚本具有相似的名称而不是重写 URL?
Why does WAMP run script with similar name instead of rewriting URL?
我正在尝试将所有请求重写到 index.php
,然后根据 $_GET['p']
变量中的值决定要包含哪个文件。例如,我在名为 leltar
的站点的主目录中有一个名为 update.php
的脚本,如果打开的页面是 localhost/leltar/update
.
,我希望将其包括在内
但是,问题是重写不起作用,因为 WAMP 运行脚本,即使 .php
扩展名不在 link 中。输出只是脚本中的输出,index.php
没有显示任何内容。如何从 运行 具有相似名称的脚本中停止 WAMP?我想,我的 .htaccess 代码也有问题,因为如果我打开 localhost/leltar/update
以外的页面,$_GET['p']
的值是字符串 "index.php"一直。
.htaccess 文件:
RewriteEngine On
RewriteRule ^(.*)$ index.php?p=
index.php:
// ...
switch ($_GET['p']) {
case 'update':
require_once('update.php');
break;
default:
// something else
break;
}
// ...
update.php
内容不相关
编辑:
主要问题是默认情况下,甚至当我使用 RewriteCond %{REQUEST_FILENAME} !-f
重写条件时,如果存在与 link 的用户友好端同名的文件,WAMP 会以某种方式覆盖我的重写规则。如果我将名为 pic.jpg
的图片放入 www
文件夹并打开 localhost/pic.jpg
,显然会显示图像。但是,如果我省略了访问页面 localhost/pic
的扩展程序,我也会得到相同的输出(而不是因为文件夹不存在而出现 404 Not Found 错误,我想)。
编辑 2:
在真实服务器上没有任何问题。如果我遗漏了扩展名,则会抛出 404 错误,所以这绝对是 WAMP 特定的东西。
.htaccess
文件中的规则有效地循环,直到 URL 没有改变(因为每次都重新开始处理,这意味着规则也会再次处理)所以你的规则当然会循环直到p
等于它自己。
你实际上不需要 p
,你可以在你的 PHP 脚本中检查 $_SERVER['REQUEST_URI']
,它会告诉你原始请求的 URI(与 REQUEST_URI
下面,每次重写都会改变)。
所以只用这个:
RewriteCond %{REQUEST_URI} !=/index.php
RewriteRule ^ index.php [L]
但是...您可能希望提供存在的文件,例如图像、脚本等,所以通常的做法是执行此操作并检查文件是否存在:
RewriteCond %{REQUEST_URI} !=/index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
虽然执行此操作并列出其中包含您要提供的文件的目录效率更高:
RewriteCond %{REQUEST_URI} !=/index.php
RewriteCond %{REQUEST_URI} !^/(?:images|css|scripts)/
RewriteRule ^ index.php [L]
只需将列表更改为包含您的静态文件的目录的名称。
更新
从评论来看,您似乎有另一个重写,将 .php
添加到 URLs,因此他们可以在没有它的情况下工作。为了不将它们重写为 index.php
,我建议将重写放在这个之前。否则,您可以像这样检查 URL 是否存在,并在其末尾带有 .php
。也许将它与文件夹检查结合起来,而不是进行两次文件系统检查。
RewriteCond %{REQUEST_URI} !=/index.php
RewriteCond %{REQUEST_FILENAME}.php !-f
RewriteCond %{REQUEST_URI} !^/(?:images|css|scripts)/
RewriteRule ^ index.php [L]
您可以像这样向第三条规则添加特定文件例外:
RewriteCond %{REQUEST_URI} !=/index.php
RewriteCond %{REQUEST_URI} !^/(?:images|css|scripts)/
RewriteCond %{REQUEST_URI} !=/some/url.php
RewriteCond %{REQUEST_URI} !=/some_other_url.php
RewriteRule ^ index.php [L]
的确,正如 @SuperDuperApps 假设的那样,问题是 WAMP 默认启用了 MultiViews
。将 Options -MultiViews
添加到我的 .htaccess
文件解决了我所有的问题,我在问题中提到的初始代码现在可以正常工作了。
我正在尝试将所有请求重写到 index.php
,然后根据 $_GET['p']
变量中的值决定要包含哪个文件。例如,我在名为 leltar
的站点的主目录中有一个名为 update.php
的脚本,如果打开的页面是 localhost/leltar/update
.
但是,问题是重写不起作用,因为 WAMP 运行脚本,即使 .php
扩展名不在 link 中。输出只是脚本中的输出,index.php
没有显示任何内容。如何从 运行 具有相似名称的脚本中停止 WAMP?我想,我的 .htaccess 代码也有问题,因为如果我打开 localhost/leltar/update
以外的页面,$_GET['p']
的值是字符串 "index.php"一直。
.htaccess 文件:
RewriteEngine On
RewriteRule ^(.*)$ index.php?p=
index.php:
// ...
switch ($_GET['p']) {
case 'update':
require_once('update.php');
break;
default:
// something else
break;
}
// ...
update.php
内容不相关
编辑:
主要问题是默认情况下,甚至当我使用 RewriteCond %{REQUEST_FILENAME} !-f
重写条件时,如果存在与 link 的用户友好端同名的文件,WAMP 会以某种方式覆盖我的重写规则。如果我将名为 pic.jpg
的图片放入 www
文件夹并打开 localhost/pic.jpg
,显然会显示图像。但是,如果我省略了访问页面 localhost/pic
的扩展程序,我也会得到相同的输出(而不是因为文件夹不存在而出现 404 Not Found 错误,我想)。
编辑 2: 在真实服务器上没有任何问题。如果我遗漏了扩展名,则会抛出 404 错误,所以这绝对是 WAMP 特定的东西。
.htaccess
文件中的规则有效地循环,直到 URL 没有改变(因为每次都重新开始处理,这意味着规则也会再次处理)所以你的规则当然会循环直到p
等于它自己。
你实际上不需要 p
,你可以在你的 PHP 脚本中检查 $_SERVER['REQUEST_URI']
,它会告诉你原始请求的 URI(与 REQUEST_URI
下面,每次重写都会改变)。
所以只用这个:
RewriteCond %{REQUEST_URI} !=/index.php
RewriteRule ^ index.php [L]
但是...您可能希望提供存在的文件,例如图像、脚本等,所以通常的做法是执行此操作并检查文件是否存在:
RewriteCond %{REQUEST_URI} !=/index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
虽然执行此操作并列出其中包含您要提供的文件的目录效率更高:
RewriteCond %{REQUEST_URI} !=/index.php
RewriteCond %{REQUEST_URI} !^/(?:images|css|scripts)/
RewriteRule ^ index.php [L]
只需将列表更改为包含您的静态文件的目录的名称。
更新
从评论来看,您似乎有另一个重写,将 .php
添加到 URLs,因此他们可以在没有它的情况下工作。为了不将它们重写为 index.php
,我建议将重写放在这个之前。否则,您可以像这样检查 URL 是否存在,并在其末尾带有 .php
。也许将它与文件夹检查结合起来,而不是进行两次文件系统检查。
RewriteCond %{REQUEST_URI} !=/index.php
RewriteCond %{REQUEST_FILENAME}.php !-f
RewriteCond %{REQUEST_URI} !^/(?:images|css|scripts)/
RewriteRule ^ index.php [L]
您可以像这样向第三条规则添加特定文件例外:
RewriteCond %{REQUEST_URI} !=/index.php
RewriteCond %{REQUEST_URI} !^/(?:images|css|scripts)/
RewriteCond %{REQUEST_URI} !=/some/url.php
RewriteCond %{REQUEST_URI} !=/some_other_url.php
RewriteRule ^ index.php [L]
的确,正如 @SuperDuperApps 假设的那样,问题是 WAMP 默认启用了 MultiViews
。将 Options -MultiViews
添加到我的 .htaccess
文件解决了我所有的问题,我在问题中提到的初始代码现在可以正常工作了。