我想使用mod_rewrite将一些人性友好的URL重写为名为php
的文件夹中的任意文件(在web根目录中,因为mod_rewrite显然不会让你重写到网络外的文件根)。
/ --> /php/home.php
/about --> /php/about_page.php
/contact --> /php/contact.php
以下是我的重写规则:
Options +FollowSymlinks
RewriteEngine On
RewriteRule ^$ php/home.php [L]
RewriteRule ^about$ php/about_page.php [L]
RewriteRule ^contact$ php/contact.php [L]
但是,我还想阻止用户直接访问此php
目录中的文件。如果用户输入以/php
开头的任何网址,我希望他们获得404页面。
我尝试在最后添加这个额外的规则:
RewriteRule ^php php/404.php [L]
...(其中404.php是一个输出404标题和“未找到”消息的文件。)
但是当我访问/
或/about
或/ contact
时,我总是被重定向到404.似乎最终的RewriteRule甚至应用于内部重写的URL(因为它们现在都以/php
开头。
我认为[L]
标志(在前三个RewriteRules上)应该阻止进一步的规则被应用?难道我做错了什么? (或者有更聪明的方法来做我想做的事情吗?)
答案 0 :(得分:0)
[L]标志只能在最后一条规则中使用,
L - 最后规则 - 停止重写过程,不再应用任何重写规则&因为你正面临着问题。
答案 1 :(得分:0)
我有类似的问题。我有一个用PHP编写的内容管理系统,它基于Model-View-Control范例。最基本的部分是mod_rewrite
。我已成功阻止全局访问PHP文件。技巧名为THE_REQUEST
。
有什么问题?
重写模块会重写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的任何变量,但它提供了一些THE_REQUEST
变量,其中包含第一行HTTP请求标头。这个变量是不变的。重写引擎工作时它不会改变。
...
RewriteCond %{THE_REQUEST} \s.*\.php\s
RewriteRule \.php$ index.php [L]
正则表达式不同。它不仅仅应用于URI,而是应用于标题的整个第一行,这意味着类似于GET /script.php HTTP/1.1
。但关键规则是仅在用户直接明确请求某些PHP脚本时应用此时间。不使用重写的URI。