CodeIgniter 4表单验证重定向失效问题排查求助
问题排查:CodeIgniter 4.3.3博客表单验证错误信息不显示
问题描述
使用CodeIgniter 4.3.3开发具备CRUD功能的博客网站,文章发布表单原本可正常插入数据库,但添加表单验证后仅能完成重定向,错误提示无法显示。相关代码如下:
路由配置
$routes->get('/', 'Pages::index'); $routes->get('/blogs', 'Blogs::index'); $routes->get('/blogs/create', 'Blogs::create'); $routes->post('/blogs/post', 'Blogs::post'); $routes->get('/blogs/(:segment)', 'Blogs::detail/$1');
控制器代码
// method create (here is form) public function create() { session(); $data = [ 'title' => 'Post Blog', 'validation' => \Config\Services::validation() ]; return view('blogs/create', $data); } // method post for insert to db public function post() { // validasi input if (!$this->validate([ 'judul' => 'required|is_unique[blogs.judul]', 'konten' => 'required', ])) { $validation = \Config\Services::validation(); // this line is my problem, validation didnt works. (only redirect works) return redirect()->to('blogs/create')->withInput()->with('validation', $validation); } $slug = url_title($this->request->getVar('judul'), '-', true); $this->blogsModel->save([ 'judul' => $this->request->getVar('judul'), 'konten' => $this->request->getVar('konten'), 'slug' => $slug, 'gambar' => 'post.png', ]); session()->setFlashdata('post', 'Artikel berhasil diposting.'); return redirect()->to('blogs'); }
错误提示视图代码
<?= $validation->listErrors(); ?> <form action="<?= site_url('blogs/post') ?>" method="post"> <?= csrf_field(); ?> ... <div class="invalid-feedback"> <?= $validation->getError('judul'); ?> </div>
问题根源
- 验证实例传递方式错误:重定向时用
with('validation', $validation)传递对象,但CodeIgniter 4中重定向是全新请求,直接传递对象会丢失错误状态,验证错误需通过session闪存存储。 - create方法未读取闪存数据:
create()中每次新建Validation实例,没有从session中获取重定向带来的验证错误信息。
修复方案
1. 修正控制器post()方法的重定向逻辑
无需手动传递validation对象,redirect()->withInput()会自动将验证错误存入session闪存,框架会自动处理:
public function post() { // validasi input if (!$this->validate([ 'judul' => 'required|is_unique[blogs.judul]', 'konten' => 'required', ])) { // 仅需调用withInput(),框架自动保存验证错误到session return redirect()->to('blogs/create')->withInput(); } // 其余代码保持不变 $slug = url_title($this->request->getVar('judul'), '-', true); $this->blogsModel->save([ 'judul' => $this->request->getVar('judul'), 'konten' => $this->request->getVar('konten'), 'slug' => $slug, 'gambar' => 'post.png', ]); session()->setFlashdata('post', 'Artikel berhasil diposting.'); return redirect()->to('blogs'); }
2. 修正控制器create()方法获取验证实例的逻辑
从session闪存中读取验证错误,不存在则新建实例:
public function create() { session(); $data = [ 'title' => 'Post Blog', // 优先从session闪存获取验证实例,否则新建 'validation' => session()->getFlashdata('validation') ?? \Config\Services::validation() ]; return view('blogs/create', $data); }
视图代码保持原有逻辑(可添加判断避免报错)
<?php if ($validation->hasErrors()): ?> <?= $validation->listErrors(); ?> <?php endif; ?> <form action="<?= site_url('blogs/post') ?>" method="post"> <?= csrf_field(); ?> <!-- 表单字段 --> <div class="invalid-feedback"> <?= $validation->getError('judul'); ?> </div> <!-- 提交按钮等 --> </form>
更简洁的替代实现(CI4推荐写法)
无需在控制器传递validation对象,直接在视图中调用\Config\Services::validation(),框架会自动从session读取闪存的错误信息:
简化后的控制器create()方法
public function create() { session(); $data = [ 'title' => 'Post Blog' ]; return view('blogs/create', $data); }
简化后的视图代码
<?= \Config\Services::validation()->listErrors(); ?> <form action="<?= site_url('blogs/post') ?>" method="post"> <?= csrf_field(); ?> <div class="form-group"> <label for="judul">Judul</label> <!-- 使用old()填充上次输入内容,hasError()判断是否添加错误样式 --> <input type="text" name="judul" id="judul" value="<?= old('judul') ?>" class="form-control <?= \Config\Services::validation()->hasError('judul') ? 'is-invalid' : '' ?>"> <div class="invalid-feedback"> <?= \Config\Services::validation()->getError('judul'); ?> </div> </div> <!-- 其他字段同理 --> <button type="submit" class="btn btn-primary">发布文章</button> </form>
这种写法更符合CodeIgniter 4的设计规范,无需手动管理验证实例的传递,减少冗余代码。
内容的提问来源于stack exchange,提问作者Ari Budiman
相关产品推荐
相关产品推荐

