Laravel 5.6 空字段验证

Posted

技术标签:

【中文标题】Laravel 5.6 空字段验证【英文标题】:Laravel 5.6 Validation on empty fields 【发布时间】:2019-01-07 17:04:41 【问题描述】:

不知何故,我觉得这应该是一个常见问题,但我似乎无法找到一个明确的答案。

问题很简单: 在验证表单时,我想从结果数组中排除空的非必填字段 - 这是为了使用在数据库级别设置的默认值。

由于 Laravel 默认使用 ConvertEmptyStringsToNull 中间件(我不太热衷于更改它),这意味着我的空字段将被转换为“null”并发送到我的数据库(因此没有得到它们的默认值,并且实际上破坏了查询,因为这些字段在数据库级别不可为空)。

$userData = $request->validate([
            'email' => 'required|string|email|max:255|unique:users',
            'number_of_whatever'  => //if this field is empty, I want it stripped out the $userData array - or automatically default to the database default
        ]);

任何有关如何以最简洁的方式解决此问题的帮助将不胜感激!我正在考虑制定一个将字段本身排除在外的自定义规则(这样我就可以在整个项目中重用这个验证规则,而不必每次遇到这种情况时都手动执行)。 另一种选择是在模型级别设置它 - 但不是那么热衷于这样做,当它已经在数据库级别完成时,必须在那里这样做似乎很奇怪。

谢谢!

【问题讨论】:

您是否尝试过从您不想验证的字段的验证请求中删除“必填”? 您可以尝试表单请求验证。它有$validated = $request->validated(); 它只返回你验证过的字段。详情请查看laravel.com/docs/5.6/validation#form-request-validation @KenziieeFlavius,这将导致该字段在未填充时设置为 null - 与“有时”或“当前”规则相同 @rkj,这与我现在使用的行为相同。除非我错过了什么?该字段正在验证中,但设置为 null,因此它存在并在结果数组中 @Ours 如果您验证请求,然后使用发布的数据,该 null 将成为默认值。我的逻辑是如果验证失败,不要继续。但如果 post 数据已经过验证,则使用 post 数据创建对象并依赖表默认处理空结果。我会尝试做一个例子并确认这一点! 【参考方案1】:

我认为你可以使用可为空的规则

$userData = $request->validate([
            'email' => 'required|string|email|max:255|unique:users',
            'number_of_whatever'  => 'nullable'
        ]);

【讨论】:

如果这有帮助或者您仍有问题,请告诉我 遗憾的是它没有。该字段在那里,具有空值 - 我希望删除该字段。我开始认为我需要删除将空字符串转换为 null 的中间件或使用不同的数据库策略【参考方案2】:

嘿,所以我发现了你的问题,也找到了解决这个问题的方法。根据下面的示例,我已经复制并现在正确理解了您的问题,即使验证器允许空值,create 方法也会引发错误并且不设置默认值。

控制器

$validator = Validator::make($data, [
    'name' => 'max:255',
    'email' => 'max:255',
    'password' => 'max:255',
]);

if ($validator->fails()) 
    dd('Validator has failed');


// This throws an error saying that the fields cannot be null!
User::create($data);

用户表

 Schema::create('users', function (Blueprint $table) 
     $table->increments('id');
     $table->string('name')->default('Ken');
     $table->string('email')->default('ken@***.com');
     $table->string('password')->default(bcrypt('password'));
     $table->rememberToken();
     $table->timestamps();
 );

我设计的解决方法是,在发布请求到达验证器之前从发布请求中删除所有空值。

示例

$data = ['name' => null, 'email' => null, 'password' => null];

foreach($data as $key => $value)

    if($value == null)
    
       unset($data[$key]);
    

这里的逻辑是通过从 post 请求中删除为 null 的字段,USER 对象不会将它们视为具有值,因此允许表默认值到表位置,但如果值为 null,这仍然是被视为一个值,因此默认值将被忽略。

我希望这是有道理的。

我的完整代码的结果

【讨论】:

嘿,非常感谢您花时间在这上面 - 我想出了一个非常相似的解决方案 // $input = array_filter($input, function($value) // return $值 !== ''; // ); - 但理想情况下,我想将此作为验证规则,以便不必手动循环每个请求。关于如何继续进行的任何意见? 哈哈,这是第一步!我推动我的团队使用 Laravel 5.6 的新标准,我真的不想去'是的,以避免我们需要删除中间件的循环'位.. 我明白,我的意思是您可以制作自己的中间件,或者从这里查看添加自定义验证规则,我不确定您是否可以查看这里创建自己的验证规则。 laravel.com/docs/5.6/validation#custom-validation-rules。但我不太确定,不管怎样,祝你好运朝着正确的方向迈出这一步。【参考方案3】:

创建一个FormRequest 并使用prepareForValidation 方法过滤掉空值:

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class TestRequest extends FormRequest

    public function authorize()
    
        return true;
    

    public function rules()
    
        return
            [
                'username' => 'required|string|email|max:255|unique:users',
                'number_of_whatever' => 'sometimes|integer',
            ];
    

    protected function prepareForValidation()
    
        if($this->number_of_whatever == null) 
            $this->request->remove('number_of_whatever');
        
    

您可以在 'sometimes' 规则之后应用除 'required' 之外的任何验证,并且仅当值不为 null 时才会应用。

【讨论】:

以上是关于Laravel 5.6 空字段验证的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 5.6 护照未经身份验证

该页面因不活动而过期。请刷新并重试。 laravel 5.6 使用 laravel 的身份验证

Laravel - 防止对空输入进行验证检查

从 Laravel 5.3 升级到 Laravel 5.4 并且空字段转换为 NULL

Laravel 5.6 上的 Ajax 身份验证重定向

Laravel 5.6 对数据库中不同表的身份验证