【问题标题】:CodeIgniter 4 - Validation Custom Rule Function QuandryCodeIgniter 4 - 验证自定义规则函数 Quandry
【发布时间】:2019-10-12 09:21:52
【问题描述】:

在我的 CI4 学习中,我首先尝试模拟用户登录功能。我有一个控制器,两个视图(这里没有显示,但实际上只是页面——一个几乎只是一个表单,另一个是“空白”成功 HTML 页面),Validation.php 文件中的一组自定义规则,和一个 CustomRule.php 文件,其中第一个方法将实现我的所有自定义规则(最终,我希望在 Validation.php 文件中进行所有设置)。由于没有更好的主意,我将 CustomRules.php 文件放在了 app\Config\ 文件夹中。

这是我的问题:

对于我来说,我无法弄清楚如何让验证服务将额外的参数(来自表单)传递给我的名为“user_validated”的自定义规则函数。 CI4 文档描述了自定义函数在接受附加参数时需要满足的内容,但没有描述如何触发验证服务将这些附加参数传递给一个自定义函数……所以虽然调用了“user_validated”,但只有“user_email_offered”被传递就像一个字符串一样-据我所知,没有其他内容可以进入。我该如何解决这个问题?

我已经尝试插入 setRuleGroup('user_signin'); > 在调用验证之前,但发现我可以将规则组的设置移动到验证调用中,使用:$validationResult = $this->validate('user_signin'),这似乎做同样的事情,并且没有规则组作为参数(?)似乎不起作用。这似乎仍然不是触发将附加数据传递给自定义规则方法的原因。

我的 hack 的摘录附在下面。

我会非常感谢你们中的一位知识渊博的人能指点我正确的方向。


在 app\Controllers\SignupTest.php 中:

<?php

    namespace App\Controllers;

    use CodeIgniter\Controller;

    class SignupTest extends BaseController
    {

            public function index() {   // redirection from the default to signup(), signin(), ...

                return $this->signup();

            }


            public function signup() {

                helper(['form']);

                $validation = \Config\Services::validation();

                if ($this->request->getPost()) {     // still TBD: any different to using $this->request->getGetPost() ?

                    $validationResult = $this->validate('user_signin'); // set the rules to use: 'user_signin', 'user_signup'

                    if (!$validationResult) {

                        $validationErrors = $validation->getErrors();

                        return view('SignupTestView', $validationErrors);   // redisplay simple html form view with list of validation errors

                    } else {

                        return view('SignupTestViewSuccess');  // display view to show success 
                    }
                } else {

                    return view('SignupTestView');   // initial display, in the event of there being no POST data 

                }
            }
    }

在 \app\Config\CustomRules.php 中:

<?php

    namespace Config;

    use App\Models\UserModel;

    //--------------------------------------------------------------------
    // Custom Rule Functions 
    //--------------------------------------------------------------------

    class CustomRules
    { 


        public function user_validated(string $str, string $fields = NULL, array $data = NULL, string &$error = NULL) : bool{            

             $user_email_offered = $str;
             $user_password_offered = '';    // to be extracted using $fields = explode(',', $fields), but $fields is never provided in the call to this user_validated method


            if (($user_email_offered !== NULL) && ($user_password_offered !== NULL)) {

                $usermodel = new UserModel();   // intended to create a UserEntity to permit connectivity to the database 

                $user_found = $usermodel->find($user_email_offered);    // we're going to assume that user_email is unique (which is a rule configured in the database table)

                if ($user_found === NULL) { // check if user exists before doing the more involved checks in the else-if section below, which may throw exceptions if there's nothing to compare (?)

                ...   

          }

}

在 \app\Config\Validation.php 中:

?php 
    namespace Config;

    class Validation
    {
        //--------------------------------------------------------------------
        // Setup
        //--------------------------------------------------------------------

        /**
         * Stores the classes that contain the
         * rules that are available.
         *
         * @var array
         */
        public $ruleSets = [
            \CodeIgniter\Validation\Rules::class,
            \CodeIgniter\Validation\FormatRules::class,
            \CodeIgniter\Validation\FileRules::class,
            \CodeIgniter\Validation\CreditCardRules::class,
            \Config\CustomRules::class,
        ];

        /**
         * Specifies the views that are used to display the
         * errors.
         *
         * @var array
         */
        public $templates = [
            'list'   => 'CodeIgniter\Validation\Views\list',
            'single' => 'CodeIgniter\Validation\Views\single',
        ];

        //--------------------------------------------------------------------
        // Custom Rules
        //--------------------------------------------------------------------

        /* configurable limits for validation rules array below*/
        const user_email_min_lenth = 9;  
        const user_email_max_lenth = 50; 
        const user_password_min_lenth = 6;   
        const user_password_max_lenth = 25;  


        public $user_signin = [
            'user_email' => [
                'label' => 'e-mail address',
                'rules' => 'trim|required|valid_email|user_validated',  // user_validated is custom rule, that will have a custom error message
                'errors' => [
                    'required' => 'You must provide an {field}',
                    'valid_email' => 'Please enter a valid {field}',
                ]
            ],
            'user_password' => [
                'label' => 'password',
                'rules' => 'trim|required',
                'errors' => [
                    'required' => 'Enter a {field} to sign in',
                    'user_password_check' => 'No such user/{field} combination found',
                ] 

【问题讨论】:

    标签: php codeigniter codeigniter-4


    【解决方案1】:

    带参数调用自定义规则应该和调用CI4的常规规则完全一样。例如,让我们获取“required_without”。你可以像在这个例子中那样使用它:

    $validation->setRule('username', 'Username', 'required_without[id,email]');
    

    函数声明如下:

    public function required_without($str = null, string $fields, array $data): bool
    {
        $fields = explode(',', $fields);
    //...
    }
    

    其中 $str - 这是您的主要字段,$fields - 字符串,打包一个逗号分隔的数组。

    对于分组规则,您无需对规则进行分组即可使用带参数的自定义规则。

    如果您只有 2 个要测试的字段,则可以便宜一些,虽然不完美但仍然有效:

    功能:

    public function myrule(string $mainfield, string $fieldtotestwith): bool
    {
    //doing stuff
    }
    

    验证规则:

    $validation->setRule('somemainfield', 'Something', 'myrule[somesecondfield]');
    

    【讨论】:

    • 感谢您的帮助 Tsefo。我发现如果我只是忽略 $fields,CI Validation 类中的所有内容都可以通过 $data 在我的 CustomRules 类中使用?!我正在测试无限猴子定理——如果我按下了足够多的键,最终会以某种方式起作用;)
    猜你喜欢
    • 2016-11-22
    • 2012-01-01
    • 2020-07-02
    • 2019-11-21
    • 2013-06-21
    • 2012-01-03
    • 2017-07-25
    • 2012-01-29
    • 2020-04-27
    相关资源
    最近更新 更多