is_unique 用于 codeigniter 表单验证

Posted

技术标签:

【中文标题】is_unique 用于 codeigniter 表单验证【英文标题】:is_unique for codeigniter form validation 【发布时间】:2012-11-21 11:07:00 【问题描述】:

我试图弄清楚如何在以下情况下使用 Codeigniter 表单验证库中的 is_unique 规则。

我正在尝试提交编辑用户表单并拥有规则:

$this->form_validation->set_rules('user_name', 'User Name', 'required|trim|xss_clean|is_unique[users.user_name]');

如果表单中的其他值正在更改但该值保持不变,该怎么办。表单将看到这个值已经存在,所以如果这个值没有改变,我将如何保护它不被编辑。

【问题讨论】:

【参考方案1】:

以您的代码为例,is_unique 验证规则通过在您的 users 数据库表中查找名为 user_name 的字段来工作。如果存在具有相同值的字段,则验证为 false。

为确保它仅在用户提交新值时运行,您可以将发布的值 $this->input->post('user_name') 与从数据库中提取的值进行检查以填充表单。如果它们相同,则不验证 is_unique;

if($this->input->post('user_name') != $original_value) 
   $is_unique =  '|is_unique[users.user_name]'
 else 
   $is_unique =  ''


$this->form_validation->set_rules('user_name', 'User Name', 'required|trim|xss_clean'.$is_unique);

【讨论】:

我将原始值定义为什么? 这将是从数据库中获取的用户 user_name 的原始值。 if 语句将原始 user_name 与用户提交的数据进行比较。如果用户更改了他们的用户名,它将检查该值是否不存在,否则它将进行正常验证。 所以我需要设置另一个查询来找出当时的旧值是多少? 也许我没有完全理解,但如果你没有用数据库中的数据填充表单,你还怎么填充它? $users = $this->db->get_where('users', array('id' => $id))->row(); $original_value = $users->user_name;【参考方案2】:

我认为有一个更好的方法来解决它,仍然使用 CodeIgniters 的验证库...... 使用 edit_unique 传递一个额外参数,即您正在编辑的行的 id。见下文。我使用它并且对我来说工作得很好。希望它有所帮助

$this->form_validation->set_rules('user_name', 'User Name', 'required|trim|xss_clean|edit_unique[users.user_name.'.$id.']');

【讨论】:

this answer 中可用的函数 edit_unique()。【参考方案3】:
$something = $this->input->post('something');

$this->form->validation->set_rules('something','Something','xss_clean|is_unique['tbl'.users]');

if($this->form_validation->run()== FALSE)


【讨论】:

【参考方案4】:

简单方法

只需将 system/libraries/form_validation.php 中的 isset 更改为 is_object

public function is_unique($str, $field)

    sscanf($field, '%[^.].%[^.]', $table, $field);
    return is_object($this->CI->db) //default isset
        ? ($this->CI->db->limit(1)->get_where($table, array($field => $str))->num_rows() === 0)
        : FALSE;

【讨论】:

我刚刚将它添加到我的 MY_Form_validation 控制器中以覆盖该功能,它的工作原理是一种享受。而且我仍然可以使用回调。非常感谢:)【参考方案5】:

这是一个对我有用的简单方法,并且使用了有据可查的代码(感谢https://github.com/ivantcholakov 的分享!)。我发现它在https://github.com/bcit-ci/CodeIgniter/issues/3109#issuecomment-46346280

    下载https://github.com/ivantcholakov/starter-public-edition-3/blob/master/platform/application/libraries/MY_Form_validation.php(MIT 许可)并将其保存到您的应用程序中的 application\libraries\MY_Form_validation.php

    从 __construct() 中删除这两行:

    $this->CI->load->helper('checkbox'); $this->CI->load->helper('email');

    删除除 __construct() 和 unique() 之外的所有函数。

    在控制器的 __construct() 方法的末尾添加这一行:

    $this->load->library('form_validation');

    根据 unique() 方法的文档,更新您的验证规则以添加这样的“唯一”规则(例如,如果您已经有 required 和 trim 规则):

    ...|required|unique[tablename.fieldname,tablename.(primaryKey-used-for-updates)]|trim...

【讨论】:

【参考方案6】:

在应用程序/库文件名 MY_Form_validation.php 中扩展 Form_validation.php 库创建类

<?php

class MY_Form_validation extends CI_Form_validation
    protected $ci;
     public function __construct($config = array())
                parent::__construct($config);
                $this->ci =& get_instance();
        

                public function is_unique_update($str, $field)
                $explode=explode('@', $field);
                $field_name=$explode['0'];
                $field_id_key=$explode['1'];
                $field_id_value=$explode['2'];
                sscanf($field_name, '%[^.].%[^.]', $table, $field_name);

                 if(isset($this->ci->db))
                        if($this->ci->db->limit(1)->get_where($table, array($field_name => $str,$field_id_key=>$field_id_value))->num_rows() === 0)
                             $this->ci->form_validation->set_message('is_unique_update', 'The field field must contain a unique value.');
                            return false;
                        
                        return true;
                    


            
  

现在在你的控制器中

$this->form_validation->set_rules('user_name', 'User Name', 'required|trim|xss_clean|is_unique_update[users.user_name@id@'.$id.']');  

“@”我用来爆炸字符串 其中 id 是用户表的主键 $id 是 id 的值。 现在您可以在任何控制器中使用这个 is_unique_update 验证。

【讨论】:

【参考方案7】:

这个问题很老了,但也许一些新人会遇到这个问题,这就是它的解决方案。 我敢打赌您正在使用模块化扩展 (HMVC),并且您已经创建了一个新库 MY_Form_validation。你为回调做了 id,所以你的类上有这行代码以便使用回调:

$this->form_validation->CI =& $this;

好吧,解决这个问题的方法是,每当你想使用“is_unique”时,你必须删除这行代码“$this->form_validation->CI =& $this;”从课堂上。我遇到过这个问题,我用这种方式修复它,现在可以正常工作了。

如果你真的想使用回调“$this->form_validation->CI =& $this;”,那么只在你不想使用 is_unique 的必需“方法”/“函数”上执行。

【讨论】:

【参考方案8】:

此代码有助于创建和更新函数的唯一验证...

在控制器中

在创建和更新函数中添加此表单验证代码

$this->form_validation->set_rules('order_no', 'Order no', 'required|callback_check_order_no');

在控制器中添加这个回调函数

function check_order_no($order_no)         
        if($this->input->post('id'))
            $id = $this->input->post('id');
        else
            $id = '';
        $result = $this->Data_model->check_unique_order_no($id, $order_no);
        if($result == 0)
            $response = true;
        else 
            $this->form_validation->set_message('check_order_no', 'Order no already exist');
            $response = false;
        
        return $response;
    

在模型中

function check_unique_order_no($id = '', $order_no) 
        $this->db->where('order_no', $order_no);
        $this->db->where('status', "A");

        if($id) 
            $this->db->where_not_in('id', $id);
        
        return $this->db->get('delivery_order')->num_rows();
    

【讨论】:

【参考方案9】:

我正在使用 codeigniter3,当我在更新值时检查用户名时它显示错误,is_unique 不适用于更新场景 所以使用@Anthony Mutisya 的回答,这里是完整的解决方案

在您的控制器中,在使用数据库验证当前用户的用户名时添加此行

$this->form_validation->set_rules('user_name', 'User Name', 'required|trim|xss_clean|edit_unique[users.user_name.'.$id.']');

您可以从您提交的表单中获取$id

现在,将以下函数添加到/system/libraries/Form_Validation.php 这个文件。 System 文件夹存在于 CodeIgniter3 文件夹的根目录中。

/**
* edit_unique // for check on update value
*
* Check if the input value doesn't already exist
* in the specified database field.
*
* @param    string  $str
* @param    string  $field
* @return   bool
*/
function edit_unique($value, $params)  
    $CI =& get_instance();
    $CI->load->database();
    $CI->form_validation->set_message('edit_unique', "Sorry, that %s is already being used.");
    
    list($table, $field, $current_id) = explode(".", $params);
    
    $query = $CI->db->select()->from($table)->where($field, $value)->limit(1)->get();
    
    if ($query->row() && $query->row()->id != $current_id)
    
        return FALSE;
     else 
        return TRUE;
    

在我的情况下它工作得很好

【讨论】:

【参考方案10】:

CodeIgniter 4 已经有解决方案,

$validation->setRules([
    'email' => 'required|valid_email|is_unique[users.email,id,id]',
]);

$_POST = [
    'id' => 4,
    'email' => 'foo@example.com',
];

那么id 占位符将被替换为数字4,给出了这个修改后的规则:

$validation->setRules([
    'email' => 'required|valid_email|is_unique[users.email,id,4]',
]);

Official Documentation

【讨论】:

【参考方案11】:

我们必须为 is_unique

添加表名

为Exp.

 is_unique[users.email]

【讨论】:

以上是关于is_unique 用于 codeigniter 表单验证的主要内容,如果未能解决你的问题,请参考以下文章

CodeIgniter 的 is_unique 总是说值已经存在

唯一验证不起作用,我该怎么办?

Codeigniter 会话不适用于 PHP 7

简单的 URL 路由不适用于 CodeIgniter

用于发送邮件的 SMTP 协议不适用于 codeigniter

CSS 不适用于 CodeIgniter