同一个 php 文件的多个 mod_rewrite 参数

同一个 php 文件的多个 mod_rewrite 参数

我想

site.com/home/profile

映射到

site.com/index.php?view=home&type=profile

site.com/profile/a1b2c3

映射到

site.com/index.php?view=profile&id=a1b2c3

site.com/profile/friends

应该映射到

site.com/index.php?view=profile&type=friends

以及(这已经起作用了,只是为了语义而包括它)

site.com/profile或者 site.com/home

映射到

site.com/index.php?view=profile或者 site.com/index.php?view=home

这是我的.htaccess文件位于DOCUMENT_ROOT

RewriteEngine on
RewriteBase /

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+)/([^/]+)/?$ /index.php?view=$1&type=$2 [QSA]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^.*\.(jpg|css|js|gif|png|bmp|svg|ico)$ [NC]
RewriteRule ^([^/]+)/([^/]+)/?$ /index.php?view=$1&id=$2 [QSA]

## This part already works, but will it interfere with my above rules?
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /index.php?view=$1 [L,NC,QSA]

我做错了什么?这只对其中一个有效,但对两个都无效!

答案1

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+)/([^/]+)/?$ /index.php?view=$1&type=$2 [QSA]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^.*\.(jpg|css|js|gif|png|bmp|svg|ico)$ [NC]
RewriteRule ^([^/]+)/([^/]+)/?$ /index.php?view=$1&id=$2 [QSA]

两条规则的模式相同RewriteRule。因此,第一条规则自然会捕获所有请求。(尽管您缺少一个L标志,但处理仍在继续……)

这看起来像是/profile/...更通用的重写的一个特例?因此,您可以profile在第一个路径段中专门检查。(尽管您没有这样做,这让我认为这个问题还有更多内容?)这也需要先进行,然后再进行更通用的万能重写。例如:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(profile)/([^/]+)/?$ /index.php?view=$1&id=$2 [QSA,L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+)/([^/]+)/?$ /index.php?view=$1&type=$2 [QSA,L]

如果检查REQUEST_URI是为了优化(以避免文件系统检查),那么它就放错了地方;它应该是第一个条件。但是,您可以将其作为单独的指令(如果您的文件中没有其他指令)。例如,您现有的指令:

RewriteRule \.(jpg|css|js|gif|png|bmp|svg|ico)$ - [L]

如果请求的 URL 以任何指定的文件扩展名结尾(无论它是否实际映射到现有文件),则处理停止。

更新:

基本上,id 包含一个 MD5 哈希值,type 是一个唯一标识符,它始终是一个单词

MD5 哈希是一个 32 个字符的十六进制字符串 - 因此您可以专门检查它以避免与“类型”冲突。例如,将第一个更改RewriteRule为:

RewriteRule ^(profile)/([a-f0-9]{32})/?$ /index.php?view=$1&id=$2 [QSA,L]

当模式匹配时你应该总是尽可能具体。

相关内容