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

PostgreSQL模式下CodeIgniter is_unique验证规则失效求助

解决CodeIgniter is_unique规则在PostgreSQL Schema表中的验证问题

我碰到过完全一样的问题!CodeIgniter 3的默认is_unique规则确实没考虑PostgreSQL的schema场景,它会错误地把products.catalog.name解析成表products的列catalog.name,而不是products schema下的catalog表的name列,再加上转义符处理出错,就出现了你看到的relation "products" does not exist错误。

CodeIgniter官方推荐用以下两种方式解决,不需要修改核心文件:

方案1:使用自定义回调函数(简单直接)

这是官方最推荐的快速解决方案,你可以在控制器里写一个回调方法来手动校验唯一性:

// 设置表单验证规则,用回调函数替代is_unique
$this->form_validation->set_rules("name", "Name", 'required|callback__check_unique_catalog_name');

// 回调方法(注意方法名前的下划线,避免被直接访问)
public function _check_unique_catalog_name($input_name)
{
    // 用Query Builder自动处理schema和表名的转义,避免SQL注入
    $this->db->where('name', $input_name);
    $this->db->from('products.catalog');
    $query = $this->db->get();

    if ($query->num_rows() > 0) {
        // 设置错误提示信息
        $this->form_validation->set_message('_check_unique_catalog_name', 'The {field} already exists in our catalog.');
        return FALSE;
    }
    return TRUE;
}

Query Builder会自动识别products.catalog是schema+表的组合,生成正确的PostgreSQL语法,不用你手动处理标识符转义。

方案2:扩展Form_validation类(通用解决方案)

如果你需要在多个地方使用带schema的唯一性验证,可以扩展系统的Form_validation类,重写is_unique方法,让它支持schema:

  1. 在application/libraries/目录下创建MY_Form_validation.php(文件名前缀要和config/config.php里的$config['subclass_prefix']一致,默认是MY_):
<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class MY_Form_validation extends CI_Form_validation {

    public function is_unique($str, $field)
    {
        // 先判断是否带schema(包含两个点:schema.table.column)
        if (substr_count($field, '.') < 2) {
            // 不带schema的情况,沿用父类的逻辑
            return parent::is_unique($str, $field);
        }

        // 拆分schema、表、列
        list($schema_table, $column) = explode('.', $field, 2);
        list($schema, $table) = explode('.', $schema_table, 2);

        // 用数据库类的方法正确转义标识符
        $schema_escaped = $this->CI->db->escape_identifiers($schema);
        $table_escaped = $this->CI->db->escape_identifiers($table);
        $column_escaped = $this->CI->db->escape_identifiers($column);

        // 执行查询
        $query = $this->CI->db->query(
            "SELECT 1 FROM $schema_escaped.$table_escaped WHERE $column_escaped = ? LIMIT 1",
            [$str]
        );

        if ($query->num_rows() > 0) {
            $this->set_message('is_unique', $this->CI->lang->line('form_validation_is_unique'));
            return FALSE;
        }

        return TRUE;
    }
}
  1. 之后你就可以像原来一样使用is_unique规则了:
$this->form_validation->set_rules("name", "Name", 'required|is_unique[products.catalog.name]');

这个扩展类会自动处理带schema的表名,同时兼容原来的简单表名场景。

内容的提问来源于stack exchange,提问作者Nafiu Lawal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 17:48:11