使用带有附加参数的自定义规则验证 Laravel 中的数组
Validating array in Laravel using custom rule with additional parameter
我正在使用 Laravel 5.7,我需要使用 2 个输入(前缀+数字)来验证 phone 长度。总位数必须始终为 10。
我正在将此自定义规则用于其他工作正常的项目:
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class PhoneLength implements Rule
{
public $prefix;
/**
* Create a new rule instance.
*
* @return void
*/
public function __construct($prefix = null)
{
//
$this->prefix = $prefix;
}
/**
* Determine if the validation rule passes.
*
* @param string $attribute
* @param mixed $value
* @return bool
*/
public function passes($attribute, $value)
{
//
return strlen($this->prefix)+strlen($value) == 10 ? true : false;
}
/**
* Get the validation error message.
*
* @return string
*/
public function message()
{
return 'El Teléfono debe contener 10 dígitos (prefijo + número)';
}
}
在我的控制器中,我做了类似
的事情
$validatedData = $request->validate([
'prefix' => 'integer|required',
'number' => ['integer','required', new PhoneLength($request->prefix)],
]);
现在我需要使用数组,所以我的新验证看起来像
$validatedData = $request->validate([
'phones.*.prefix' => 'required',
'phones.*.number' => ['required', new PhoneLength('phones.*.prefix')],
]);
以上代码根本不起作用,参数没有按预期发送。
如何发送数组值?当然我需要从同一个数组元素中获取值,所以如果 phones[0].number
正在验证中,则需要前缀 phones[0].prefix
。
我发现了这个问题,但我拒绝相信这不可能以 "native" 的方式进行:
Laravel array validation with custom rule
提前致谢
您可以从请求本身得到 $prefix
:
class PhoneLength implements Rule
{
public function passes($attribute, $value)
{
$index = explode('.', $attribute)[1];
$prefix = request()->input("phones.{$index}.prefix");
}
}
或者在PhoneLength
规则构造函数中传递$request
,然后使用它。
Abdeldayem Sherif的答案很好,但是当属性的嵌套级别更高时就会出现问题,例如:clients.*.phones.*.prefix
。在这种情况下,分解并使用 1
索引将导致意外错误。更好的解决方案是使用 str_replace
.
class PhoneLength implements Rule
{
public function passes($attribute, $value)
{
$prefixAttr = str_replace('.number', '.prefix', $attribute);
$prefix = request()->input($prefixAttr);
}
}
根据这个 https://github.com/laravel/framework/pull/18654 你可以使用,它会将你的自定义规则添加为依赖项并用所需的索引替换星号
Validator::extendDependent('contains', function ($attribute, $value, $parameters, $validator) {
// The $parameters passed from the validator below is ['*.provider'], when we imply that this
// custom rule is dependent the validator tends to replace the asterisks with the current
// indices as per the original attribute we're validating, so *.provider will be replaced
// with 0.provider, now we can use array_get() to get the value of the other field.
// So this custom rule validates that the attribute value contains the value of the other given
// attribute.
return str_contains($value,
array_get($validator->getData(), $parameters[0])
);
});
Validator::make(
[['email' => 'test@mail.com', 'provider' => 'mail.com']],
['*.email' => 'contains:*.provider']
)->validate();
我正在使用 Laravel 5.7,我需要使用 2 个输入(前缀+数字)来验证 phone 长度。总位数必须始终为 10。
我正在将此自定义规则用于其他工作正常的项目:
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class PhoneLength implements Rule
{
public $prefix;
/**
* Create a new rule instance.
*
* @return void
*/
public function __construct($prefix = null)
{
//
$this->prefix = $prefix;
}
/**
* Determine if the validation rule passes.
*
* @param string $attribute
* @param mixed $value
* @return bool
*/
public function passes($attribute, $value)
{
//
return strlen($this->prefix)+strlen($value) == 10 ? true : false;
}
/**
* Get the validation error message.
*
* @return string
*/
public function message()
{
return 'El Teléfono debe contener 10 dígitos (prefijo + número)';
}
}
在我的控制器中,我做了类似
的事情$validatedData = $request->validate([
'prefix' => 'integer|required',
'number' => ['integer','required', new PhoneLength($request->prefix)],
]);
现在我需要使用数组,所以我的新验证看起来像
$validatedData = $request->validate([
'phones.*.prefix' => 'required',
'phones.*.number' => ['required', new PhoneLength('phones.*.prefix')],
]);
以上代码根本不起作用,参数没有按预期发送。
如何发送数组值?当然我需要从同一个数组元素中获取值,所以如果 phones[0].number
正在验证中,则需要前缀 phones[0].prefix
。
我发现了这个问题,但我拒绝相信这不可能以 "native" 的方式进行: Laravel array validation with custom rule
提前致谢
您可以从请求本身得到 $prefix
:
class PhoneLength implements Rule
{
public function passes($attribute, $value)
{
$index = explode('.', $attribute)[1];
$prefix = request()->input("phones.{$index}.prefix");
}
}
或者在PhoneLength
规则构造函数中传递$request
,然后使用它。
Abdeldayem Sherif的答案很好,但是当属性的嵌套级别更高时就会出现问题,例如:clients.*.phones.*.prefix
。在这种情况下,分解并使用 1
索引将导致意外错误。更好的解决方案是使用 str_replace
.
class PhoneLength implements Rule
{
public function passes($attribute, $value)
{
$prefixAttr = str_replace('.number', '.prefix', $attribute);
$prefix = request()->input($prefixAttr);
}
}
根据这个 https://github.com/laravel/framework/pull/18654 你可以使用,它会将你的自定义规则添加为依赖项并用所需的索引替换星号
Validator::extendDependent('contains', function ($attribute, $value, $parameters, $validator) {
// The $parameters passed from the validator below is ['*.provider'], when we imply that this
// custom rule is dependent the validator tends to replace the asterisks with the current
// indices as per the original attribute we're validating, so *.provider will be replaced
// with 0.provider, now we can use array_get() to get the value of the other field.
// So this custom rule validates that the attribute value contains the value of the other given
// attribute.
return str_contains($value,
array_get($validator->getData(), $parameters[0])
);
});
Validator::make(
[['email' => 'test@mail.com', 'provider' => 'mail.com']],
['*.email' => 'contains:*.provider']
)->validate();