【问题标题】:Correct approach to ensure a rewritten URL always finds what you expect it to?确保重写的 URL 始终找到您期望的正确方法?
【发布时间】:2011-06-14 12:35:41
【问题描述】:

我正在尝试使用 mod_rewrite 为用户和搜索引擎提供更好看的 URL - 这是许多动态网站上相当普遍的做法。

例如,我从以下开始:

http://www.mydomain.com/profile/view.php?id=136

假设用户号 136 被调用,为了争论 Bob T. Smith the 3rd(抱歉 Bob,如果你存在的话)。

据我所知,我的“讨厌”URL 中必须有 Bob 名字的变体,因为您只能重写存在的内容 - 所以我需要更改我的代码,以便此 URL 找到我们的个人资料'正在寻找:

http://www.mydomain.com/profile/view.php?id=bob-t-smith-the-3rd

现在可以变成

http://www.mydomain.com/profile/bob-t-smith-the-3rd

我正在使用自定义函数将下划线和空格转换为破折号,去除所有非字母数字字符,然后将所有内容小写以使 URL 看起来非常漂亮。

所以在我的页面中,我现在不必查找非常独特的主键“136”,而是查找用户名 - 但经过净化的版本,所以我正在使用这样的东西 -因为MySQL不能做正则表达式:

SELECT LOWER(REPLACE(REPLACE(REPLACE('Bob T. Smith the 3rd'," ","-"),"_","-"),".",""));

该名称显然会被 URL 中的任何内容替换,并进行清理。

我期望的问题是,不想将 MySQL REPLACE() 函数链接在一起来处理每个可能的非法字符(这会令人困惑,难以维护,并且可能效率低下),并且没有执行正则表达式的能力在查询方面,如何确保每次都找到并返回用户配置文件?

如果 Bob 注册为 'Bob T. Smith! (The 3rd)' - 我仍然会在 PHP 中将其清理为 bob-t-smith-the-3rd,因为 preg_replace 去掉了感叹号和括号,但我的查询 - 除非我添加更多 REPLACE () 函数,找不到该用户。

我是否应该确保用户只能使用 A-Z、0-9、破折号和下划线进行注册?

我是否应该以某种方式继续传递唯一的数字 ID,但只是以某种方式从重写规则中省略它?

我完全没有抓住重点吗?有没有一种我没有想到的可接受的方法?

谢谢:-)

【问题讨论】:

  • 我想我偶然发现了另一个潜在的解决方案,到目前为止(在我的大脑中)它对我有用——当用户注册为“Bob T. Smith the 3rd”时——以及将其存储为登录,我可以使用我的自定义 modRewriteEncode() 函数将剥离/清理的版本存储在旁边,以进行数据库查找?有人看到这有问题吗?

标签: php mysql .htaccess mod-rewrite


【解决方案1】:

如果我遗漏了什么,请纠正我,但为什么不直接从调用 php 脚本时在重写规则中添加的破折号中删除用户名?

$undashed_username = explode("-",$dashed_username);
$username = implode(" ",$undashed_username);

然后您可以在您的数据库中搜索。

【讨论】:

  • 对不起,我没有关注你。在数据库中,它完全按照用户注册的方式存储,即“Bob T. Smith the 3rd”——因此当用户登录时,他们可以使用他们注册时使用的名称。在友好的 url 中,它被简化为小写,没有空格,没有标点符号版本 - 这是不可逆的,并且难以在数据库中匹配。
  • 我明白了。获得确定匹配的唯一方法是两个名称相同。您唯一可能的解决方案是对标点符号等进行编码,以便您可以确保匹配。但是,我认为您在用户名中允许使用标点符号会遇到更多问题。即使您对两个不同的用户 Bob 应用了 REPLACE 规则。 T Smith 和 Bob T. Smith(都有唯一的名称)将产生相同的重写用户名。我建议只允许您可以使用所需方案进行编码的用户名。
  • 你有一个有效的点。您对我添加问题的评论的看法 - 即,在用户注册时存储经过清理的版本(可以在 PHP 中检查重复项) - 你认为这可行吗?
  • 我认为这会起作用。这简化了您对与数据库匹配的正确配置文件的搜索。这是一个权衡。您使匹配更简单,但您在数据库中占用了更多空间来存储“冗余”数据。
【解决方案2】:

你为什么不提出这个要求?

http://www.mydomain.com/profile/bob-t-smith-the-3rd?id=136

所以你有一个很好的 URL,你不需要处理实际搜索用户名的问题。

如果您害怕在您的 URL 中包含 ?,您也可以这样做:

http://www.mydomain.com/profile/136/bob-t-smith-the-3rd

然后从请求字符串中解析出数字信息。

这也会减少数据库的工作量。

【讨论】:

  • 我对此的第一个想法是,您在其他网站上并没有真正看到这一点,尽管很难判断他们是在重写 URL,还是他们只是设置了物理页面。假设他们正在重写,他们的友好 URL 中没有包含数字 ID - 所以我想知道他们是否以某种方式传递了 ID 来进行查询,但是从重写的版本中省略了它..?
  • 确实网站在其友好的 URL 中包含数字 ID。只需在 SE 上查看我的个人资料的链接 - 例如:
  • 如果您不喜欢profile/136/bob-t-smith-the-3rd,因为它看起来像您有一个文件夹,请考虑这个(几乎相同)profile/136-bob-t-smith-the-3rd - 您可以轻松地从此类 URL 中提取 id
  • 看看我对这个问题的评论 - 也许我应该在他注册时将“bob-t-smith-the-3rd”与用户名一起存储在数据库中,并确保其唯一性?
  • 您也可以这样做,但在数据库中搜索字符串比搜索唯一(数字)id 更费力。如果您不想要任何数字,那么您需要其他独特的东西来搜索。所以这取决于你能负担得起多少奢侈品。
猜你喜欢
  • 2013-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-21
  • 2011-10-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多