应先用parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)提取路径,再trim去首尾斜杠,最后explode分割;需urldecode处理编码字符,且不可依赖$_GET获取REST路径参数。

PHP如何从$_SERVER['REQUEST_URI']提取RESTful路径段
直接用 explode('/', $_SERVER['REQUEST_URI']) 拿路径段最常见,但容易漏掉开头空字符串、忽略查询参数、混淆URL编码字符。
- 先用
parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)提取纯路径,避免?id=123干扰 - 再用
trim($path, '/')去掉首尾斜杠,防止开头出现空数组元素 - 最后
explode('/', $trimmed_path),得到干净的段数组,比如/api/v1/users/123→['api', 'v1', 'users', '123'] - 注意:如果路径含中文或特殊符号(如
%E4%BD%A0%E5%A5%BD),需额外调用urldecode(),否则段内容是编码后的字节串
为什么不能直接用$_GET接收RESTful参数
$_GET 只捕获查询字符串里的键值对,而 RESTful 路径参数(如 /posts/42/comments/7 中的 42 和 7)根本不会进 $_GET —— 它们属于路径结构本身,不是查询参数。
- Apache 的
.htaccess或 Nginx 的try_files必须把所有非静态资源请求重写到入口文件(如index.php),否则 PHP 根本收不到完整 URI - 没做重写时,访问
/api/users/5会直接 404,$_SERVER['REQUEST_URI']都拿不到 - 即使重写了,也要确认 Web 服务器未自动解码 URI:某些 Nginx 配置会提前 decode,导致 PHP 收到的是原始字符而非 % 编码,影响后续判断
处理带可选段或版本前缀的REST路径
真实 API 常有类似 /v2/products/:id/reviews 或 /legacy/orders/:order_id 这种嵌套结构,硬拆固定索引(如 $parts[2])极易出错。
- 别依赖数组下标取值,改用循环 + 模式匹配:检查
$parts[$i] === 'users'后,下一个才是 ID;或用array_search('products', $parts)定位资源名位置 - 版本号(
v1,v2)建议统一前置并单独剥离,避免每个路由逻辑都重复判断:if (in_array($parts[0], ['v1', 'v2'])) { $version = array_shift($parts); } - 空段(如
//users//5)可能因拼接错误产生,array_filter($parts)可清理,但要注意它也会过滤掉合法的0值(如/items/0),此时应显式用array_values(array_filter($parts, 'strlen'))
$_SERVER['PATH_INFO']比REQUEST_URI更可靠吗
在 CGI/FastCGI 环境下,$_SERVER['PATH_INFO'] 理论上只包含重写后路径中「脚本名之后」的部分,语义更清晰。但它受 SAPI 类型和服务器配置强影响,实际兼容性反而更差。
- Apache + mod_php 通常不设
PATH_INFO,除非显式启用AcceptPathInfo On - PHP-FPM 下默认关闭,需在
php-fpm.conf或 pool 配置里加security.limit_extensions = .php .html并确保fastcgi_split_path_info正确分隔 - 很多共享主机禁用
PATH_INFO,且 Windows IIS 表现不一致;相比之下REQUEST_URI+parse_url组合在所有环境都稳定 - 若坚持用
PATH_INFO,务必先isset($_SERVER['PATH_INFO']) && $_SERVER['PATH_INFO'] !== ''判断,不能直接explode
真正麻烦的不是怎么切字符串,而是路径里混着编码、重写规则没生效、或者前端发了带 hash 的 URL(#section)却指望后端拿到——hash 根本不会发给服务器,连 REQUEST_URI 里都没有。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











