我没有获得所需的 URLRewrite
I'm not obtaining the desired URLRewrite
我遇到了一个奇怪的 URL 问题。我正在使用 .htaccess
和 header(location)
来设置网址。
我认为我正在使用 header(位置)“重置”底部的网址,但我指定的地址看起来像是附加到当前地址而不是全部替换。
我的代码是:
$route = ltrim(strtok($_SERVER['REQUEST_URI'], '?'), '/');
if($route == strtolower($route)) {
if($route === 'contact/edit') {
include __DIR__ . '/../myscripts/MainScript.php';
$driver = new MainDriver();
$page = $driver->edit();
}elseif($route === 'contact/add' ) {
include __DIR__ . '/../myscripts/MainScript.php';
$driver = new MainDriver();
$page = $driver->add();
}else {
include __DIR__ . '/../myscripts/MainScript.php';
$driver = new MainDriver();
$page = $driver->home();
}
}else {
http_response_code(301);
header('location: index.php?route=' . strtolower($route));
}
.htaccess 看起来像这样:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /index.php [NC,L,QSA]
RewriteRule ^/contact/edit(new|existing)$ /index.php?route=/contact/edit [NC,L,QSA]
本地主机打开就好了。但是,如果我尝试去 localhost/contact/editNew
,而不是把我带到 localhost/contact/editnew
,我会被带到 localhost/contact/index.php?contact/editnew
并且欢迎页面 index.php
被加载!
我认为最后的重写规则是必须修改的内容,但我不确定。这就是为什么我在这里寻求帮助。我根据我阅读的 apache.org 上的 mod_rewrite 页面编写了该规则。
如果您需要更多详细信息来理解此问题,请告诉我。
(编辑#2)
我已将 header 调用编辑为
header('location: ' . strtolower($route);
还是得到了同样的结果,证实了问题出在我现在学习的URLRewrite规则上。你们知道如何解决这个问题吗?
您发布的代码存在一些问题...
http_response_code(301);
header('location: index.php?route=' . strtolower($route));
您在 Location
header 中传递了一个 亲属 URL。 浏览器 将相对于当前 URL 解决此问题。如果请求的 URL 是 /contact/editNew
那么以上将导致重定向到 /contact/index.php?route=<route>
.
你在Location
中设置的URL至少应该是root-relative(以斜杠开头),或者绝对的(最好)。
这也是 301(永久)重定向,因此将由浏览器永久缓存。 (使用 302(临时)重定向测试 以避免潜在的缓存问题。)
您正在重定向到一个查询字符串 route=<route>
,您也在尝试在您的 RewriteRule
指令之一中执行此操作。但是,您的 PHP 脚本仅配置为解析 URL-path - 查询字符串从请求中剥离以计算路由:
$route = ltrim(strtok($_SERVER['REQUEST_URI'], '?'), '/');
这会检索 URL 之前 查询字符串和 丢弃 查询字符串的部分。它还从 URL-path 的开头修剪 /
,使其成为 relative。因此,如果您稍后使用 header('location: ' . strtolower($route));
- 您将遇到与上述相同的问题。
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /index.php [NC,L,QSA]
RewriteRule ^/contact/edit(new|existing)$ /index.php?route=/contact/edit [NC,L,QSA]
第二条规则似乎没有任何作用?在 RewriteRule
模式 上使用斜杠前缀并且在重写为 /index.php
之后出现它无论如何都不会做任何事情。
但它也不需要做任何事情,至少根据您的 PHP 脚本不需要。您的 PHP 脚本查看 请求的 URL 上的 URL-path。它没有查看重写的 URL 或查询字符串。
次要点,但第一个 RewriteRule
上的 NC
和 QSA
标志是多余的,正则表达式可以简化为一个点。 substitution 字符串上的斜杠前缀不是必需的。例如:
RewriteRule . index.php [L]
如果您只是想将所有 URL 转换为小写,那么您可以在 .htaccess
、之前 您现有的指令中执行此操作:
# Convert URL to lowercase.
RewriteCond expr "tolower(%{REQUEST_URI}) =~ /(.*)/"
RewriteRule [A-Z] %1 [R=301,L]
更新: 也许您想将请求的 URL-path 作为查询字符串传递给您的脚本?但是,如前所述,您的 PHP 当前使用的是 URL-path,而不是查询字符串。
例如,您的 .htaccess
会像下面这样:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php?route= [QSA,L]
您的 PHP 脚本现在将接收 route
作为查询字符串的一部分。您可以在 PHP 脚本中使用 $_SERVER['QUERY_STRING']
或 $_GET['route']
超全局变量来检查。 Or/and,您仍然可以检查您当前正在执行的请求 URL-path,以提供两种访问您的页面的方法。
请注意,通过上述重写,route
URL-parameter 将不会出现在对主页的请求中,因为这是由 DirectoryIndex
处理的(mod_dir).
我遇到了一个奇怪的 URL 问题。我正在使用 .htaccess
和 header(location)
来设置网址。
我认为我正在使用 header(位置)“重置”底部的网址,但我指定的地址看起来像是附加到当前地址而不是全部替换。
我的代码是:
$route = ltrim(strtok($_SERVER['REQUEST_URI'], '?'), '/');
if($route == strtolower($route)) {
if($route === 'contact/edit') {
include __DIR__ . '/../myscripts/MainScript.php';
$driver = new MainDriver();
$page = $driver->edit();
}elseif($route === 'contact/add' ) {
include __DIR__ . '/../myscripts/MainScript.php';
$driver = new MainDriver();
$page = $driver->add();
}else {
include __DIR__ . '/../myscripts/MainScript.php';
$driver = new MainDriver();
$page = $driver->home();
}
}else {
http_response_code(301);
header('location: index.php?route=' . strtolower($route));
}
.htaccess 看起来像这样:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /index.php [NC,L,QSA]
RewriteRule ^/contact/edit(new|existing)$ /index.php?route=/contact/edit [NC,L,QSA]
本地主机打开就好了。但是,如果我尝试去 localhost/contact/editNew
,而不是把我带到 localhost/contact/editnew
,我会被带到 localhost/contact/index.php?contact/editnew
并且欢迎页面 index.php
被加载!
我认为最后的重写规则是必须修改的内容,但我不确定。这就是为什么我在这里寻求帮助。我根据我阅读的 apache.org 上的 mod_rewrite 页面编写了该规则。
如果您需要更多详细信息来理解此问题,请告诉我。
(编辑#2)
我已将 header 调用编辑为
header('location: ' . strtolower($route);
还是得到了同样的结果,证实了问题出在我现在学习的URLRewrite规则上。你们知道如何解决这个问题吗?
您发布的代码存在一些问题...
http_response_code(301); header('location: index.php?route=' . strtolower($route));
您在 Location
header 中传递了一个 亲属 URL。 浏览器 将相对于当前 URL 解决此问题。如果请求的 URL 是 /contact/editNew
那么以上将导致重定向到 /contact/index.php?route=<route>
.
你在Location
中设置的URL至少应该是root-relative(以斜杠开头),或者绝对的(最好)。
这也是 301(永久)重定向,因此将由浏览器永久缓存。 (使用 302(临时)重定向测试 以避免潜在的缓存问题。)
您正在重定向到一个查询字符串 route=<route>
,您也在尝试在您的 RewriteRule
指令之一中执行此操作。但是,您的 PHP 脚本仅配置为解析 URL-path - 查询字符串从请求中剥离以计算路由:
$route = ltrim(strtok($_SERVER['REQUEST_URI'], '?'), '/');
这会检索 URL 之前 查询字符串和 丢弃 查询字符串的部分。它还从 URL-path 的开头修剪 /
,使其成为 relative。因此,如果您稍后使用 header('location: ' . strtolower($route));
- 您将遇到与上述相同的问题。
RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^.*$ /index.php [NC,L,QSA] RewriteRule ^/contact/edit(new|existing)$ /index.php?route=/contact/edit [NC,L,QSA]
第二条规则似乎没有任何作用?在 RewriteRule
模式 上使用斜杠前缀并且在重写为 /index.php
之后出现它无论如何都不会做任何事情。
但它也不需要做任何事情,至少根据您的 PHP 脚本不需要。您的 PHP 脚本查看 请求的 URL 上的 URL-path。它没有查看重写的 URL 或查询字符串。
次要点,但第一个 RewriteRule
上的 NC
和 QSA
标志是多余的,正则表达式可以简化为一个点。 substitution 字符串上的斜杠前缀不是必需的。例如:
RewriteRule . index.php [L]
如果您只是想将所有 URL 转换为小写,那么您可以在 .htaccess
、之前 您现有的指令中执行此操作:
# Convert URL to lowercase.
RewriteCond expr "tolower(%{REQUEST_URI}) =~ /(.*)/"
RewriteRule [A-Z] %1 [R=301,L]
更新: 也许您想将请求的 URL-path 作为查询字符串传递给您的脚本?但是,如前所述,您的 PHP 当前使用的是 URL-path,而不是查询字符串。
例如,您的 .htaccess
会像下面这样:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php?route= [QSA,L]
您的 PHP 脚本现在将接收 route
作为查询字符串的一部分。您可以在 PHP 脚本中使用 $_SERVER['QUERY_STRING']
或 $_GET['route']
超全局变量来检查。 Or/and,您仍然可以检查您当前正在执行的请求 URL-path,以提供两种访问您的页面的方法。
请注意,通过上述重写,route
URL-parameter 将不会出现在对主页的请求中,因为这是由 DirectoryIndex
处理的(mod_dir).