0

我似乎无法使用 Codeigniter 进行表单验证。我尝试通过创建 My_Form_validation.php 来扩展 Form_validation 类,但没有成功。我现在正在尝试回调方法。我出现了一段时间的错误,但是它们是不正确的。

这是位于我的控制器中的代码:

 function create_user() {

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

    $validate = array(

        array(
            'field' => 'first_name',
            'label' => 'First Name',
            'rules' => 'trim|required|xss_clean'
        ),

        array(
            'field' => 'last_name',
            'label' => 'Last Name',
            'rules' => 'trim|required|xss_clean'
        ),

        array(
            'field' => 'username',
            'label' => 'Username',
            'rules' => 'trim|required|xss_clean|callback_user_exists'
        ),

        array(
            'field' => 'email_address',
            'label' => 'Email Address',
            'rules' => 'trim|required|valid_email|callback_email_exists'
        ),

        array(
            'field' => 'password',
            'label' => 'Password',
            'rules' => 'trim|required|min_length[5]|max_length[32]'
        ),

        array(
            'field' => 'password2',
            'label' => 'Confirm Password',
            'rules' => 'trim|required|matches[password]'
        )

    );

    $this->form_validation->set_rules($validate);

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

        $this->load->view('user/user-signup');      

    } else {

        $this->load->model('user_model');

        if($query = $this->user_model->create_user()) {

            $this->load->view('user/user-login');

        } else {

            $this->index();

        }

    }

}

function user_exists($username) {

    $this->load->model('user_model');
    $this->user_model->user_exists($username);
    $this->form_validation->set_message('user_exists', 'This username is already taken');

}

function email_exists($email) {

    $this->load->model('user_model');
    $this->user_model->email_exists($email);
    $this->form_validation->set_message('email_exists', 'This email is already in use');

}

这是位于我的模型中的代码:

function create_user() {

    $insert_user = array(
        'first_name'    => $this->input->post('first_name'),
        'last_name'     => $this->input->post('last_name'),
        'username'      => $this->input->post('username'),
        'email_address' => $this->input->post('email_address'),         
        'password'      => md5($this->input->post('password'))                      
    );

    $insert = $this->db->insert('users', $insert_user);

    return $insert;

}


function user_exists($username) {

    $this->db->where('username', $username);
    $query = $this->db->get('users');

    if($query->num_rows > 0) {

        return true;

    } else {

        return false;

    }

}


function email_exists($email) {

    $this->db->where('email_address', $email);
    $query = $this->db->get('users');

    if($query->num_rows > 0) {

        return true;

    } else {

        return false;

    }

}

我想通过检查数据库中是否已经存在用户名或电子邮件地址来进行验证,如果存在,用户将需要进行适当的更改。

有任何想法吗?

4

4 回答 4

1

您的代码很难阅读,所以我将向您展示如何改进它。:)

在您的控制器中,您可以使用构造函数进行模型加载,而不是这两行:

$this->load->model('user_model');

像这样:

function __constructor() {
    parent::__constructor();

    $this->load->model('user_model');
}

将您的 user_exists 回调更改为:

function user_exists($username) {

    $user_check = $this->user_model->user_exists($username);

    if($user_check > 0) {
        $this->form_validation->set_message('user_exists', 'This username is already taken');
        return FALSE;
    }
    else {
        return TRUE;
    }

}

将您的 email_exists 回调更改为:

function email_exists($email) {

    $check_email = $this->user_model->email_exists($email);

    if($check_email > 0) {
        $this->form_validation->set_message('email_exists', 'This email is already in use');
        return FALSE;
    }
    else {
        return TRUE;
    }

}

现在,回到您的模型并更改这两种模型方法:

function user_exists($username) {

    $this->db->where('username', $username);
    $query = $this->db->get('users');

    return $query->num_rows();

}

function email_exists($email) {

    $this->db->where('email_address', $email);
    $query = $this->db->get('users');

    return $query->num_rows();

}

现在,您做错了,因为您不了解模型的含义。在模型方法中,您可以编写数据库查询...因此,如果您想创建一个用户,您应该在控制器中获取输入的信息,然后将它们传递给模型方法 create_user,如下所示:

控制器方法 create_user:

function create_user() {

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

    $validate = array(

        array(
            'field' => 'first_name',
            'label' => 'First Name',
            'rules' => 'trim|required|xss_clean'
        ),

        array(
            'field' => 'last_name',
            'label' => 'Last Name',
            'rules' => 'trim|required|xss_clean'
        ),

        array(
            'field' => 'username',
            'label' => 'Username',
            'rules' => 'trim|required|xss_clean|callback_user_exists'
        ),

        array(
            'field' => 'email_address',
            'label' => 'Email Address',
            'rules' => 'trim|required|valid_email|callback_email_exists'
        ),

        array(
            'field' => 'password',
            'label' => 'Password',
            'rules' => 'trim|required|min_length[5]|max_length[32]'
        ),

        array(
            'field' => 'password2',
            'label' => 'Confirm Password',
            'rules' => 'trim|required|matches[password]'
        )

    );

    $this->form_validation->set_rules($validate);

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

        $this->load->view('user/user-signup');      

    } else {
        $user_data['first_name'] = $this->input->post("first_name");
        $user_data['last_name'] = $this->input->post("last_name");
        $user_data['username'] = $this->input->post("username");
        $user_data['email_address'] = $this->input->post("email_address");
        $user_data['password'] = $this->input->post("password");

        if($query = $this->user_model->create_user($user_data)) {

            $this->load->view('user/user-login');

        } else {

            $this->index();

        }

    }

}

模型的方法create_user:

function create_user($user_data) {

    return $this->db->insert("users", $user_data);

}

就是这样,它会起作用的。祝你好运。

于 2012-06-29T07:58:12.020 回答
0

你试过is_unique[table_name.field_name]规则吗?

例子:

$this->form_validation->set_rules('username', 'Username',
 'required|min_length[5]|max_length[12]|is_unique[users.username]');

$this->form_validation->set_rules('email', 'Email',
 'required|valid_email|is_unique[users.email]');

更新

如果你想使用回调函数,那么user_exists函数应该在控制器中,而不是在你提到的模型中。正确的定义方式是——

public function username_check($str)
{
    if ($str == 'test')
    {
        $this->form_validation->set_message('username_check', 'The %s field can not be the word "test"');
        return FALSE;
    }
    else
    {
        return TRUE;
    }
}
于 2012-06-29T07:42:26.753 回答
0

我曾经也有过一样的问题。回调函数的问题之一是它只能接受一个参数。检查表单中记录的唯一性时需要考虑两种状态。1) 您正在添加新记录 2) 您正在编辑现有记录。

如果您要添加新记录,则内置is_unique可以正常工作。如果您正在编辑现有记录is_unique不起作用,因为它会找到您正在编辑的记录并说表单数据不是唯一的。

为了解决这个问题,我使用了会话类,在运行验证脚本之前将其设置为案例 2,因此您需要知道您是在编辑现有记录还是添加新记录。为此,我只需在编辑表单时向表单添加一个隐藏输入,例如记录唯一 ID。
大概您的用户表中有一个唯一的用户 ID,例如,在运行验证之前设置它。

if($this->input->post('user_id')){$this->session->set_userdata('callback_user_id',$this->input->post('user_id'));}

然后在你的回调中,使用这种算法:

案例 1) 即 $this->session->userdata('callback_user_id') == FALSE 如果用户名是唯一的,则验证并返回 true。如果用户名不是唯一的,则返回 false 并带有验证消息用户必须是唯一的。

情况 2) 即,设置了 callback_user_id。如果用户名是唯一的,则验证并返回 true 如果用户名已经设置,并且该记录与 user_id 具有相同的 id,这意味着您正在更新相同的记录,并且可以验证。否则,另一条记录具有用户名,它应该无法通过验证。在模型中,我只有一个返回用户名唯一 ID 的方法。

运行验证后,取消设置 callback_user_id 会话变量可能是个好主意。对不起,我没有要粘贴的代码,但我认为这个描述应该对你有所帮助。

==== 现在编辑,我认为用新功能覆盖表单验证是要走的路。所以:有一个语言包条目,一个表单验证行和覆盖:这假设一个名为 ID 的字段被发布,该 ID 具有该行的 id。

$lang['form_validation_is_unique_not_current'] ='The {field} field must contain a unique value.';

array('field' => 'username', 'label' => 'lang:…username…', 'rules' => 'trim|required|min_length[2]|max_length[40]|is_unique_not_current[users.username]'),


class MY_Form_validation extends CI_Form_validation {

    function __construct($rules = array())
    {
        parent::__construct($rules);
        $this->_error_prefix = '<div class="alert alert-danger"><p>';
        $this->_error_suffix = '</p></div>';
    }
    public function is_unique_not_current($str, $field)
    {
        sscanf($field, '%[^.].%[^.]', $table, $field);
        $id = $this->CI->input->post('id');
        if($this->CI->input->post('field_name'))
        {
            return isset($this->CI->db)
                ? ($this->CI->db->limit(1)->get_where($table, array(
                    $field => $str,
                    'id <> ' => $id))->num_rows() === 0)
                : FALSE;
        }
        return FALSE;

    }
}
于 2012-06-29T13:01:06.467 回答
0

像这样重写你的函数

function user_exists($username) {

$this->load->model('user_model');
$result = $this->user_model->user_exists($username);
if($result != NULL){
    $this->form_validation->set_message('user_exists', 'This username is already taken');
    return FALSE;
}else{
    return TRUE;
}
}

您没有返回 true 或 false,因此它总是得到 xss_clea 返回的最后一个 true。

于 2012-06-29T07:52:46.360 回答