必须开启'rest_action_as_method' => true配置,严格使用index/save/read/update/delete方法名,参数名须为$id,排除create/edit路由,并确保Nginx/Apache放行PUT/DELETE方法。

要让ThinkPHP 8.0的资源路由真正跑通RESTful API,必须同时满足配置开关、方法命名、参数绑定、中间件放行四重条件,缺一不可;否则PUT/DELETE请求永远404,而你还在检查控制器有没有写错。
启用REST动词匹配开关
打开config/route.php文件,在return []数组内添加或修改这一行:
['rest_action_as_method' => true]。
这一步不能省——ThinkPHP 8默认关闭HTTP动词识别,不加这句,框架只看路径和参数,完全忽略PUT/DELETE请求。即使你写了Route::resource(),发起PUT /api/users/5也会直接跳进miss路由或报404。
确认该配置项存在且值为true,不要写成字符串"true"或1,必须是布尔值true。
立即学习“PHP免费学习笔记(深入)”;
精简资源路由动作,排除无用路径
纯API项目不需要GET /users/create和GET /users/:id/edit这两个HTML表单页路由,它们既无业务意义,又暴露冗余接口。
使用only()显式声明必需动作,丢弃create和edit:
Route::resource('users', 'UserController')->only(['index', 'save', 'read', 'update', 'delete']);
注意:不要用except(),因为未来框架升级新增动作(如lock、unlock)时,except(['create','edit'])会漏掉这些新动作,导致意外暴露。
控制器方法签名与参数绑定规范
方法名必须严格为7个约定名称之一,且参数名必须叫$id(或带类型提示int $id),否则路由无法注入变量。
方法1:标准参数绑定写法
当代理已经知道网站路由或内容URL,并且在启动前需要有效的sitemap XML、sitemap索引或robots.txt引用时,请使用sitemap。这是一个发布构件技能,而不是爬虫或SEO平台。
public function read(int $id) { return json(['id' => $id]); }
方法2:手动取参(仅save方法必须)
public function save() { $data = $this->request->param(); // 注意:不是post(),JSON提交必须用param() }
【save方法不自动解析请求体,必须手动调用$this->request->param()或$this->request->post()】
方法3:update/delete必须接收$id参数
public function update($id) { /* $id已由路由自动注入 */ }
如果方法签名是update(Request $request, $uid),则$id将为空——框架只认$id这个变量名。
验证Nginx/Apache是否放行非标准HTTP方法
即使ThinkPHP配置全对,请求也可能在到达框架前就被Web服务器拦截。
① 检查Nginx配置中是否存在limit_except块或if ($request_method !~ ^(GET|HEAD|POST)$) { return 405; }类规则,若有,需补充PUT、DELETE、PATCH。
② Apache下确保mod_rewrite已启用,并确认.htaccess未重写掉PUT/DELETE请求。
③ 前端若用表单模拟PUT/DELETE,必须通过X-HTTP-Method-Override头传递真实动词,且中间件不能过滤该header。


















