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

あなたのコードは非常に読みにくいので、それをどのように改善するかをお見せします。:)

コントローラでは、次の2行の代わりに、モデルのロードにコンストラクタを使用できます。

$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;
    }

}

ここで、モデルに戻り、次の2つのモデルの方法を変更します。

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 つは、1 つのパラメーターしか受け入れられないことです。フォーム内のレコードの一意性をチェックする際に考慮すべき 2 つの状態があります。1) 新しいレコードを追加している 2) 既存のレコードを編集している。

新しいレコードを追加する場合、組み込みのis_uniqueは正常に機能します。既存のレコードを編集している場合、is_uniqueは機能しません。これは、編集中のレコードが検出され、フォーム データが一意ではないことが示されるためです。

この問題を回避するために、セッション クラスを使用し、検証スクリプトを実行する前にケース 2 に設定しました。そのため、既存のレコードを編集しているか、新しいレコードを追加しているかを知る必要があります。これを行うには、編集時に非表示の入力をフォームに追加するだけです。たとえば、レコードの一意の ID です。
おそらく、users テーブルに一意のユーザー 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 が設定されます。ユーザー名が一意の場合、ユーザー名が既に設定されていて、そのレコードが user_id と同じ ID を持っている場合は、検証して true を返します。これは、同じレコードを更新していることを意味し、検証しても問題ありません。それ以外の場合、別のレコードにユーザー名があり、検証に失敗するはずです。モデルには、ユーザー名の一意の 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;

    }
}
于 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 に答える