You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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>

问题根源

  1. 验证实例传递方式错误:重定向时用with('validation', $validation)传递对象,但CodeIgniter 4中重定向是全新请求,直接传递对象会丢失错误状态,验证错误需通过session闪存存储。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 20:45:10