CodeIgniter无内置“智能表单填充”,所谓智能是组合set_value()、数据库读取、时间戳逻辑和错误处理的结果;编辑时需显式传入原始数据作fallback,验证失败应直接渲染而非重定向。

CodeIgniter 本身没有“智能表单填充”这个内置概念——它不自动猜字段、不关联模型属性、也不做客户端预测。所谓“智能”,实际是开发者把几个基础机制(set_value()、数据库读取、时间戳逻辑、错误上下文)组合使用后产生的效果。关键不在框架有多聪明,而在你是否清楚每个环节的触发条件和失效边界。
为什么 set_value() 在编辑表单里总为空
因为 set_value() 只读 $_POST,不查数据库、不读 session、不回溯上一次成功提交的数据。编辑场景下,用户首次访问是 GET 请求,没 POST 数据,set_value('title') 必然返回空字符串。
- 正确做法:在控制器中查出原始数据,显式传给视图,比如
$data['row'] = $this->article_model->get_by_id($id); - 视图中用
set_value('title', $row->title)—— 第二个参数才是编辑时的 fallback 值 - 如果同时要支持“验证失败后保留用户改过的值”,
set_value()会自动优先取 POST 值,无需额外判断 - 别把
set_value('status')直接塞进form_dropdown();下拉菜单要用set_select('status', $row->status)配合,否则选中态永远不对
新增/编辑共用一个表单时,时间字段怎么填才不混乱
新增时 created_at 应由 PHP 或 MySQL 填;编辑时它不该变,但 updated_at 必须更新。靠 set_value() 填这两个字段是错的——用户根本不会 POST 它们。
- 新增表单:
form_input('created_at', date('Y-m-d H:i:s')),或直接省略该字段,让数据库用CURRENT_TIMESTAMP - 编辑表单:
form_input('created_at', $row->created_at),且确保该字段在 HTML 中加readonly或隐藏域,防止被意外修改 -
updated_at字段不要出现在表单里,改在模型的update()方法中手动赋值:$data['updated_at'] = date('Y-m-d H:i:s'); - 若数据库字段类型是
TIMESTAMP且设了ON UPDATE CURRENT_TIMESTAMP,PHP 层可完全不传updated_at,但要注意 MySQL 时区和 PHP 时区是否一致(常见差 8 小时)
验证失败后重定向,表单还怎么回填
一旦调用 redirect(),原始 POST 数据就丢了,set_value() 失效是必然结果。这不是 bug,是 HTTP 协议限制。
- 唯一合规解法:验证失败时不重定向,直接
$this->load->view()渲染当前页面 - 若必须重定向(比如防止重复提交),就得手动把 POST 数据存成闪存:
$this->session->set_flashdata('post', $this->input->post()); - 然后在目标控制器方法里取出:
$post_data = $this->session->flashdata('post');,再传给视图 - 注意:
flashdata只能取一次,第二次访问就为空;且不能存大数组或对象,只适合简单字段 - 这种方案绕过了
set_value(),你需要自己写逻辑:value="<?php echo isset($post_data['email']) ? $post_data['email'] : ''; ?>"
最易被忽略的一点:所有“智能”都依赖请求生命周期的精确控制。验证失败却重定向、编辑时硬套 set_value() 不带默认值、时间字段混进表单又不做防护——这些不是配置问题,是流程断点。填得准不准,不看函数多高级,而看你有没有在控制器里守住那条“POST → 验证 → 成功跳转 / 失败渲染”的分界线。


















