CodeIgniter 4 - 验证自定义规则函数 Quandry
CodeIgniter 4 - Validation Custom Rule Function Quandry
在我的CI4学习中,我从尝试模拟用户登录功能开始。我有一个控制器,两个视图(此处未显示,但实际上只是页面 - 一个几乎只是单一表单,另一个是“空白”成功页面 HTML),一组自定义规则 Validation.php 文件,以及一个 CustomRule.php 文件,其中第一个方法将实现我所有的自定义规则(最终,我希望在 Validation.php 文件中进行所有设置)。由于没有更好的主意,我将 CustomRules.php 文件放在 app\Config\ 文件夹中。
这是我的问题:
对于我的生活,我无法弄清楚如何让验证服务将附加参数(从表单)传递到我名为“user_validated”的自定义规则函数。 CI4 文档描述了自定义函数在接受附加参数时需要满足的条件,但没有描述如何触发验证服务将这些附加参数传递给自定义函数……所以尽管调用了“user_validated”,但只有“user_email_offered' 曾经作为字符串传递 - 据我所知,没有其他内容。我该如何解决这个问题?
我试过插入 < $validation->setRuleGroup('user_signin'); > 在验证调用之前,但发现我可以将规则组的设置移动到验证调用中,使用:$validationResult = $this->validate('user_signin'),这似乎是一样的,如果没有规则组作为参数(?),这似乎不起作用。这似乎仍然不是触发将附加数据传递给自定义规则方法的原因。
我的技巧摘录附在下面。
非常感谢你们中的一位知识渊博的人能为我指明正确的方向。
在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',
]
调用带参数的自定义规则应该和调用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]');
在我的CI4学习中,我从尝试模拟用户登录功能开始。我有一个控制器,两个视图(此处未显示,但实际上只是页面 - 一个几乎只是单一表单,另一个是“空白”成功页面 HTML),一组自定义规则 Validation.php 文件,以及一个 CustomRule.php 文件,其中第一个方法将实现我所有的自定义规则(最终,我希望在 Validation.php 文件中进行所有设置)。由于没有更好的主意,我将 CustomRules.php 文件放在 app\Config\ 文件夹中。
这是我的问题:
对于我的生活,我无法弄清楚如何让验证服务将附加参数(从表单)传递到我名为“user_validated”的自定义规则函数。 CI4 文档描述了自定义函数在接受附加参数时需要满足的条件,但没有描述如何触发验证服务将这些附加参数传递给自定义函数……所以尽管调用了“user_validated”,但只有“user_email_offered' 曾经作为字符串传递 - 据我所知,没有其他内容。我该如何解决这个问题?
我试过插入 < $validation->setRuleGroup('user_signin'); > 在验证调用之前,但发现我可以将规则组的设置移动到验证调用中,使用:$validationResult = $this->validate('user_signin'),这似乎是一样的,如果没有规则组作为参数(?),这似乎不起作用。这似乎仍然不是触发将附加数据传递给自定义规则方法的原因。
我的技巧摘录附在下面。
非常感谢你们中的一位知识渊博的人能为我指明正确的方向。
在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',
]
调用带参数的自定义规则应该和调用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]');