表单提交后控制器收不到数据,大概率是路由、method或csrf配置没对齐;需检查action与method是否匹配、使用route_to()而非index.php路径、显式声明method="post"、添加csrf_field()、用$request->getpost()取值、处理后重定向而非直接渲染视图。

表单提交后控制器收不到数据,大概率是路由、method 或 CSRF 配置没对齐,而不是逻辑写错了。
检查 form 标签的 action 和 method 是否匹配路由
CI4 默认关闭了 index.php 路由前缀,所以 action 里写 index.php/welcome/login 通常会 404。你应该用 base_url('login') 或更推荐的 route_to('login')(前提是 routes.php 里已定义命名路由)。
常见错误现象:404 Not Found 或表单提交后页面刷新但控制器方法完全没执行。
- 确保
<form></form>的method="post"显式写出,不能省略 - 避免混用原生
<form></form>和form_open()—— 浏览器会直接忽略嵌套的内层表单,导致 POST 数据丢失 - 如果用
form_open('login'),对应控制器方法必须是public function login(),且路由要允许 POST
用 $this->request->getPost() 取值,别依赖 $_POST
CI4 封装了请求对象,$this->request->getPost() 会自动过滤、转义(取决于配置),比直接读 $_POST 更安全也更可靠。
使用场景:登录、注册、编辑等需要接收用户输入的操作。
- 取单个字段:
$this->request->getPost('username') - 取全部 POST 数据:
$this->request->getPost()(返回关联数组) - 带默认值的取法:
$this->request->getPost('status', FILTER_SANITIZE_STRING) ?? 'draft' - 注意:如果开启了全局 XSS 过滤(不推荐),
getPost()返回值可能被意外修改
必须手动加 csrf_field(),否则 403 Forbidden
CI4 默认启用 CSRF 保护,所有 POST 表单都必须包含隐藏的 token 字段,否则请求会被拦截并返回 403 Forbidden。
错误现象:表单点击提交后页面空白、跳转到首页、或直接报 403,但控制器方法一行都没进。
- 在视图中表单内部加:
= csrf_field() ?> - 不要手写
<input type="hidden" name="csrf_test_name" ...>—— token 值会过期,且 key 名可能随配置变化 - 如果用 AJAX 提交,需从
meta[name="csrf-token"]或响应头中提取 token 并附在请求头里 - 临时调试可关掉 CSRF(
app/Config/Security.php中设$tokenName = null),但上线前务必恢复
处理完立刻重定向,别直接渲染视图
成功保存数据后如果直接 return view('success'),用户刷新页面会重复提交 —— 这不是 bug,是 HTTP 协议特性。
正确做法是用 PRG 模式:处理完 POST,用 return redirect()->to('dashboard') 或 return redirect()->back() 触发一次 GET 请求。
- 这样浏览器地址栏变成新 URL,刷新不会重发 POST
-
set_value()和old()在重定向后的 GET 请求里自然为空,表单自动清空 - 若需传提示信息,用
session()->setFlashdata('message', '保存成功'),然后在目标视图里读取 - 别在重定向前调用
exit或die,会中断 CI4 的响应生命周期
最常被忽略的是 CSRF 字段和 PRG 重定向这两步 —— 它们不报错,但会让整个流程“静默失败”或“行为反直觉”。先确认这两点,再查逻辑。











