如何使用 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】:
从您的帖子中不太清楚变量是什么。但是假设ModuleType
、id
(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