【问题标题】:Removing the query string and redirecting (rewrite rule and rewrite cond)删除查询字符串和重定向(rewrite rule 和 rewritecond)
【发布时间】:2017-04-05 16:11:07
【问题描述】:

我目前正在尝试设置重写规则,以设置内部重定向以获得更适合 SEO 的 url 结构。

我要展示:

/find-teacher/primary-school.php

而不是悲伤的样子:

/find-teacher/subject-class-choose.php?school=primary-school

在阅读了一些关于重写规则和重写条件的帖子和教程后,我想出了这个:

在我的 choose-school.php 中,我有一个带有漂亮 url 的链接:

<a href="https://www.example.com/find-teacher/primary-school.php">
Primary School</a>

在我的 .htaccess 中:

RewriteCond %{REQUEST_URI} ^find-teacher/primary-school.php$
RewriteRule ^find-teacher/([a-z-]+)-([0-9]+).php$ /find-teacher/subject-class-choose.php?school=$1 [NC]

现在,如果我做对了,RewriteCond 部分会检查是否请求了以下 url。如果是这样,那么([a-z-]+)-([0-9]+)的部分被替换部分的$1替换(/find-teacher/subject-class-choose.php?school=$1)

问题是如果我点击/find-teacher/primary-school.php,我会被重定向到我的错误页面

【问题讨论】:

  • 查询字符串school_id=1是否表示小学数据?
  • @AbhishekGurjar 对不起,我把它改成了school_id=primary-school

标签: php .htaccess mod-rewrite


【解决方案1】:

您在这里不需要 RewriteCond 和 RewriteRule,因为它们正在(或应该)都检查相同的东西。

但是,目前没有可以匹配这两种模式的 URL。让我们分解问题。

要专门检查 URL /find-teacher/primary-school.php,您可以写:

RewriteRule ^find-teacher/primary-school.php$ /find-teacher/subject-class-choose.php?school=primary-school [NC]

下一步是用(和)“捕获”“小学”,并用$1将其动态放置到目标上:

RewriteRule ^find-teacher/(primary-school).php$ /find-teacher/subject-class-choose.php?school=$1 [NC]

最后,我们可以使用正则表达式 [a-z-]+ 使模式匹配任何字母或连字符而不是精确字符串:

RewriteRule ^find-teacher/([a-z-]+).php$ /find-teacher/subject-class-choose.php?school=$1 [NC]

在您问题的规则中,您在正则表达式中添加了一个额外的部分:-([0-9]+)。这匹配-,然后是一个数字。要获取该数字,您可以将 $2 放在目标中的某个位置:

RewriteRule ^find-teacher/([a-z-]+)-([0-9]+).php$ /find-teacher/subject-class-choose.php?school=$1&id=$2 [NC]

这将匹配 /find-teacher/primary-school-123.php 之类的内容,并将其转换为 /find-teacher/subject-class-choose.php?school=primary-school&amp;id=123。

最后两点:

  • 根据您的 Apache 配置的设置方式,您可能需要也可能不需要在您的模式中包含前导 /,即以 ^/ 开头
  • 我发现一个调试重写规则的好方法是让它们重定向你的浏览器,通过将R=temp添加到标志(例如[NC,R=temp]);这样,您就不必依赖 PHP 代码来告诉您请求的 URL 是什么

【讨论】:

  • 非常感谢!我的页面/find-teacher/primary-school.php 现在重定向到/find-teacher/subject-class-choose.php?school=primary-school。但问题是,我认为这是一个对访问者不可见且对 SEO 友好的“内部”重定向——如果我从链接重定向到看起来很悲伤的 url,它仍会在 url 地址栏中显示为目标 url。我一直在查看更多教程,但他们都说这将是“不可见的”和“内部的”,尽管它不在我身边:(。我在这里做错了什么?
  • @Franky2207 使用[R] 标志,告诉浏览器转到新的URL;没有它,Apache 只是“假装”你在新的 URL 上,而不告诉浏览器。您可能还想添加[L](用于“Last”)标志,以阻止配置中进一步的其他规则导致额外的重定向。请注意,如果您使用[R] 而不使用=temp,它将发出“永久”重定向,并且您的浏览器可能会或多或少地永久缓存该重定向;使用稍微不同的 URL 进行测试,以确保这不是问题。
  • 再次感谢。这是否意味着,我必须使用[R] 标志,否则重定向无法正常工作?我想我并没有真正理解告诉浏览器和假装浏览器之间的区别。如果我省略了[R] 标志,它会按原样显示/primary-school.php。它还通过$_GET 从school_id 传输值。是否仍然不建议省略 [R] 标志?我还尝试使用不同的 URL 并使用 [L] 标志,但如果我包含 [R=temp],它仍然会导致地址栏中出现“悲伤的 url”。
  • 在您的情况下,省略 [R] 标志是正确的。这不是关于推荐与否,而是关于不同的用例。如果您想说“您输入了旧的或错误的 URL,请转至此处”,您会想告诉浏览器,因此可以使用 [R];在您的情况下,您想说“这是一个不错的 URL,我知道您的意思”,所以 不会 使用 [R]。我可能对我的注释感到困惑,即有时使用[R=temp] 用于测试很有用,因为当它显示在地址栏中时,您可以更轻松地看到它的结果;一旦你完成了测试,你就会拿走旗帜。
  • 非常感谢您的帮助。我现在明白了 :) 真的很乐意帮助我!
猜你喜欢
  • 2011-03-11
  • 1970-01-01
  • 1970-01-01
  • 2016-06-11
  • 2014-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-30
相关资源
最近更新 更多