如何使用 mod_rewrite 显示 SEO 友好的 URL?

Posted

技术标签:

【中文标题】如何使用 mod_rewrite 显示 SEO 友好的 URL?【英文标题】:How can I display SEO friendly URLs using mod_rewrite? 【发布时间】:2010-12-03 13:18:14 【问题描述】:

我本质上不是 php 开发人员,我被要求在现有 PHP 网站上执行一些 SEO。

我注意到的第一件事是丑陋的 URL,所以我想让这些 URL 重写为提供更多信息的东西。以下是所有可能的模式:

/index.php?m=ModuleType&categoryID=id
/index.php?m=ModuleType&categoryID=id&productID=id
/index.php?page=PageType
/index.php?page=PageType&detail=yes

所以基本上我想做的就是将这些转换成类似的东西:

/ModuleType/Category
/ModuleType/Category/ProductName
/Page
/Page

在任何建议或示例都很棒之前,我还没有使用过 mod_rewrite!

谢谢。

【问题讨论】:

【参考方案1】:

mod_rewrite 宁愿被用来做相反的事情:在内部将/ModuleType/Category/ProductName 的请求重写为/index.php?m=ModuleType&categoryID=id&productID=id。在文档中使用新的 URL 是您的应用程序的工作。


编辑    下面是一个将参数化 URL 转换为新 URL 的函数的示例:

function url($url, $rules) 
    $url = parse_url($url);
    parse_str($url['query'], $url['query']);
    $argNames = array_keys($url['query']);
    foreach ($rules as $rule) 
        if ($rule[0] == $url['path'] && array_keys($rule[1]) == $argNames) 
            $newUrl = $rule[2];
            foreach ($rule[1] as $name => $pattern) 
                if (!preg_match('/'.addcslashes($pattern, '/').'/', $url['query'][$name], $match)) 
                    continue 2;
                
                $newUrl = str_replace('<'.$name.'>', $match[0], $newUrl);
            
            return $newUrl;
        
    
    return $url;


$rules = array(
    array(
        '/index.php',
        array('m'=>'.*', 'categoryID'=>'.*', 'productID'=>'.*'),
        '/<m>/<categoryID>/<productID>'
    )
);
echo '<a href="' . url('/index.php?m=ModuleType&categoryID=categoryID&productID=productID', $rules) . '">/ModuleType/Category/ProductName</a>';

【讨论】:

好的,那我该怎么做呢?如何将参数化查询转换为更好的 URL? @James:您的 Web 应用程序应该这样做。通常你会有一个从一种形式映射到另一种形式的映射。 是的,但我不太清楚我是怎么做到的,你能举个例子吗? @James:nice to parameterized 还是parameterized to nice 方向? @Gumbo,基本上网站目前的方式是 URL 显示为参数化,所以我希望它们显示得更好。【参考方案2】:

无论如何,我都不是 mod_rewrite 专家,但这是我如何为 Image Flair 网站整理 .htaccess 的示例:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^(.*)/(.*)\.png$ imageFlair.php?mode=$1&userid=$2 [L]
RewriteRule ^(.*)\.png$ imageFlair.php?userid=$1 [L]
</IfModule>

这基本上是地图:

MODE/USERID.png -> imageFlair.php?mode=MODE&userid=USERID

USERID.png -> imageFlair.php?userid=USERID

您应该能够根据自己的需要进行调整,但您可能会遇到一些问题:

    如果您想在 URL 上使用“名称”而不是 ID,则需要更改 PHP 以接受名称。 如果您还想在 Page 中包含更多参数,您可能会遇到 /Page 和 /ModuleType 冲突的问题,除非您可以组合一个正则表达式来确定哪个是哪个。

进入你想要的 URL 列表,这应该可以,虽然我不会声称这是最好的或唯一的方法:-)

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^(.*)/(.*)/(.*)$ index.php?m=$1&categoryID=$2&productID=$3 [L]
RewriteRule ^(.*)/(.*)$ index.php?m=$1&categoryID=$2 [L]
RewriteRule ^(.*)$ index.php?Page=$1 [L]
</IfModule>

按照建议,您可能想用 [^/]+ 替换 .*,但我这样做时遇到了不匹配的问题,并且没有时间进行故障排除,所以 YMMV :-)

【讨论】:

请将.* 替换为[^/]+ 并用$ 标记URL 路径的结尾。 嗨史蒂夫,谢谢你的例子!总是觉得学习起来更容易……重写规则末尾的 L 参数是干什么用的? 它只是告诉 Apache 在匹配规则后停止处理该请求。 我把这条规则放进去了,但是我所有的 javascripts 都出现了错误!把它拿出来,它们运行良好。 使用[^/]而不是.更加明确和高效,因为它避免了回溯。【参考方案3】:

从您的帖子中不太清楚变量是什么。但是假设ModuleTypeid (x2) 和Page 都是变量,那么以下带有反向引用的规则应该在.htaccess 文件中起作用。

RewriteEngine On
RewriteRule ^([^/]+)/([^/]+)$ /index.php?m=$1&categoryID=$2 [L]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)$ /index.php?m=$1&categoryID=$2&productID=$3 [L]
RewriteRule ^([^/]+)$ /index.php?page=PageType [L]
RewriteRule ^([^/]+)/detail$ /index.php?page=PageType&detail=yes [L]

正如您所写的那样,最后一个并没有真正的意义。因此,您可以在末尾添加/detail

这些应该直接滑过现有应用程序的顶部,而无需对应用程序进行任何修改。因为他们没有使用[R] 重定向,所以它对您的用户是透明的。

【讨论】:

嗨,丹,对最后一个道歉,我从没想过必须区分这两个!这将是一个理想的解决方案。我会试试看的。 您好,我在 .htaccess 文件中输入了您的规则,但它们似乎没有执行任何操作?我需要重新启动任何东西吗?抱歉,我在 PHP 方面有点新手。 我已对其进行了更新,使其适合直接粘贴到 .htaccess 文件中。 我认为您在每条规则的开头缺少反斜杠,我将其包含在内并且错误停止发生。但是,这些规则似乎没有生效。

以上是关于如何使用 mod_rewrite 显示 SEO 友好的 URL?的主要内容,如果未能解决你的问题,请参考以下文章

Mod_rewrite 结合 SEO 友好的 url 和 CDN

在灯上使用 mod_rewrite 制作 seo/canonical url

使用 Mod_Rewrite 的临时维护页面对我的 Google 信誉和/或 SEO 有害吗? [关闭]

WordPress博客怎么做SEO优化

如何通过php查询使URL友好SEO [重复]

.htaccess 新手问题使用 mod_rewrite