让我们确保我们在同一页面上。 ;) 在我的服务器根目录中,我有一个 .htaccess 文件,在该文件中我有:
RewriteEngine On
RewriteRule ^(.+/)?custom $1index.php?page=value [NC,L]
RewriteRule 包含三个组件:匹配模式、目标和标志列表。匹配模式可以包含纯文本或正则表达式。目标可以包含纯文本或带有在正则表达式匹配模式中捕获的混合变量的文本。匹配模式和目标都相对于 .htaccess 文件所在的目录。
匹配模式与当前目录之后的 URL 中的文本进行比较。如果匹配成功,则从 .htaccess 文件所在的目录调用目标。如果在匹配模式中捕获信息,则首先在目标中插入目标中的变量。
在本例中,.htaccess 文件位于服务器根目录中,因此匹配模式将与以下 URL 文本进行比较:http://localhost/
为了测试它,这是我放在 index.php 文件中的 PHP 代码:
<?php
echo 'page value: ' .$_GET['page'] . '<br>';
echo 'script loaded: ' . $_SERVER['PHP_SELF'];
?>
当我在浏览器中导航到 http://localhost/custom 时:正则表达式匹配模式与字符串“custom”进行比较,匹配成功,因此目标 index.php?page=value 被执行,我得到 index.php 页面加载的根目录。显示的页面如下所示:
page value: value
script loaded: /index.php
接下来,我在服务器根目录中创建一个名为 "newFolder" 的新目录,并将 index.php 文件复制到新创建的目录中。
当我在浏览器中导航到 http://localhost/newFolder/custom 时:正则表达式匹配模式与字符串 “newFolder/custom” 进行比较,再次成功匹配,这次是目标 newFolder/index.php?page=value被执行,并且我在加载的 newFolder 目录中获得了 index.php 页面。现在显示的页面如下所示:
page value: value
script loaded: /newFolder/index.php
同样,我可以在根目录中创建任意数量的目录并在这些目录中创建新的 index.php 文件,当导航到这些目录中的“自定义”时,这个 .htaccess 文件应该在当前子目录中加载相应的 index.php 文件。
~~~
我将在这里冒险并假设您要动态加载页面,因此将“自定义”捕获为动态页面名称并将其转储到页面字段中(替换“值”)并将其发送到当前子目录下的 index.php 文件。
RewriteEngine On
RewriteCond %{REQUEST_URI} !index\.php
RewriteRule ^(.+/)?(.+)$ $1index.php?page=$2 [NC,L]
如前所述,括号捕获动态文本并将其转储到美元符号数字所在的目标字符串中。因此,第一组括号中捕获的文本替换了“$1”,第二组括号中捕获的文本替换了“$2”。我还添加了RewriteCond 语句以防止此规则重复使用。 :) 如果我不这样做,则“自定义”调用和重定向到 index.php 都会执行此规则。
所以现在当我导航到http://localhost/newFolder/whoopdeedoo 时,正则表达式匹配模式与“newFolder/whoopdeedoo”进行比较,匹配成功,目标newFolder/index.php?page=whoopdeedoo 被执行,我得到:
page value: whoopdeedoo
script loaded: /newFolder/index.php
~~~
冒着嗡嗡声的风险,这里有一些背景信息。您提到这在根目录中有效:
RewriteEngine On
RewriteRule ^custom index.php?page=value [NC,L]
但在浏览器导航到子目录时它不起作用。阅读 cmets 后,您似乎发现下一点适用于子目录,特别是“newFolder”:
RewriteEngine On
RewriteRule ^newFolder/custom newFolder/index.php?page=value [NC,L]
但现在它不再适用于根目录。所以你可以简单地包括两者:
RewriteEngine On
RewriteRule ^custom index.php?page=value [NC,L]
RewriteRule ^newFolder/custom newFolder/index.php?page=value [NC,L]
但是,这里有几件事让我很震惊。一是我宁愿将 .htaccess 文件放在每个子目录中并接管那里的 URL 处理,而不是在我的根 .htaccess 中硬编码目录名称。
但是,如果出于某种原因,您更愿意在根目录中维护一个 .htaccess 文件,那么,让我大吃一惊的是规则中的重复。因此,或者,您可以使用正则表达式使子目录名称成为捕获的变量,如本答案顶部所示:
RewriteEngine On
RewriteRule ^(.+/)?custom $1index.php?page=value [NC,L]
正则表达式捕获括号替换了文本“newFolder/”,在括号内我们说的是“捕获一个或多个字符,后跟一个正斜杠”。然后,如果匹配成功,则捕获的值将替换目标中的“$1”。这也适用于根目录的原因是括号后面的问号使括号内的正则表达式是可选的。因此,如果“自定义”之前没有任何内容,我们仍然适合比赛。在这种情况下,“$1”将被替换为空字符串。