$request->method()返回大写原始http方法(如"get"),严格对应$_server['request_method'];而ismethod()等语义方法会识别_method隐藏字段,适合常规路由逻辑。

用 $request->method() 获取原始请求方法
在控制器或中间件里,直接调用 Laravel 的 Request 实例的 method() 方法,它返回大写的字符串,比如 "GET"、"POST"、"PUT"。这个值来自底层 Swoole 或 PHP-FPM 的原始 $_SERVER['REQUEST_METHOD'],不经过任何重写或模拟处理。
常见误判点:别用 $request->isMethod('post') 做条件分支——它内部会把 POST 请求 + _method 隐藏字段(如表单提交)也识别为 POST,而实际 HTTP 方法可能是 POST,但语义上你可能想区分“真 POST”和“伪装 PUT/DELETE”。
实操建议:
- 需要严格判断协议层方法(例如做 API 网关、日志审计、CORS 预检响应),用
$request->method() === 'OPTIONS' - 要兼容表单伪造方法(
_method字段),改用$request->isMethod('put')或$request->isPut() -
$request->method()返回值恒为大写,比较时别写小写字符串
用 $request->isGet() 这类快捷方法判断常用方法
Laravel 提供了 isGet()、isPost()、isPut()、isDelete()、isPatch()、isHead()、isOptions() 七个布尔方法,它们会同时检查原始方法和 _method 参数(如果存在且合法),更适合常规路由逻辑。
注意:这些方法对大小写不敏感,但内部仍以大写比对;且只支持上述七种方法名,传入 isTrace() 会报 BadMethodCallException。
典型场景:
- 表单提交带
<input name="_method" value="PUT">时,$request->isPut()返回true,但$request->method()仍是"POST" - API 接口需拒绝非
GET请求时,用! $request->isGet()更安全,因为它涵盖真实 GET 和伪造 GET(虽然极少伪造 GET) - 不要在中间件里混用
isPost()和method() === 'POST'做同一判断,行为不一致容易漏掉伪造请求
在路由定义中用 Route::match() 或数组方式限制方法
比起在控制器里判断,更推荐把方法约束提前到路由层。Laravel 路由注册本身就能过滤非法方法,避免请求进到控制器再抛异常。
两种写法效果等价,但语义不同:
-
Route::match(['GET', 'HEAD'], '/users', [UserController::class, 'index'])—— 显式列出允许的方法,适合多方法共用一个处理逻辑 -
Route::get('/users', [UserController::class, 'index'])->methods(['GET', 'HEAD'])—— 默认已包含HEAD,methods()是覆盖而非追加
关键细节:
- 没显式声明
HEAD时,Route::get()自动响应HEAD请求(返回空体 + 正确 header),但Route::match(['GET'])不会自动支持HEAD - 使用
Route::any()等同于开放所有方法,生产环境慎用,尤其配合CSRF验证时可能绕过防护
调试时快速确认当前方法:dd($request->method(), $request->isMethod('delete'))
开发中遇到方法判断失效,最直接的方式是在控制器开头加一行调试代码,同时输出原始方法和语义方法判断结果。这能立刻暴露是伪造机制生效了,还是前端发错了方法。
常见错误现象:
- Vue 或 Axios 发送
DELETE请求,后端却收到POST—— 很可能是前端没设method: 'DELETE',或用了axios.post()却手动塞DELETE到 body - 表单提交后
$request->isDelete()为false—— 检查是否漏了@csrf和@method('DELETE'),后者会生成隐藏字段,缺一不可 - API 测试工具(如 Postman)选了
PUT,但$request->method()输出"POST"—— 查看请求头是否有X-HTTP-Method-Override: PUT,Laravel 默认不启用该头解析,需手动配置中间件
真正容易被忽略的是:Laravel 的方法判断依赖于请求生命周期早期的解析顺序,一旦在中间件里修改了 $request 实例(比如用 replace() 替换了参数),isMethod() 可能仍按原始状态判断,而 method() 不受影响。这种差异只在深度定制请求处理流程时才会浮现。











