我有一个用PHP编写的网站,为每个项目(类别和搜索页面)创建“漂亮”的网址,像这样,
mysite.com/category/slug-for-item-one/1
mysite.com/category/slug-for-item-two/2
/ category /和/ slug /取决于项目的数字ID
我有mod_rewrite服务来自网址的实际内容,如下所示:
mysite.com/view-item.php?id=1
mysite.com/view-item.php?id=2
仅使用项目ID检索每个项目的内容。
这是我的htaccess:
RewriteEngine on
RewriteRule ^([^/\.]+)/?$ view-item.php?id=$1 [L]
RewriteRule ^([^/\.]+)/([^/\.]+)/?$ view-item.php?pid=$2 [L]
RewriteRule ^([^/\.]+)/([^/\.]+)/([^/\.]+)/?$ view-item.php?id=$3 [L]
到目前为止,每件事都可以,但如果有人登上网址,
mysite.com/1
mysite.com/catey/slug-for-item-one/1
或
mysite.com/category/slug-item-one/1
内容仍然提供,但我如何自动重置或重定向到网址的规范版本,以便:
mysite.com/category/slug-for-item-one/1
我搜索了SO并广泛搜索答案,但没有运气。我只使用mod_rewrite进行简单的重定向,例如来自没有www的重定向。与www。而我的理解是暂时的,因此我很难理解如何继续进行。
有人能指出我正确的方向吗?
谢谢大家的帮助。非常感激。我正在努力实现Jon Lin的答案,因为我更熟悉使用php / mysql数据库,并了解它应该如何以及为什么应该工作。我的目标是在星期五之前完成,并在完成后更新此页面。非常感谢,卡尔。
*更新* 我已经实现了Jon Lin的答案,现在我的'漂亮'网址,当错误输入时,现在被重定向到正确或'规范'网址,就像在SO上一样。谢谢Jon和所有贡献的人!
答案 0 :(得分:2)
我认为你需要两套重写规则才能实现这一目标。
第一组规则将用于向客户端发送301重定向,以确保它们引用规范网址:
RewriteRule ^/1 /category/slug-for-item-one/1 [R=301,L]
然后使用passthroughs [PT]来提供内容的第二组规则:
RewriteRule ^([^/\.]+)/([^/\.]+)/([^/\.]+)/?$ view-item.php?id=$3 [PT,L]
或者那些东西......
答案 1 :(得分:1)
简单的馅饼:
RewriteCond %{REQUEST_URI} ^([^/\.]+)/([^/\.]+)/([^/\.]+)/$
RewriteCond %1 !category
RewriteRule ^([^/\.]+)/([^/\.]+)/([^/\.]+)/$ $1/category/$3/
这意味着:如果请求看起来像category/slug-for-item-two/2
和,则第一个匹配项不是 category
(不管它是什么),那么强制重定向到category/slug-for-item-two/2
请告诉我它是否有效
更新(发表评论后):
以下是应该起作用的:
创建2个地图文件(请参阅mod_rewrite.html#rewritemap了解如何操作)。
创建一个mapfile,您可以在其中放置所需的所有类别:
RewriteMap mapcategories \
dbm:/web/htdocs/yoursite/rewriterules/categories.map
在mapfile中创建简单的条目,如:
shirts 1
hats 2
condoms 3
vegetables 4
mother-in-laws 5
...
现在用另一个文件做另一个文件:
RewriteMap mapcategoriesreverse \
dbm:/web/htdocs/yoursite/rewriterules/categoriesreverse.map
在mapfile中创建简单的条目,如:
1 shirts
2 hats
3 condoms
4 vegetables
5 mother-in-laws
...
然后在这里你去寻找困难的部分:
RewriteCond %{REQUEST_URI} ^([^/\.]+)/([^/\.]+)/([^/\.]+)/$
# The following rule will try to search into the categories map file
# and if not found, assign CATEGORY to "notfound"
RewriteRule ^([^/\.]+)/([^/\.]+)/([^/\.]+)/$ \
- [QSA,E=CATEGORY:${mapcategories:%1|notfound}]
# if the CATEGORY is not empty and is not found:
RewriteCond %{ENV:CATEGORY} notfound
# do a reverse map to get the *real* category:
RewriteRule ^([^/\.]+)/([^/\.]+)/([^/\.]+)/$ \
- [QSA,E=CATEGORYREVERSE:${mapcategoriesreverse:%1|notfound}]
# if the CATEGORYREVERSE is not empty and is not found:
RewriteCond %{ENV:CATEGORYREVERSE} notfound
# this should never happen => 404:
RewriteRule . - [R=404,L]
# If reach here = if the CATEGORYREVERSE is not empty
# this means it has properly been found:
RewriteCond %{ENV:CATEGORYREVERSE} !^$
# Inject the right category:
RewriteRule ^([^/\.]+)/([^/\.]+)/([^/\.]+)/$ \
%{ENV:CATEGORYREVERSE}/$2/$3/ [QSA]
这样一切都是动态的,但它(更长)和(更多)更复杂。
奥利弗
答案 2 :(得分:0)
这可能是您想要在view-item.php
中实现的,而不是尝试使用mod_rewrite。当您在内容中内部生成链接时,可以使用ID来查找类别和slugs。这将是你通常如何生成一个漂亮的SEO友好链接。
首先需要将类别和slug传递给请求。有点像:
RewriteEngine on
RewriteRule ^([^/\.]+)/?$ view-item.php?id=$1 [L]
RewriteRule ^([^/\.]+)/([^/\.]+)/?$ view-item.php?pid=$2&cat=$1 [L]
RewriteRule ^([^/\.]+)/([^/\.]+)/([^/\.]+)/?$ view-item.php?id=$3&cat=$1&slug=$2 [L]
在view-item.php的顶部,只需检查cat
和slug
参数是否存在,将它们与实际类别进行比较,并在查找{{1 }}。如果其中一个不匹配(或丢失,如果需要),则使用id
函数将浏览器重定向到具有正确类别和slug的正确链接:
header()
重定向后,该过程会自行重复,但这一次,view-item.php会看到正确的类别和slug,因此页面可以正常显示。