将404重定向到类似的网址

时间:2012-01-20 12:23:43

标签: php mysql .htaccess url-rewriting http-status-code-404

我有一个有故事的网站。我可以在多个类别中拥有多种类型的故事,例如:

  • 儿童
  • 浪漫
  • 科幻
  • 动作
  • thriler
  • 任务

可以使用以下网址访问这些故事:

www.example.com/action/story-name-action/
www.example.com/romance/story-name-romance/

并使用规则将.htaccess重定向到第一个param(action)和第二个(story-name-action)。 这部分工作正常。

最近,我从不同的网站获得了几十个404,这就是我想要做的但我不知道如何:

如果有人输入,例如:/action/story-nme-ction,我想重定向到:action/story-name-action/

有没有一种有效的方法来实现它?

6 个答案:

答案 0 :(得分:37)

哦,伙计哦,伙计!

你所要求的并不简单,需要你拥有一台功能强大的电脑,但结果真是太棒了。

以下是我建议做的事情:

  • 对于404正确处理,您在vhost配置中具有ErrorDocument重定向。我的看起来像这样:ErrorDocument 404 /404.php;
  • 当拥有404时,Apache将使用所有参数调用/404.php(错误的URL等等,转储$_SERVER以查看此内容)。您必须测试网址/中是否只有两个表达式,即http://mysite.com/(expr1)/(expr2)/
  • 如果没有,那就做一个经典的404。
  • 如果是,则使用MySQL进行SOUNDEX搜索(在404 Php文件中)。请参阅查询示例here
  • 然后,在这个“特殊”的404案例中,做一个像google那样的建议,即:“你的意思是/action/story-name-action/吗?如果是的话,点击链接”。

这是一项艰苦的工作,但它既有趣又能展示你的技巧。很少有网站这样做(我实际上只知道谷歌)。

这是我法语表上的一个演示,它可以让你概述它的工作原理:

mysql> SELECT * FROM job WHERE
SOUNDEX( description ) LIKE SOUNDEX('Machiniste cinéma');
+-------+--------------------+
| id    | description        |
+-------+--------------------+
| 14018 | Machiniste cinéma  |
+-------+--------------------+
1 row in set (0.06 sec)

mysql> SELECT * FROM job WHERE
SOUNDEX( description ) LIKE SOUNDEX('Mchiniste cinéma');
+-------+--------------------+
| id    | description        |
+-------+--------------------+
| 14018 | Machiniste cinéma  |
+-------+--------------------+
1 row in set (0.06 sec)

mysql> SELECT * FROM job WHERE
SOUNDEX( description ) LIKE SOUNDEX('Machnste cinema');
+-------+--------------------+
| id    | description        |
+-------+--------------------+
| 14018 | Machiniste cinéma  |
+-------+--------------------+
1 row in set (0.06 sec)

mysql> 

答案 1 :(得分:18)

除非您非常确定用户真正想要导航到的网址,否则使用重写/重定向到特定网址是一个非常糟糕的主意。

举个例子,假设您想要处理掉掉两个字母的每个案例,在URL的最后部分有17个字符,那就是17 * 16 = 272个组合,而有可能匹配多个'假的'url与一个正则表达式,你将需要很多重写规则。

更好的解决方案是,使用PHP实现404处理程序(因为您在q中包含了该标记),以生成(例如)前10个URL的列表,其路径与请求的路径具有最短的levenstein距离,以及默认链接和支持文本。 (有基于mysql的实现 - 尝试谷歌的URL)。 NB处理程序仍应返回404状态 - NB HTML内容必须超过最小长度才能抑制MSIE的“友好”错误消息。

答案 2 :(得分:7)

如果您知道可能的URL是什么,可以使用:

levenshtein($givenURL, $possibleURL)

PHP文档示例,为简洁起见删除了注释:

$input = 'carrrot';

$words  = array('apple','pineapple','banana','orange',
                'radish','carrot','pea','bean','potato');

$shortest = -1;

foreach ($words as $word) {
    $lev = levenshtein($input, $word);
    if ($lev == 0) {
        $closest = $word;
        $shortest = 0;
        break;
    }
    if ($lev <= $shortest || $shortest < 0) {
        $closest  = $word;
        $shortest = $lev;
    }
}

echo $shortest == 0 ? "Exact match found: $closest\n" : "Did you mean: $closest?\n";

输出:

  

输入字:carrrot
  你的意思是:胡萝卜?

如果你认为人们可能已经遗漏了一封信或者放了一个额外的信,这很好,但当人们真的不知道如何拼写单词并想出一些有创意的东西时,它可能会失败!

如果您更喜欢soundex()路线,请查看metaphone()功能。

我喜欢在metaphone() levenshtein() 旁边使用similar_text()的想法,因为它会返回该单词的语音表示,但您仍然希望看到它与你的原作有多相似。

示例:

metaphone('name') = NM
metaphone('naaaaaameeeeeeee') = NM
metaphone('naiym') = NM
metaphone('naiyem') = NYM

虽然很多拼写错误都会返回相同的匹配,但最后一个示例显示您仍然希望找到与levenshtein()

之类的匹配最接近的匹配

为了提高效率,如果你使用一个不同的404文件,其中重写试图匹配这个模式并且失败,那么比你用于网站的其余部分,它真的不应该是一个巨大的开销。

如果您从同一个推荐人那里获得相同的404,(并且无法让他们更改链接),那么在这种情况下进行静态重写可能是值得的。

答案 3 :(得分:4)

有一些解决方案:

  • 确定错误网址的来源。这根本不应该发生,我无法想象为什么会这样。是否有其他人从其他地方链接并且他们打错了(忽略了复制和粘贴的存在)?你能看到它的来源(引用者)并与他们联系吗?
  • 为网址添加ID,/action/123/story-name-action,您可以在其中查看ID上的文章而不是其标题(奖励:添加创建具有相同标题的同一类别的多个故事的可能性)< / LI>
  • 使用fuzzy search之类的内容对标题执行soundex,并将用户重定向到最合适的标题,或者显示具有类似@symcbean建议的相似标题的概述页。

我更喜欢ID。

答案 4 :(得分:1)

我们将重定向设置为搜索页面,以便我们的搜索具有“建议”功能。

答案 5 :(得分:0)

由于值(大概)是根据标题从MySQL中提取的,因此您可以在标题列上放置FULLTEXT索引,并使用MySQL MATCH()函数查找最相关的匹配项,并将用户重定向到该。

虽然这绝不是一个完美的解决方案 - 以任何真实的准确度执行此操作所需的智能类型正在危险地接近Turing test领域。