codeigniter 4:在null上调用成员函数,其中post请求在var_dump()中有效

发布于 2025-02-04 05:59:44 字数 13525 浏览 2 评论 0原文

**对Codeigniter非常新颖,请友好! **

我的两个用户身份验证表格有问题:用户/register.phpusers/login.php我无法将帖子输入传递给我的模型中的函数。

截至目前,我在注册表单上的null 上获取错误call to contration function adduser(),并在登录表上获得验证错误,该登录表中指示用户名/密码不匹配任何凭据在数据库中。两者似乎都源于帖子,尽管事实并非如此。

我已经在$ login上完成了一个var_dump,该定义为$ login = $ this-> request-> getPost(),并在Firefox开发人员中检查了请求浏览器以查找正确显示的所有帖子数据。我很难过。为什么我不能将这个数组传递给我的模型?

这是login.php的POST请求的屏幕截图(对于registration.php,可以说同样的话,并且不包括在内)。

这些是我的路线:

// Login and Registration
$routes->match(['get', 'post'], 'users/register', 'Users::register');
$routes->match(['get', 'post'], 'users/login', 'Users::login', ["filter" => "noauth"]);

这是我的Model usermodel.php的完整途径:

class UserModel extends Model
{
    protected $DBGroup          = 'default';
    protected $table            = 'users';
    protected $primaryKey       = 'username';
    protected $useAutoIncrement = false;
    protected $insertID         = 0;
    protected $returnType       = 'object';
    protected $useSoftDelete    = false;
    protected $allowedFields    = [
        'username',
        'password',
        'id',
        'role',
        'profile_image',
        'profile_views',
        'last_login',
        'about_me',
        'age',
        'gender',
        'occupation',
        'hometown',
        'country',
        'fav_shape',
        'fav_color',
        'created',
        'modified',
    ];

    // Dates
    protected $useTimestamps    = true;
    protected $dateFormat       = 'datetime';
    protected $createdField     = 'created';
    protected $modifiedField    = 'modified';

    // Callbacks
    protected $allowCallbacks   = true;
    protected $beforeInsert     = ['beforeInsert'];

    public function __construct() 
    {
        parent::__construct(); 
    }

    protected function beforeInsert(array $data)
    {
        $data = $this->passwordHash($data);

        return $data;
    }

    protected function passwordHash(array $data)
    {
        if (isset($data['password'])) {

            $data['password'] = password_hash($data['password'], PASSWORD_DEFAULT);
        }

        return $data;
    }

       public function lastLogin($username)
    {
        $this->builder()
            ->where('username', $username)
            ->update('last_login', date('Y-m-d H:i:s'));
    }

    public function addUser($newUser)
    {
        $builder = $this->builder()
            ->set($newUser)
            ->insert();

        if ($builder->affected_rows() == 1) {

            return TRUE;
        
        } else {

            return FALSE;
        }
    }

    public function getUser($username)
    {
        $builder = $this->builder()
            ->where(['username' => $username])
            ->limit(1);

        if ($builder->countAllResults() === 1) {
            
            return $builder->get()->getRow();
        
        } else {

            return FALSE;
        }
    }
}

以下是我的controller users.php

class Users extends BaseController
{
    protected $userModel;

    public function __construct() 
    {
        $userModel = new UserModel();
    }

    public function login()
    {
        $validation = \Config\Services::validation();

        // Set session variable
        $session = session();

        if ($this->request->getMethod() === 'post' && ! empty($_POST)) {   
            $validation->getRuleGroup('login');
            $validation->setRuleGroup('login');
            $validation->withRequest($this->request)->run(); 

            $recaptchaResponse = trim($this->request->getVar('g-recaptcha-response'));

            $userIp = $this->request->getIPAddress();

            $secret = env('recaptcha2_secretkey');

            $credential = [
                'secret'    => $secret,
                'response'  => $recaptchaResponse,
                'remoteip'  => $userIp,
            ];

            $verify = curl_init();

            curl_setopt($verify, CURLOPT_URL, 'https://www.google.com/recaptcha/api/siteverify');
            curl_setopt($verify, CURLOPT_POST, TRUE);
            curl_setopt($verify, CURLOPT_POSTFIELDS, http_build_query($credential));
            curl_setopt($verify, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($verify, CURLOPT_RETURNTRANSFER, TRUE);

            $response = curl_exec($verify);

            $status = json_decode($response, TRUE);

            curl_close($verify);

            if (empty($validation->getErrors()) && $status['success']) {
                $login = $this->request->getPost();

                $user = $this->userModel->getUser($login['username']);

                // Storing session values
                $this->setUserSession($user);

                // Storing success message
                $session->setFlashdata('success', 'You have successfully logged in!');

                // Update last login datetime
                $this->userModel->lastLogin($login['username']);

                // Redirecting to dashboard after login
                if ($user['role'] == 1) {

                    return redirect()->to('admin/dashboard');
                
                } elseif ($user['role'] == 0) {

                    return redirect()->to('members/dashboard');
                }
            } else {

                $data = [
                    'title'     => 'Login',
                    'errors'    => $validation->getErrors(),
                ];

                echo view('templates/index_header', $data);
                echo view('users/login');
                echo view('templates/footer', $data);
            }   
        } else {
            $data = [
                'title' => 'Login',
            ];

                echo view('templates/index_header', $data);
                echo view('users/login');
                echo view('templates/footer', $data);  
        }
    }

    /**
     * Sets session with user id, username, isLoggedIn, and role for use in member/admin site
     * @param model user data
     * @return boole if session was set successfully
     */
    private function setUserSession($user)
    {
        $data = [
            'id' => $user->id,
            'username' => $user->username,
            'profile_image' => $user->profile_image,
            'isLoggedIn' => true,
            'role' => $user->role,
        ];

        if (session()->set($data)) {
            
            return true;
        
        } else {

            return false;
        }
    }

    public function register() 
    {
        $validation = \Config\Services::validation();

        if ($this->request->getMethod() == 'post' && ! empty($_POST)) {

            $validation->getRuleGroup('registration');
            $validation->setRuleGroup('registration');
            $validation->withRequest($this->request)->run(); 

            if (empty($validation->getErrors())) {

                $newUser = $this->request->getPost();

                if ($this->userModel->addUser($newUser)) {

                    $this->session->setFlashdata('success', 'Successful Registration');

                    $data['title'] = 'Login';

                    echo view('templates/index_header', $data);
                    echo view('users/login');
                    echo view('templates/footer', $data);

                } else {

                    $this->session->setFlashdata('error', 'Something went wrong with your registration! Please try again.');
                }

            } else {

                $data = [];

                $data = [
                    'title'     => 'Register',
                    'script'    => 'js/click_link',
                    'errors'    => $validation->getErrors(),
                ];
                
                echo view('templates/index_header', $data);
                echo view('users/register', $data);
                echo view('templates/footer', $data);
            }
        } else {
            $data = [
                'title'         => 'Register',
                'script'        => 'js/click_link',
            ];
        
            echo view('templates/index_header', $data);
            echo view('users/register', $data);
            echo view('templates/footer', $data);
        }
    }
}

这些是我的验证config \验证中的规则

/**
     *  Registration
     */
    public $registration = [
        'username'      => 'required|is_unique[users.username,username]|min_length[5]|max_length[25]|alpha_dash|badWordsFilter[username]',
        'password'      => 'required|min_length[8]|max_length[255]|regex_match[/^(?=.*[!@#$%^&*-])(?=.*[0-9])(?=.*[A-Z]).{8,255}$/]',
        'pass_confirm'  => 'required|matches[password]',
        'about_me'      => 'permit_empty|max_length[250]|alpha_numeric_punct|badWordsFilter[about_me]',
        'occupation'    => 'permit_empty|max_length[50]|alpha_space|badWordsFilter[occupation]',
        'hometown'      => 'permit_empty|max_length[50]|alpha_space|badWordsFilter[hometown]',
        'age'           => 'permit_empty|less_than[100]|greater_than[0]|numeric',
        'country'       => 'permit_empty',
    ];
/**
     *  Password Verification
     */
    public $login = [
        'password'      => 'required|validateUser[username,password]',
    ];

是我的自定义规则,可以验证用户名和密码凭据user_rules

class User_rules 
{
    /**
     * Checks if input username exists in database and then checks whether the input password matches the hash for that username
     * @param string $str is the input password
     * @param string $fields are the associated form fields that are being used
     * @param array $data is an array containing the values for the fields indexed by field names
     * @return boolean true or false depending on if the user exists and the password matches the hashed password stored in the database
     */
    public function validateUser(string $str, string $fields, array $data)
    {
        $userModel = new UserModel();

        $user = $userModel->getUser($data['username']);

        if(!$user) {

            return FALSE;
        }

        return password_verify($data['password'], $user->password);
    }

最后,我对login.php的视图:

<div class='form-container'>

    <?= form_open('users/login',['autocomplete' => FALSE]); ?>

        <div class='form-header'>
            <h2>Login</h2>
        </div>
        
        <div class='form-body'>

            <div class='form-row'>
                <div class='input-container'>
                    <i class='fas fa-user'></i>

                    <?php $attributes = [
                        'type'      => 'text',
                        'name'      => 'username',
                        'class'     => 'input-field',
                        'id'        => 'username',
                        'placeholder'   => 'Username',
                        'required'      => TRUE,
                    ]; ?>
                    <?= form_input($attributes); ?>
                
                </div>
            </div>

            <div class='form-row'>
                <div class='input-container'>
                    <i class='fas fa-lock'></i>

                    <?php $attributes = [
                        'type'          => 'password',
                        'name'          => 'password',
                        'class'         => 'input-field',
                        'placeholder'   => 'Password',
                        'required'      => TRUE,
                    ]; ?>
                    <?= form_input($attributes); ?>
                  
                </div`>
            </div>
        </div>
                
        <div class='captcha-container'>
            <div class='g-recaptcha' data-sitekey='<?= env('recaptcha2_sitekey'); ?>'></div>
        </div>

        <div class='form-footer'>

            <?php $submit = [
                    'name'      => 'loginSubmit',
                    'value'     => 'Login',
                    'class'     => 'submit-btn',
            ];?>
            <?= form_submit($submit); ?>
    
        </div>

        <h4 style='text-align: center'>Not a member yet? Register 
            <a href= <?= site_url('users/register'); ?> title = 'Register'> HERE</a>
        </h4>

     <?= form_close(); ?>
</div>

** Very new to CodeIgniter so please be kind! **

I have an issue with my two user authentication forms: users/register.php and users/login.php where I cannot pass the post input to functions in my model.

As of now, I'm getting the error Call to member function addUser() on null on the registration form and a validation error on the login form that states the username/password don't match any credentials in the database. Both seem to stem from post being null although it is not.

I have done a var_dump on $login which is defined as $login = $this->request->getPost() as well as inspected the request in Firefox Developers Browser to find all the post data correctly displayed. I am stumped. Why can't I pass this array to my model?

Here is a screenshot of the post request for login.php (the same can be said for registration.php and is not included).

Screenshot showing inspector mode in Firefox Developer Browser.

These are my routes:

// Login and Registration
$routes->match(['get', 'post'], 'users/register', 'Users::register');
$routes->match(['get', 'post'], 'users/login', 'Users::login', ["filter" => "noauth"]);

Here is my model UserModel.php in its entirety:

class UserModel extends Model
{
    protected $DBGroup          = 'default';
    protected $table            = 'users';
    protected $primaryKey       = 'username';
    protected $useAutoIncrement = false;
    protected $insertID         = 0;
    protected $returnType       = 'object';
    protected $useSoftDelete    = false;
    protected $allowedFields    = [
        'username',
        'password',
        'id',
        'role',
        'profile_image',
        'profile_views',
        'last_login',
        'about_me',
        'age',
        'gender',
        'occupation',
        'hometown',
        'country',
        'fav_shape',
        'fav_color',
        'created',
        'modified',
    ];

    // Dates
    protected $useTimestamps    = true;
    protected $dateFormat       = 'datetime';
    protected $createdField     = 'created';
    protected $modifiedField    = 'modified';

    // Callbacks
    protected $allowCallbacks   = true;
    protected $beforeInsert     = ['beforeInsert'];

    public function __construct() 
    {
        parent::__construct(); 
    }

    protected function beforeInsert(array $data)
    {
        $data = $this->passwordHash($data);

        return $data;
    }

    protected function passwordHash(array $data)
    {
        if (isset($data['password'])) {

            $data['password'] = password_hash($data['password'], PASSWORD_DEFAULT);
        }

        return $data;
    }

       public function lastLogin($username)
    {
        $this->builder()
            ->where('username', $username)
            ->update('last_login', date('Y-m-d H:i:s'));
    }

    public function addUser($newUser)
    {
        $builder = $this->builder()
            ->set($newUser)
            ->insert();

        if ($builder->affected_rows() == 1) {

            return TRUE;
        
        } else {

            return FALSE;
        }
    }

    public function getUser($username)
    {
        $builder = $this->builder()
            ->where(['username' => $username])
            ->limit(1);

        if ($builder->countAllResults() === 1) {
            
            return $builder->get()->getRow();
        
        } else {

            return FALSE;
        }
    }
}

Here are excerpts from my controller Users.php:

class Users extends BaseController
{
    protected $userModel;

    public function __construct() 
    {
        $userModel = new UserModel();
    }

    public function login()
    {
        $validation = \Config\Services::validation();

        // Set session variable
        $session = session();

        if ($this->request->getMethod() === 'post' && ! empty($_POST)) {   
            $validation->getRuleGroup('login');
            $validation->setRuleGroup('login');
            $validation->withRequest($this->request)->run(); 

            $recaptchaResponse = trim($this->request->getVar('g-recaptcha-response'));

            $userIp = $this->request->getIPAddress();

            $secret = env('recaptcha2_secretkey');

            $credential = [
                'secret'    => $secret,
                'response'  => $recaptchaResponse,
                'remoteip'  => $userIp,
            ];

            $verify = curl_init();

            curl_setopt($verify, CURLOPT_URL, 'https://www.google.com/recaptcha/api/siteverify');
            curl_setopt($verify, CURLOPT_POST, TRUE);
            curl_setopt($verify, CURLOPT_POSTFIELDS, http_build_query($credential));
            curl_setopt($verify, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($verify, CURLOPT_RETURNTRANSFER, TRUE);

            $response = curl_exec($verify);

            $status = json_decode($response, TRUE);

            curl_close($verify);

            if (empty($validation->getErrors()) && $status['success']) {
                $login = $this->request->getPost();

                $user = $this->userModel->getUser($login['username']);

                // Storing session values
                $this->setUserSession($user);

                // Storing success message
                $session->setFlashdata('success', 'You have successfully logged in!');

                // Update last login datetime
                $this->userModel->lastLogin($login['username']);

                // Redirecting to dashboard after login
                if ($user['role'] == 1) {

                    return redirect()->to('admin/dashboard');
                
                } elseif ($user['role'] == 0) {

                    return redirect()->to('members/dashboard');
                }
            } else {

                $data = [
                    'title'     => 'Login',
                    'errors'    => $validation->getErrors(),
                ];

                echo view('templates/index_header', $data);
                echo view('users/login');
                echo view('templates/footer', $data);
            }   
        } else {
            $data = [
                'title' => 'Login',
            ];

                echo view('templates/index_header', $data);
                echo view('users/login');
                echo view('templates/footer', $data);  
        }
    }

    /**
     * Sets session with user id, username, isLoggedIn, and role for use in member/admin site
     * @param model user data
     * @return boole if session was set successfully
     */
    private function setUserSession($user)
    {
        $data = [
            'id' => $user->id,
            'username' => $user->username,
            'profile_image' => $user->profile_image,
            'isLoggedIn' => true,
            'role' => $user->role,
        ];

        if (session()->set($data)) {
            
            return true;
        
        } else {

            return false;
        }
    }

    public function register() 
    {
        $validation = \Config\Services::validation();

        if ($this->request->getMethod() == 'post' && ! empty($_POST)) {

            $validation->getRuleGroup('registration');
            $validation->setRuleGroup('registration');
            $validation->withRequest($this->request)->run(); 

            if (empty($validation->getErrors())) {

                $newUser = $this->request->getPost();

                if ($this->userModel->addUser($newUser)) {

                    $this->session->setFlashdata('success', 'Successful Registration');

                    $data['title'] = 'Login';

                    echo view('templates/index_header', $data);
                    echo view('users/login');
                    echo view('templates/footer', $data);

                } else {

                    $this->session->setFlashdata('error', 'Something went wrong with your registration! Please try again.');
                }

            } else {

                $data = [];

                $data = [
                    'title'     => 'Register',
                    'script'    => 'js/click_link',
                    'errors'    => $validation->getErrors(),
                ];
                
                echo view('templates/index_header', $data);
                echo view('users/register', $data);
                echo view('templates/footer', $data);
            }
        } else {
            $data = [
                'title'         => 'Register',
                'script'        => 'js/click_link',
            ];
        
            echo view('templates/index_header', $data);
            echo view('users/register', $data);
            echo view('templates/footer', $data);
        }
    }
}

These are my validation rules in Config\Validation:

/**
     *  Registration
     */
    public $registration = [
        'username'      => 'required|is_unique[users.username,username]|min_length[5]|max_length[25]|alpha_dash|badWordsFilter[username]',
        'password'      => 'required|min_length[8]|max_length[255]|regex_match[/^(?=.*[!@#$%^&*-])(?=.*[0-9])(?=.*[A-Z]).{8,255}$/]',
        'pass_confirm'  => 'required|matches[password]',
        'about_me'      => 'permit_empty|max_length[250]|alpha_numeric_punct|badWordsFilter[about_me]',
        'occupation'    => 'permit_empty|max_length[50]|alpha_space|badWordsFilter[occupation]',
        'hometown'      => 'permit_empty|max_length[50]|alpha_space|badWordsFilter[hometown]',
        'age'           => 'permit_empty|less_than[100]|greater_than[0]|numeric',
        'country'       => 'permit_empty',
    ];
/**
     *  Password Verification
     */
    public $login = [
        'password'      => 'required|validateUser[username,password]',
    ];

This is my custom rule to authenticate username and password credentials User_rules:

class User_rules 
{
    /**
     * Checks if input username exists in database and then checks whether the input password matches the hash for that username
     * @param string $str is the input password
     * @param string $fields are the associated form fields that are being used
     * @param array $data is an array containing the values for the fields indexed by field names
     * @return boolean true or false depending on if the user exists and the password matches the hashed password stored in the database
     */
    public function validateUser(string $str, string $fields, array $data)
    {
        $userModel = new UserModel();

        $user = $userModel->getUser($data['username']);

        if(!$user) {

            return FALSE;
        }

        return password_verify($data['password'], $user->password);
    }

Lastly, my view for login.php:

<div class='form-container'>

    <?= form_open('users/login',['autocomplete' => FALSE]); ?>

        <div class='form-header'>
            <h2>Login</h2>
        </div>
        
        <div class='form-body'>

            <div class='form-row'>
                <div class='input-container'>
                    <i class='fas fa-user'></i>

                    <?php $attributes = [
                        'type'      => 'text',
                        'name'      => 'username',
                        'class'     => 'input-field',
                        'id'        => 'username',
                        'placeholder'   => 'Username',
                        'required'      => TRUE,
                    ]; ?>
                    <?= form_input($attributes); ?>
                
                </div>
            </div>

            <div class='form-row'>
                <div class='input-container'>
                    <i class='fas fa-lock'></i>

                    <?php $attributes = [
                        'type'          => 'password',
                        'name'          => 'password',
                        'class'         => 'input-field',
                        'placeholder'   => 'Password',
                        'required'      => TRUE,
                    ]; ?>
                    <?= form_input($attributes); ?>
                  
                </div`>
            </div>
        </div>
                
        <div class='captcha-container'>
            <div class='g-recaptcha' data-sitekey='<?= env('recaptcha2_sitekey'); ?>'></div>
        </div>

        <div class='form-footer'>

            <?php $submit = [
                    'name'      => 'loginSubmit',
                    'value'     => 'Login',
                    'class'     => 'submit-btn',
            ];?>
            <?= form_submit($submit); ?>
    
        </div>

        <h4 style='text-align: center'>Not a member yet? Register 
            <a href= <?= site_url('users/register'); ?> title = 'Register'> HERE</a>
        </h4>

     <?= form_close(); ?>
</div>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

穿越时光隧道 2025-02-11 05:59:44

这是一个愚蠢的错误。 Codeigniter论坛上的某人在这里回答了我的问题:

基本上在构造函数中,我需要$ this-&gt; usermodel = new usermodel();而不是$ usermodel = new usermodel();

It was a stupid mistake. Someone on the codeigniter forum answered my question here: CodeIgniter Forum

basically in my constructor I needed $this->userModel = new UserModel(); instead of $userModel = new UserModel();.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文