如何通过Apache .htaccess通用重写规则实现RESTful API路径到PHP接口的映射
现有规则失效原因
- 规则执行顺序错误:优先执行了补PHP后缀的逻辑,导致带路径参数的请求还没拆分就被补了后缀,后续匹配不到规则
- 正则贪婪匹配问题:
^(.+)(\/\d+)$中.+是贪婪匹配,会把entity/5里的entity/也吞进去,导致分组结果不符合预期 - 缺少规则终止标记和重写循环判断:未加
L标记控制规则执行流,也没有排除已经重写为.php后缀的请求,容易触发内部重写循环
正确实现方案
方案1:重写为pathinfo格式(api/entity/5 → api/entity.php/5,适合自行解析URI的场景)
PHP侧可以直接通过$_SERVER['PATH_INFO']获取路径后缀参数,配置如下:
RewriteEngine On # 排除已经是.php后缀的请求,避免重写循环 RewriteCond %{REQUEST_URI} \.php$ RewriteRule ^ - [L] # 匹配「路径/数字」格式的REST请求,拆分后追加.php后缀 RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^([^/]+)/(\d+)$ $1.php/$2 [NC,L] # 普通无后缀请求补全.php后缀 RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^([^\.]+)$ $1.php [NC,L]
方案2:重写为查询参数格式(api/entity/5 → api/entity.php?id=5,适合直接用$_GET取参数的场景)
如果希望直接把路径中的数字赋值给id变量,无需额外解析URI,用以下配置:
RewriteEngine On # 排除已经是.php后缀的请求,避免重写循环 RewriteCond %{REQUEST_URI} \.php$ RewriteRule ^ - [L] # 匹配「路径/数字」格式的REST请求,重写为带id参数的形式,QSA标记保留原有查询参数 RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^([^/]+)/(\d+)$ $1.php?id=$2 [NC,QSA,L] # 普通无后缀请求补全.php后缀 RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^([^\.]+)$ $1.php [NC,L]
注意事项
- 需确保Apache已开启
mod_rewrite模块,同时站点配置中AllowOverride设置为All,允许.htaccess文件生效 - 规则中
!-f和!-d判断会跳过实际存在的文件、目录,避免和静态资源、真实路径冲突 QSA标记的作用是保留原始请求带的查询参数,比如api/entity/5?status=1重写后会变成api/entity.php?id=5&status=1,不会丢失原有参数
内容的提问来源于stack exchange,提问作者Jake H
相关产品推荐
相关产品推荐

