我想
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]
当模式匹配时你应该总是尽可能具体。