Apache 如何防止mod_rewrite多次重写URL?

Apache 如何防止mod_rewrite多次重写URL?,apache,mod-rewrite,Apache,Mod Rewrite,我想使用mod_rewrite将一些人性化的URL重写到名为php的文件夹中的任意文件中(该文件夹位于web根目录内,因为mod_rewrite显然不允许您重写到web根目录外的文件) 以下是我的重写规则: Options +FollowSymlinks RewriteEngine On RewriteRule ^$ php/home.php [L] RewriteRule ^about$ php/about_page.php [L] RewriteRule ^contact$ php/con

我想使用mod_rewrite将一些人性化的URL重写到名为
php
的文件夹中的任意文件中(该文件夹位于web根目录内,因为mod_rewrite显然不允许您重写到web根目录外的文件)

以下是我的重写规则:

Options +FollowSymlinks
RewriteEngine On

RewriteRule ^$ php/home.php [L]
RewriteRule ^about$ php/about_page.php [L]
RewriteRule ^contact$ php/contact.php [L]
但是,我还想阻止用户直接访问这个
php
目录中的文件。如果用户输入以
/php
开头的anyURL,我希望他们获得404页面

我尝试在末尾添加此额外规则:

RewriteRule ^php php/404.php [L]
…(其中404.php是一个输出404头和“未找到”消息的文件。)

但是当我访问
/
/about
或/
contact
时,我总是被重定向到404。似乎最终的重写规则甚至适用于内部重写的URL(因为它们现在都以
/php
开头)


我以为
[L]
标志(在前三条重写规则上)应该阻止应用更多的规则?我做错什么了吗?(或者有更聪明的方法来做我想做的事情吗?

[L]标志应该只在最后一条规则中使用


L-最后一条规则-停止此处的重写过程,不再应用任何重写规则&因为您面临问题。

[L]标志应仅在最后一条规则中使用


L-最后一条规则-在此处停止重写过程,不再应用任何重写规则&因为您面临问题。

我也有类似的问题。我有一个用PHP编写的基于模型-视图-控制范式的内容管理系统。最基本的部分是
mod_rewrite
。我已经成功地阻止了对PHP文件的全局访问。该技巧的名称为\u请求

有什么问题吗?

重写模块重写URI。如果URI与规则匹配,则会重写该URI,并对新的重写URI应用其他规则。但是如果匹配的规则以
[L]
结束,则引擎实际上不会终止,而是重新启动。然后新的URI不再匹配以
[L]
结尾的规则,继续并匹配最后一个。结果如何?程序员在意外的404错误页面开始说脏话。不管计算机做什么,你们说什么,不做什么,你们想要什么。我的
.htaccess
文件中有这个:

RewriteEngine On
RewriteBase /
RewriteRule ^plugins/.* pluginLoader.php [L]

RewriteCond %{REQUEST_URI} \.php$
RewriteRule .* index.php [L]
那是错误的。甚至以
plugins/
开头的URI也被重写为
index.php

解决方案

当且仅当原始-未重写-URI与规则匹配时,才需要应用该规则。遗憾的是,
mod_rewrite
没有提供任何包含原始URI的变量,但它提供了一些
包含HTTP请求头第一行的_请求
变量。这个变量是不变的。当重写引擎工作时,它不会更改

...
RewriteCond %{THE_REQUEST} \s.*\.php\s
RewriteRule \.php$ index.php [L]

正则表达式是不同的。它不仅仅应用于URI,而是应用于头的整个第一行,这意味着类似于
GET/script.php HTTP/1.1
。但关键规则是,只有当用户直接显式请求某些PHP脚本时,才会应用此规则。未使用重写的URI

我也有类似的问题。我有一个用PHP编写的基于模型-视图-控制范式的内容管理系统。最基本的部分是
mod_rewrite
。我已经成功地阻止了对PHP文件的全局访问。该技巧的名称为\u请求

有什么问题吗?

重写模块重写URI。如果URI与规则匹配,则会重写该URI,并对新的重写URI应用其他规则。但是如果匹配的规则以
[L]
结束,则引擎实际上不会终止,而是重新启动。然后新的URI不再匹配以
[L]
结尾的规则,继续并匹配最后一个。结果如何?程序员在意外的404错误页面开始说脏话。不管计算机做什么,你们说什么,不做什么,你们想要什么。我的
.htaccess
文件中有这个:

RewriteEngine On
RewriteBase /
RewriteRule ^plugins/.* pluginLoader.php [L]

RewriteCond %{REQUEST_URI} \.php$
RewriteRule .* index.php [L]
那是错误的。甚至以
plugins/
开头的URI也被重写为
index.php

解决方案

当且仅当原始-未重写-URI与规则匹配时,才需要应用该规则。遗憾的是,
mod_rewrite
没有提供任何包含原始URI的变量,但它提供了一些
包含HTTP请求头第一行的_请求
变量。这个变量是不变的。当重写引擎工作时,它不会更改

...
RewriteCond %{THE_REQUEST} \s.*\.php\s
RewriteRule \.php$ index.php [L]

正则表达式是不同的。它不仅仅应用于URI,而是应用于头的整个第一行,这意味着类似于
GET/script.php HTTP/1.1
。但关键规则是,只有当用户直接显式请求某些PHP脚本时,才会应用此规则。未使用重写的URI

但这正是我想要的,在这里结束重写过程。我是说,我不希望它在一个匹配后继续应用后续规则。但最终的规则总是会被执行,即使之前的规则(带有[L]标志)已经被执行。为什么?但这正是我想要的,在这里结束重写过程。我是说,我不希望它在一个匹配后继续应用后续规则。但最终的规则总是会被执行,即使之前的规则(带有[L]标志)已经被执行。为什么?