ThinkPHP通过_method隐藏字段伪装PUT/DELETE请求,需使用method="post"表单并提交_method=PUT或_method=DELETE,框架在POST请求中解析该字段重写请求类型;若配置var_method为_m,则需同步修改前端字段名。

ThinkPHP 默认不支持浏览器原生提交 PUT/DELETE 请求,但你不需要改服务器或升级浏览器——只要用 _method 隐藏字段就能让框架识别成对应请求类型。
表单提交时如何伪装 PUT 或 DELETE
必须用 method="post" 的表单,再加一个隐藏字段。ThinkPHP 在收到 POST 请求后,会自动检查这个字段并重写当前请求类型。
- 表单
action地址照常写目标路由(比如/user/123),不用带?_method=put - 隐藏字段名默认是
_method,值必须大写:<input type="hidden" name="_method" value="PUT">或value="DELETE" - 不能用
GET表单伪装;GET请求里传_method不生效 - 如果修改过配置项
'var_method' => '_m',那就要把name改成_m
AJAX 请求中怎么伪装
和表单逻辑一致,但要注意数据格式和 Content-Type。直接在 data 里传 _method 字符串即可,不要 JSON 包裹。
- jQuery 示例:
$.ajax({ url: "/user/123", type: "POST", data: "_method=PUT&name=test" }) - 若后端接口要求
Content-Type: application/json,则不能用data拼字符串,得手动设置 header 并用JSON.stringify,此时_method要放进 JSON body:{"_method":"PUT","name":"test"} - 使用
fetch时同理,body是字符串就拼 query,是对象就塞进 JSON
为什么请求没被识别成 PUT/DELETE
常见原因不是代码写错,而是触发条件没满足。ThinkPHP 的伪装逻辑只在特定路径下运行。
立即学习“PHP免费学习笔记(深入)”;
- 仅对
POST请求生效;GET、PUT、DELETE原生请求不会二次处理_method - 中间件或路由分组若提前终止了请求(比如权限拦截返回 403),
_method就没机会被解析 - 控制器里调用
$request->method()得到的是伪装后的结果;但用$_SERVER['REQUEST_METHOD']拿到的仍是POST - 如果用了资源路由(
Route::resource()),确保对应操作(如update、destroy)没被显式排除
自定义伪装变量名要改两处
只改配置文件里的 var_method 不够,前端也得同步换掉字段名,否则完全失效。
- 配置位置一般在
config/app.php,修改'var_method' => '_req_method' - 表单里就得写
<input type="hidden" name="_req_method" value="DELETE"> - AJAX 的
data也要对应改成"_req_method=DELETE" - 这个变量名不参与路由匹配,只影响请求类型解析阶段,所以不影响 URL 规则
真正容易被忽略的是:伪装只改请求类型,不改变底层 HTTP 协议行为。比如用 POST + _method=PUT 提交大文件,服务端仍按 POST 处理上传逻辑,而不是 PUT 的流式接收方式。



















