ThinkPHP 6.1+ 废弃 input() 后应改用 think\facade\Request 或依赖注入 think\Request;Request::param() 不等同于 input(),因不自动解析 JSON、不包含 $_REQUEST 全逻辑且类型过滤需显式传参,推荐按来源用 get()/post() 并重构旧调用。

ThinkPHP 6.1+ 中 input() 等助手函数被废弃后怎么写
直接用 think\facade\Request 替代,不是加个命名空间就能跑通——关键在调用时机和参数语义差异。
常见错误现象:input('id') 直接换成 Request::param('id') 后取不到 POST 数据,或者默认值不生效。这是因为 input() 默认合并 GET/POST/REQUEST,而 Request::param() 默认只读 $_POST + $_GET(且按顺序覆盖),但不包含 $_REQUEST 的完整逻辑。
-
Request::param('id'):等价于旧版input('id')的常用场景,但注意它不会自动解析 JSON body(需手动Request::post()或启用json_input配置) -
Request::get('id')/Request::post('id'):更明确,推荐在接口中显式指定来源,避免歧义 - 如果项目依赖
input('id/s')这类类型转换,得改用Request::param('id', null, 'intval')或配合filter参数,否则类型强制失效
自定义兼容层封装 input() 时要注意的三个陷阱
有人写个 function input($key = null, $default = null, $filter = '') 来兜底,结果线上出问题:参数没过滤、JSON 解析失败、路由变量被重复解析。
- 别直接转发给
Request::param()—— 它不处理$_SERVER['PATH_INFO']或路由绑定参数,要手动合并Request::route() - JSON body 默认不自动解析,
input('data/a')在 Content-Type: application/json 下会返回 null,必须先调Request::getContent()+json_decode(),或开启配置'json_input' => true -
$filter参数若传字符串如'htmlspecialchars',新版Request不再内置支持,得自己call_user_func(),且注意回调函数必须接收且返回单个值
从 cookie() session() 迁移到 think\facade\Cookie think\facade\Session 的实际影响
表面只是换类名,但行为有隐性变化:生命周期、加密方式、跨域策略全由新门面接管,老配置可能失效。
立即学习“PHP免费学习笔记(深入)”;
-
cookie('name')→Cookie::get('name'),但旧版默认不加密,新版默认启用cookie_encrypt配置,若未配密钥会导致读不到旧 cookie -
session('user.id')→Session::get('user.id'),注意新版Session默认使用File驱动,但子目录权限不足时静默失败,日志里只报session_start(): Failed to initialize storage module - 若原项目用
session(null, 'think')切换 session name,新版必须用Session::init(['name' => 'think']),且只能在首次get()前调用,之后无效
为什么建议放弃“完全兼容旧助手函数”的思路
因为 ThinkPHP 6 的请求生命周期和容器注入机制已重构,硬套旧习惯反而放大风险:比如在中间件里调用自定义 input(),可能拿到未经过全局 filter 的原始数据;又比如在命令行模式下,Request 实例根本不存在,而旧 input() 会 fallback 到 $_ENV 或 argv,新方案必须显式判断运行环境。
真正省事的做法是:在控制器方法签名里直接依赖注入 think\Request 对象,用 IDE 能跳转、能提示、能测覆盖率,比维护一层胶水代码可靠得多。那些散落在模型、服务类里的 input() 调用,恰恰是最该借机清理的技术债。


















