【问题标题】:Rewriting url parameters using rewritemap and mysql使用rewritemap和mysql重写url参数
【发布时间】:2013-04-02 06:25:14
【问题描述】:

我意识到这个问题已经被很多人打死了,但大多数答案似乎都是针对一个非常具体的案例,只适合他们的需求,到目前为止我还没有找到合适的解决方案(至少,据我所知)。

我的问题是我试图让我的网站将 URL 参数从 ID 重定向到实际字符串。

例如:

www.example.com/?category=1

将显示为:

www.example.com/software

同时

www.example.com/?category=2

将显示为:

www.example.com/software/desktop

根据我阅读的内容,我应该研究 apache rewritemap,这就是我的困惑所在。我真的不想从平面 txt 文件中加载,因为我'我想让它尽可能动态,我已经读过我可以让它从 php 文件中读取并从 MySQL 数据库中读取,这就是我想要的。

问题在于,我真的不太确定实现这一目标的正确方法是什么。 RewriteMap 文档仅在某种程度上涵盖了平面 .txt 文件,并没有通过 MySQL 实现。

所以基本上我要问的是是否有人可以解释如何实现我正在寻找的东西,或者至少为我指明正确的方向。遗憾的是,到目前为止,我发现的大多数线程还没有太大帮助,但我可能已经通过了有用的线程。

如果有帮助,现在,我的 MySQL 数据将被格式化为继承结构,如下所示:

 ID |   Title          |   Link             | Parent
  1 | Software         | /Software/         |  NULL
  2 | Desktop Software | /Software/Desktop/ |   1
  2 | Mobile Software  | /Software/Mobile/  |   2

PS: 我应该补充一点,我发现的大多数解决方案都以此为例:

  RewriteMap examplemap prg:/path/to/file.php
  RewriteRule (.*) ${examplemap:$1}

但它从不提供有关该 file.php 中的内容以及它如何查询和返回值的信息。

编辑 我应该提到我在共享托管服务器上,而不是我自己的私人服务器,因此我可能无法访问所有可能的选项

编辑 2 只是为了清楚起见: 我要做的是让访问“example.com/software”的用户被视为在“example.com/?category=1”上;基本上美化链接并使其更具可读性。唯一的问题是,我正在尝试从数据库中读取它

【问题讨论】:

  • +1 用于清楚地解释手头的问题。

标签: php mysql .htaccess mod-rewrite rewritemap


【解决方案1】:

如果您无权访问服务器或虚拟主机配置,则无论如何都不能使用RewriteMap。映射本身需要在服务器或虚拟主机配置中定义,而不是在 htaccess 文件中。但是 apache 2.4 可以选择使用 mod_dbd 来使用 SQL query to define a rewrite map

如果您需要访问 MySQL,最好在 PHP 中完成所有这些操作,而不是使用 mod_rewrite。您将使用 mod_rewrite 路由到您的 php 文件,然后该文件将重定向。也许是这样的?

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /file.php?link=$1 [L]

因此,当有人请求 http://example.com/Software/Mobile/ 时,请求会被重写为:/file.php?link=Software/Mobile/,而您的 file.php 脚本会进行查找。

或者,如果您实际上是相反的意思:

RewriteCond %{QUERY_STRING} category=([0-9]+)
RewriteRule ^$ /file.php?ID=%1 [L]

因此,当有人请求 http://example.com/?category=2 时,请求会被重写为:/file.php?ID=2,并且 php 脚本会进行查找。

【讨论】:

  • 感谢您的回复!我会更好地澄清我在寻找什么;我想要它以便访问 example.com/software 的人在内部被解析为 example.com/?category=1;基本上“漂亮”的链接。使用您发布的内容,是否会像这样使用: RewriteCond %{"SELECT link FROM category WHERE id = %s"} ?还是我理解得很奇怪?编辑:另外,file.php 将如何进行查找?它必须返回一个值吗?
  • 忽略我上面的帖子,我明白你现在在说什么(我想我当时只是傻了)。完美的!谢谢大佬
  • 有什么方法可以保证,当链接作为参数传递时,有一个斜杠?因为 'software/desktop' 不等同于查询中的 'software/desktop/'。这只是在 $__GET['link'] 之后的 PHP 脚本吗?还是有一种 apache 方式来做到这一点?
  • @Bitwize 你的意思是这样吗? RewriteRule ^(.*/)$ /file.php?link=$1 [L](强制使用斜杠并作为“link”参数传递)或RewriteRule ^(.*)/$ /file.php?link=$1 [L](强制使用斜杠,但不包含在“link”参数中)
  • 第一个是我想要完成的,如果那里没有斜杠,它会自动添加一个斜杠并将其作为参数发送(所以有人访问'example.com/software'将与“example.com/software/”相同);你刚才提到的重写规则只是使它不传递参数,除非它有最后的斜杠。是否应该只使用 PHP 来完成?
【解决方案2】:

我的建议是考虑使用前端控制器模式。我认为,一旦您开始了解用户友好的 URL 或“路由”的概念,前端控制器就可以真正简单地处理事情,因为您不再需要担心将特定 URL 映射到 Web 服务器级别的特定控制器。

如果您启用了 Apache mod_dir(很有可能),您可以在 Apache 配置或 .htaccess 中执行类似的操作:

FallbackResource /index.php

这个简单的指令会将任何会导致 404 错误的请求定向到位于 /index.php 的前端控制器。

这也可以通过mod_rewrite 来完成,如下所示:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php [L,QSA]

在前端控制器中,您可以评估 URI 并将请求路由到需要处理请求的任何逻辑。您可以通过从数据库中查找路线或硬编码的路线数组或其他方式来做到这一点。 (但我建议,如果使用数据库,您可以使用缓存版本的路由以供快速访问)。

有许多不同的 PHP 路由控制器可用,因此您无需重新发明轮子(大多数现代框架都有某种路由概念)。

【讨论】:

  • 我不确定这是否是我想采用的方法。我只是对它做了一些阅读,如果重写规则不匹配,它看起来主要是一个后备。我提供的上述数据库只是网站所有部分的一小部分,为了便于解释,我对其进行了简化。这就是我重写 URL 参数的原因。不过谢谢你的回答! (如果我对它的理解有误,请随时纠正我)
  • @Bitwize 你也可以使用 mod_rewrite 来建立一个前端控制器(事实上,你通常看到它已经完成了)。我已经更新了答案以显示这种方法。我倾向于使用 FallbackResource 路由到前端控制器,但使用重写规则来实际重写/重定向由于任何原因需要我更改的 URL。如果您有许多路由,您可能正在为其编写特定的重写规则,这可能是转移到前端控制器的更多理由,因为仅在应用程序级别处理路由逻辑更易于维护。
猜你喜欢
  • 1970-01-01
  • 2011-12-07
  • 1970-01-01
  • 1970-01-01
  • 2019-08-11
  • 1970-01-01
  • 2017-11-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多