request() 返回 think\Request 实例,是全局快捷入口,与 $this->request 指向同一单例但获取时机不同;中间件中 action() 为 NULL 因路由未解析;param() 按路由/POST/GET 优先级合并取值,input() 需显式指定来源且依赖配置过滤;CLI 环境下 param()/get()/post() 基本失效,应改用 $this->input 或 $_SERVER['argv']。

request() 助手函数返回的是 think\Request 实例,可直接链式调用所有 Request 方法;它不是 input() 的替代品,而是对请求对象的快捷入口。
request() 和 $this->request 有什么区别?
两者指向同一个 Request 实例(单例),但生命周期和获取时机不同:
-
request()是全局助手函数,控制器任意位置、甚至模型里都能直接调用(只要框架已初始化) -
$this->request是控制器基类注入的属性,仅在继承think\Controller的控制器中可用 - 中间件中推荐用
request(),因为$this->request可能未初始化或为空
为什么 request()->action() 在中间件里返回 NULL?
这不是函数写错了,是 TP 路由解析顺序导致的:中间件执行时,路由匹配尚未完成,action、controller 等属性还没被赋值。
可靠做法是回退到原始服务器变量:
立即学习“PHP免费学习笔记(深入)”;
- 优先读
request()->server('PATH_INFO')(伪静态下可能为空) - 再 fallback 到
request()->server('REQUEST_URI'),手动解析路径段 - 别在中间件里依赖
request()->action()或request()->controller()做分支逻辑
request()->param() 和 input() 的关键差异
它们行为接近但底层逻辑不同,混用容易踩坑:
-
request()->param('id'):按「路由变量 > POST > GET」优先级合并取值,适合统一收口参数 -
input('post.id/d'):必须显式指定来源(post.、get.等),且漏写类型修饰符(如/d)会失去类型强制转换和 XSS 过滤能力 -
request()->param('id', null, 'htmlspecialchars')支持传入过滤方法;input('id/s')的过滤由配置项default_filter驱动,不可临时覆盖 - 检测是否存在时:
request()->has('id')返回 bool;input('?id')才等价,input('id')会返回默认值或空字符串,不能用于判断
命令行环境下 request() 还能用吗?
能调用,但部分方法会失效或返回空:
-
request()->param()、request()->get()、request()->post()在 php think command 中基本返回空数组——因为没有 HTTP 上下文 -
request()->server()仍可读取 CLI 环境变量(如argv、argc),但PATH_INFO、REQUEST_URI等无意义 - 命令行逻辑应改用
$this->input(如果命令类继承think\Console\Command)或直接解析$_SERVER['argv']
真正容易被忽略的点是:request() 返回的对象本身不“感知”运行环境,它只是按当前上下文尽力返回数据;你得自己判断场景——HTTP 请求就信 param(),CLI 就别碰 get/post,中间件就绕开 action/controller。否则看似一行代码,实际在不同生命周期里行为完全不一致。



















