原生PHP写RESTful API可行,关键在四支点:HTTP方法识别、路径解析、JSON请求体读取(需file_get_contents('php://input')而非$_POST)、显式设状态码与Content-Type头。

直接用 PHP 原生写 RESTful API 是完全可行的,关键不是“能不能”,而是你是否踩对了四个支点:HTTP 方法识别、路径解析、请求体读取、状态码与响应头显式控制。框架能省事,但一上来就依赖它,反而会掩盖这些底层逻辑出错时的真实原因。
怎么正确读取 POST/PUT 的 JSON 数据
最常卡住的地方是以为 $_POST 能接收到前端发来的 JSON —— 它不能。$_POST 只处理 application/x-www-form-urlencoded 和 multipart/form-data;而 REST 接口绝大多数用的是 application/json,必须手动读流。
- 先检查
$_SERVER['CONTENT_TYPE']是否包含application/json - 确认后调用
file_get_contents('php://input')获取原始请求体 - 再用
json_decode($raw, true)解析,别漏掉第二个参数true(返回关联数组) - 务必检查
json_last_error(),非JSON_ERROR_NONE就该返回 400 并终止
如何安全提取路径中的 ID 参数
直接用 explode('/', $uri) 拿第 4 段当 ID 是危险的。攻击者可能构造 /api/users/123%00admin=1 或带 SQL 注入片段的路径,导致后续拼接查询时崩掉。
- 用
parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)先规范提取路径 - 再用正则强匹配,例如
preg_match('@^/api/users/(\d+)$@', $path, $matches) - 只信任
$matches[1],且必须转为整型:(int)$matches[1] - 如果没匹配上,直接
http_response_code(404),别往下走
为什么必须显式设置状态码和 Content-Type
PHP 默认输出是 200 OK + text/html,但前端 fetch 或 axios 会严格校验 Content-Type。哪怕你 echo 出了合法 JSON,只要 header 没设对,.json() 就会抛 Unexpected token 错误。
立即学习“PHP免费学习笔记(深入)”;
- 所有响应前必须加
header('Content-Type: application/json; charset=utf-8') - 每种业务分支都要调用
http_response_code():201 创建、204 删除、404 未找到、405 方法不支持 -
header()前不能有任何输出,包括 BOM、空行、echo或调试var_dump - 空响应也要输出合法 JSON,比如
[]或{},而不是null或空字符串
Apache/Nginx 路由转发没配好,代码再对也 404
很多人写完 api.php,直接访问 /api/users/123 报 404,第一反应是 PHP 写错了——其实 Web 服务器根本没把路径透传进来。
- Nginx 需在 server 块里加:
try_files $uri $uri/ /api.php?$args - Apache 要确保
.htaccess生效,且内容为:RewriteRule ^(.*)$ api.php [QSA,L] - 验证是否生效:在
api.php开头加var_dump($_SERVER['REQUEST_URI']); die;,看打印出的路径是否含/users/123 - 别依赖
$_SERVER['PATH_INFO'],它在 CGI/FastCGI 下经常为空,统一用parse_url(..., PHP_URL_PATH)
真正难的不是写几行路由分发,而是每次请求进来时,都得重新审视:这个方法是不是该用 PUT 而不是 POST?这个 ID 是不是被正则兜住了?这个 404 是数据不存在,还是路径压根没被 rewrite 进来?——这些细节不盯死,API 表面跑通,实际一上线就埋雷。



















