PHP MVC项目.htaccess自定义重写规则失效问题求助
问题背景
我有一个基于PHP MVC架构的Web应用,目录结构及.htaccess配置如下:
根目录.htaccess:
RewriteEngine on RewriteCond %{REQUEST_FILENAME} !(.*)\.(png|jpg)$ RewriteRule ^$ public/ [L] RewriteRule (.*) public/$1 [L]
该配置将所有请求转发至Public目录,基础转发功能正常。
初始Public目录.htaccess:
RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^ index.php [L]
尝试添加自定义重写规则(如RewriteRule api/([a-zA-Z\-]+) ?p=api.word.word_show&action=read_word_data&word=$1)时无法生效,服务器不存在api或definition目录。
调整后的Public目录.htaccess:
RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^ index.php RewriteRule api/([^/]*)$ index.php?p=api.word.word_show&action=read_word_data&word=$1 [L]
直接访问index.php?p=api.word.word_show&action=read_word_data&word=whatever可正常运行,但自定义重写规则仍失效。
问题根源
调整后的Public目录.htaccess规则顺序错误:通用路由(RewriteRule ^ index.php)被放在了特定api路由之前,所有非文件/目录的请求会先被转发到index.php,后续的api规则完全没有执行机会。此外,通用路由缺少[L]标志,会导致规则继续向下匹配,但即便加上,顺序问题依然会导致api规则无法触发。
修复方案
修复后的Public目录.htaccess
将特定路由放在通用路由之前,并补充必要的规则标志:
RewriteEngine On # 优先处理api开头的请求 RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^api/([^/]+)$ index.php?p=api.word.word_show&action=read_word_data&word=$1 [L,QSA] # 处理其他所有非文件/目录的请求 RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^ index.php [L]
关键说明
- 规则顺序:特定路由必须放在通用路由前面,确保匹配优先级。
- [L]标志:匹配当前规则后停止处理后续规则,避免不必要的规则冲突。
- QSA标志:保留原请求的查询参数(如
api/test?foo=bar会被转发为index.php?p=...&word=test&foo=bar),提升兼容性。 - 根目录.htaccess无需修改:基础转发功能正常,保持原有配置即可。
验证
访问http://yourdomain/api/your-word,应与直接访问http://yourdomain/index.php?p=api.word.word_show&action=read_word_data&word=your-word效果一致。
内容的提问来源于stack exchange,提问作者JMB

