4

我有一个之前的问题得到了很好的回答,但需要修改,我无法回答,所以创建了一个新问题。

我需要一个 mod_rewrite 进行以下操作:

www.example.com?page=var1&cat=var2&subcat=var3&subsubcat=var4

进入这个:

www.example.com/var1/var2/var3/var4/

但这也涵盖了 var2、var3 和 var4 的可选使用,因此如果这些变量为空,它仍然可以工作。

这个问题得到了很好的回答,但它需要修改才能使用 var2、var3 和 var4 的不同字段选项。

我的代码是:

RewriteEngine on
Options +FollowSymlinks -MultiViews

RewriteCond  %{QUERY_STRING} !^page= [NC]
RewriteRule ^([^/]+)/?$ /?page=$1 [L]

RewriteCond  %{QUERY_STRING} !^page= [NC]
RewriteRule ^([^/]+)/([^/]*)/?$ /?page=$1&cat=$2 [L]

RewriteCond  %{QUERY_STRING} !^page= [NC]
RewriteRule ^([^/]+)/([^/]*)/([^/]*)/?$ /?page=$1&cat=$2&subcat=$3 [L]

RewriteCond  %{QUERY_STRING} !^page= [NC]
RewriteRule ^([^/]+)/([^/]*)/([^/]*)/([^/]*)/?$ /?page=$1&cat=$2&subcat=$3&subsubcat=$4 [L]

这可行,但我需要它能够做出 if-or-else 来选择哪个字段用于哪个变量并区分差异。

例如,如果我们正常有以下两个字符串,就很容易区分哪个字段对应哪个变量:

www.example.com?page=var1&cat=var2&subcat=var3&subsubcat=var4

www.example.com?othervar1=var1&othervar2=var2&othervar3=var3&othervar4=var4

但是对于这个字符串,它需要能够区分变量用于哪个字段:

www.example.com/var1/var2/var3/var4/

我需要 mod_rewrite 来选择正在使用的。

除此之外,当我实际转到确实存在的文件夹时,它确实可以正常工作。例如,如果我转到一个名为“test”的文件夹,它是一个实际文件夹:

www.example.com/test/

它使用它作为“页面”字段的变量。如果我在没有结束正斜杠的情况下使用以下内容:

www.example.com/test 

它将以下内容输出到 URL 中:

www.example.com/test/?page=test

我需要它来处理正常存在的文件夹。

请有人能告诉我这是怎么做到的吗?我将不胜感激解决此问题的任何帮助。

另外,有人能告诉我一开始的“-MultiViews”位是什么意思吗,因为我以前没有遇到过这个?

谢谢你。

4

1 回答 1

2

首先确定MultiViews选项:根据 Apache 手册:

多视图

Content negotiated "MultiViews" are allowed using mod_negotiation.

简而言之,如果您有一个名为的文件foo.html并且如果浏览器请求http://example.com/foo,那么 Apache 会自动查找并附加扩展名并提供foo.html给浏览器,而不是抛出404。这种行为会导致许多重写规则失败,因此我在回答您之前的问题时一开始就禁用了它。

现在要排除真实目录被重写规则处理,我们需要一个像这样的附加条件:RewriteCond %{REQUEST_FILENAME} !-d

支持多种漂亮的 URL 方案:

您在这里几乎没有选择。请告诉我你想要哪一个,我会为此提供规则。

选项 1:在您的 URL 中同时包含var name和,如下所示:var value

www.example.com/page/var1/cat/var2/subcat/var3/subsubcat/var4或者
www.example.com/othervar1/var1/othervar2/var2/othervar3/var3/othervar4/var4

这为您提供了最大的灵活性,并且如果您愿意走这条路线,那么在重写规则中很容易处理。对于此选项,只需编写一次重写规则,只要变量数不变,您就可以应对未来的变化

选项 2:为每个方案设置不同的开始。例如:

www.example.com/handler1/var1/var2/var3/var4或者
www.example.com/handler2/var1/var2/var3/var4

这个是为您提供更短的 URL,但不像以前的选项那样提供灵活性。但是这个在 Rewrite 规则中也很容易处理。但是对于此选项,需要为每个组合编写重写规则

所以我会推荐选项 1,如果你也喜欢这个选项,我很乐意为你准备一个 .htaccess。

选项 2 的 .htaccess 文件

Options +FollowSymlinks -MultiViews
RewriteEngine on

# 404 handler
ErrorDocument 404 /notFound.php

RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^handler1/([^/]+)/?$ /?page=$1 [NC,QSA,L]
RewriteRule ^handler1/([^/]+)/([^/]+)/?$ /?page=$1&cat=$2 [NC,QSA,L]
RewriteRule ^handler1/([^/]+)/([^/]*)/([^/]*)/?$ /?page=$1&cat=$2&subcat=$3 [NC,QSA,L]
RewriteRule ^handler1/([^/]+)/([^/]*)/([^/]*)/([^/]*)/?$ /?page=$1&cat=$2&subcat=$3subsubcat=$4 [NC,QSA,L]

RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^handler2/([^/]+)/?$ /?othervar1=$1 [NC,QSA,L]
RewriteRule ^handler2/([^/]+)/([^/]+)/?$ /?othervar1=$1&othervar2=$2 [NC,QSA,L]
RewriteRule ^handler2/([^/]+)/([^/]*)/([^/]*)/?$ /?othervar1=$1&othervar2=$2&othervar3=$3 [NC,QSA,L]
RewriteRule ^handler2/([^/]+)/([^/]*)/([^/]*)/([^/]*)/?$ /?othervar1=$1&othervar2=$2&othervar3=$3othervar4=$4 [NC,QSA,L]


选项 1 的 .htaccess 文件

Options +FollowSymlinks -MultiViews
RewriteEngine on

# 404 handler
ErrorDocument 404 /notFound.php

RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/([^/]+)(/.*)?$ $3?$1=$2 [N,QSA,DPI]
RewriteRule ^(/[^/]+|[^/]+/|/?)$ /index.php [L,QSA,DPI]

使用这些规则,一个 URLhttp://localhost/n1/v1/n2/v2/n3/v3/n4/v4将被内部重定向,以将由http://localhost/?n4=v4&n3=v3&n2=v2&n1=v1分隔的每一对 URL 段/视为name-valueQUERY_STRING 的一对。请记住,如果 URI 没有偶数个段,例如:http://localhost/n1/v1/n2/那么它将被重定向到http://localhost/?n1=v1,丢弃额外的 n2。

于 2011-04-25T12:26:11.600 回答