Laravel 复杂条件验证
Laravel Complex Conditional Validation
我正在尝试创建一个至少需要三个输入之一的验证器。
我试过了
protected function validateFundingSource (): array
{
return request()->validate([
'title' => 'required',
'description' => 'required',
'national' => 'nullable',
'province' => Rule::requiredIf(!request('national')),
'url' => [
'required_without_all:phone,email',
'active_url'
],
'phone' => [
'required_without_all:url,email|regex:/^(\+\s?)?1?\-?\.?\s?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}(?: *#(\d+))?\s*$/im'
],
'email' => [
'required_without_all:url,phone|email:rfc,dns'
],
'categories' => 'exists:categories,id'
]);
}
但它只强制第一个字段 (url)。所以我尝试了 Complex Conditional Validation.
protected function validateFundingSource ()
{
$v = Validator::make(request()->all(), [
'title' => 'required',
'description' => 'required',
'national' => 'nullable',
'categories' => 'exists:categories,id',
]);
$v->sometimes('province', 'required', function ($input) {
return ($input->national === null) ;
});
$v->sometimes('url', 'required|active_url', function ($input) {
return (($input->phone === null) && ($input->email === null));
});
$v->sometimes('phone', 'required|regex:/^(\+\s?)?1?\-?\.?\s?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}(?: *#(\d+))?\s*$/im', function ($input) {
return (($input->url === null) && ($input->email === null));
});
$v->sometimes('email', 'required|email:rfc,dns', function ($input) {
return (($input->url === null) && ($input->phone === null));
});
return $v;
}
但仍然没有运气......现在不再需要我可以提交所有三个空字段并且它正在工作......
有什么线索可以帮助我吗?
谢谢!
您的代码运行良好。您只是忘记检查验证是否通过。
因为当你使用 Validator::make 时你需要手动检查它。 for request()->validate laravel 将为您完成。在您的 validateFundingSource () 函数中,只需在 return 之前检查它是否通过验证,如下所示:
private function validateFundingSource () {
$v = Validator::make(request()->all(), [
'title' => 'required',
'description' => 'required',
'national' => 'nullable',
'categories' => 'exists:categories,id',
]);
$v->sometimes('province', 'required', function ($input) {
return ($input->national === null) ;
});
$v->sometimes('url', 'required|active_url', function ($input) {
return (($input->phone === null) && ($input->email === null));
});
$v->sometimes('phone', 'required|regex:/^(\+\s?)?1?\-?\.?\s?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}(?: *#(\d+))?\s*$/im', function ($input) {
return (($input->url === null) && ($input->email === null));
});
$v->sometimes('email', 'required|email:rfc,dns', function ($input) {
return (($input->url === null) && ($input->phone === null));
});
// check if validae failed
if($v->fails()) {
dd('fail', $v); // do something when it failed
}
}
也很抱歉我的英语不好,希望对您有所帮助
如果您要查找 "at least one of" url
、phone
或 email
,那么您需要使用 required_without
。此规则表示当缺少 any 指定字段时,该字段是必需的; required_without_all
表示缺少 所有 指定字段时需要。
您还混淆了规则语法,您必须使用数组或竖线分隔的字符串语法,不能同时使用两者。
您可能还想改进 phone 数字正则表达式; + -. (000-111.9999 #8
不是一个很好的 phone 数字,但会通过您的验证。我建议清理您的值以删除除数字和前导 + 之外的所有内容,然后在剩下的内容上使用更好的模式。
而且,这只是外观上的更改,但您可以像其他规则一样用简单的 required_if
规则替换 Rule::requiredIf(!request('national')),
。
更改为 form request validation,这看起来像:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class StoreFundingsource extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Prepare the data for validation.
*
* @return void
*/
protected function prepareForValidation()
{
$phone = preg_replace("/[^0-9]/", "", $this->phone);
if (strpos($this->phone, "+") === 0) {
$phone = "+$phone";
}
$this->merge(["phone"=>$phone]);
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'title' => ['required'],
'description' => ['required'],
'national' => ['nullable'],
'province' => ['required_if,national,'],
'categories' => ['exists:categories,id']
'url' => [
'required_without:phone,email',
'active_url'
],
'phone' => [
'required_without:url,email',
'regex:/^\+?1?[2-9][0-9]{5,14}$/'
],
'email' => [
'required_without:url,phone',
'email:rfc,dns'
],
];
}
}
我正在尝试创建一个至少需要三个输入之一的验证器。
我试过了
protected function validateFundingSource (): array
{
return request()->validate([
'title' => 'required',
'description' => 'required',
'national' => 'nullable',
'province' => Rule::requiredIf(!request('national')),
'url' => [
'required_without_all:phone,email',
'active_url'
],
'phone' => [
'required_without_all:url,email|regex:/^(\+\s?)?1?\-?\.?\s?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}(?: *#(\d+))?\s*$/im'
],
'email' => [
'required_without_all:url,phone|email:rfc,dns'
],
'categories' => 'exists:categories,id'
]);
}
但它只强制第一个字段 (url)。所以我尝试了 Complex Conditional Validation.
protected function validateFundingSource ()
{
$v = Validator::make(request()->all(), [
'title' => 'required',
'description' => 'required',
'national' => 'nullable',
'categories' => 'exists:categories,id',
]);
$v->sometimes('province', 'required', function ($input) {
return ($input->national === null) ;
});
$v->sometimes('url', 'required|active_url', function ($input) {
return (($input->phone === null) && ($input->email === null));
});
$v->sometimes('phone', 'required|regex:/^(\+\s?)?1?\-?\.?\s?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}(?: *#(\d+))?\s*$/im', function ($input) {
return (($input->url === null) && ($input->email === null));
});
$v->sometimes('email', 'required|email:rfc,dns', function ($input) {
return (($input->url === null) && ($input->phone === null));
});
return $v;
}
但仍然没有运气......现在不再需要我可以提交所有三个空字段并且它正在工作......
有什么线索可以帮助我吗?
谢谢!
您的代码运行良好。您只是忘记检查验证是否通过。 因为当你使用 Validator::make 时你需要手动检查它。 for request()->validate laravel 将为您完成。在您的 validateFundingSource () 函数中,只需在 return 之前检查它是否通过验证,如下所示:
private function validateFundingSource () {
$v = Validator::make(request()->all(), [
'title' => 'required',
'description' => 'required',
'national' => 'nullable',
'categories' => 'exists:categories,id',
]);
$v->sometimes('province', 'required', function ($input) {
return ($input->national === null) ;
});
$v->sometimes('url', 'required|active_url', function ($input) {
return (($input->phone === null) && ($input->email === null));
});
$v->sometimes('phone', 'required|regex:/^(\+\s?)?1?\-?\.?\s?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}(?: *#(\d+))?\s*$/im', function ($input) {
return (($input->url === null) && ($input->email === null));
});
$v->sometimes('email', 'required|email:rfc,dns', function ($input) {
return (($input->url === null) && ($input->phone === null));
});
// check if validae failed
if($v->fails()) {
dd('fail', $v); // do something when it failed
}
}
也很抱歉我的英语不好,希望对您有所帮助
如果您要查找 "at least one of" url
、phone
或 email
,那么您需要使用 required_without
。此规则表示当缺少 any 指定字段时,该字段是必需的; required_without_all
表示缺少 所有 指定字段时需要。
您还混淆了规则语法,您必须使用数组或竖线分隔的字符串语法,不能同时使用两者。
您可能还想改进 phone 数字正则表达式; + -. (000-111.9999 #8
不是一个很好的 phone 数字,但会通过您的验证。我建议清理您的值以删除除数字和前导 + 之外的所有内容,然后在剩下的内容上使用更好的模式。
而且,这只是外观上的更改,但您可以像其他规则一样用简单的 required_if
规则替换 Rule::requiredIf(!request('national')),
。
更改为 form request validation,这看起来像:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class StoreFundingsource extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Prepare the data for validation.
*
* @return void
*/
protected function prepareForValidation()
{
$phone = preg_replace("/[^0-9]/", "", $this->phone);
if (strpos($this->phone, "+") === 0) {
$phone = "+$phone";
}
$this->merge(["phone"=>$phone]);
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'title' => ['required'],
'description' => ['required'],
'national' => ['nullable'],
'province' => ['required_if,national,'],
'categories' => ['exists:categories,id']
'url' => [
'required_without:phone,email',
'active_url'
],
'phone' => [
'required_without:url,email',
'regex:/^\+?1?[2-9][0-9]{5,14}$/'
],
'email' => [
'required_without:url,phone',
'email:rfc,dns'
],
];
}
}