我似乎无法使用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;
}
}
我想通过检查数据库中是否已存在用户名或电子邮件地址进行验证,如果存在,则用户需要进行适当的更改。
有什么想法吗?
答案 0 :(得分: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);
}
这就是全部,它会起作用。祝你好运。
答案 1 :(得分: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;
}
}
答案 2 :(得分: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。
答案 3 :(得分:0)
我遇到了同样的问题。 回调函数的一个问题是它只能接受一个参数。 在检查表单中记录的唯一性时,需要考虑两种状态。 1)您正在添加新记录 2)您正在编辑现有记录。
如果您要添加新记录,则内置的 is_unique 可以正常工作。 如果您正在编辑现有记录 is_unique 不起作用,因为它找到您正在编辑的记录并说表单数据不是唯一的。
为了解决这个问题,我使用了会话类,在运行验证脚本之前将其设置为案例2,因此您需要知道是在编辑现有记录还是添加新记录。要做到这一点,我只需在编辑时为表单添加一个隐藏的输入,例如记录唯一ID 大概你在用户表中有一个唯一的用户ID,例如在验证运行之前设置它。
如果($这 - &GT;输入 - &GT;柱( 'USER_ID')){$这 - &GT;会话而&GT; set_userdata( 'callback_user_id',$这 - &GT;输入 - &GT;柱('USER_ID “));}
然后在你的回调中,使用这种算法:
案例1)即$ this-&gt; session-&gt; userdata('callback_user_id')== FALSE 如果用户名是唯一的,则验证并返回true。 如果用户名不是唯一的,则返回false,验证消息用户必须是唯一的。
情况2)即,设置了callback_user_id。 如果用户名是唯一的,则验证并返回true 如果用户名已经设置,并且该记录与user_id具有相同的id,则表示您正在更新相同的记录,并且可以进行验证。 否则,另一条记录具有用户名,并且它应该无法通过验证。 在模型中,我只有一个返回用户名唯一ID的方法。
运行验证后,取消设置callback_user_id会话变量可能是个好主意。 对不起,我没有要粘贴的代码,但我认为这个描述可以帮到你。
====编辑 如今,我认为用新功能覆盖表单验证是可行的方法。 so:有一个语言包条目,一个表单验证行和覆盖: 这假定一个名为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;
}
}