Laravel validator `required` fails for empty strin

2020-08-22 07:06发布

问题:

I'm trying laravel required validator in my code, unfortunately it fails for even empty string. I do not want it fail for empty string.

$validator = \Validator::make(array("name"=>""), array("name"=>"required"));
if ($validator->fails()){
    var_dump($validator->messages());
} else {
    die("no errors :)");
}

It gives me the following output

object(Illuminate\Support\MessageBag)[602]
  protected 'messages' => 
    array (size=1)
      'name' => 
        array (size=1)
          0 => string 'The name field is required.' (length=27)
  protected 'format' => string ':message' (length=8)

It is supposed to pass, since i'm giving an empty string as the name field.

The above behavior happens in OSX environment (PHP Version 5.5.18), but it works fine in linux environment (PHP Version 5.5.9-1ubuntu4.5).

回答1:

The required rule actually returns false if you pass an empty string.

If we look at the code (Illuminate\Validation\Validator)

protected function validateRequired($attribute, $value)
{
    if (is_null($value))
    {
        return false;
    }
    elseif (is_string($value) && trim($value) === '')
    {
        return false;
    }

    // [...]

    return true;
}

I think your only option here is to write your own validation rule that checks if the value is not null:

Validator::extendImplicit('attribute_exists', function($attribute, $value, $parameters){
    return ! is_null($value);
});

(The extendImplicit is needed because with extend custom rules will only run when the value is not an empty string)

And then use it like this:

\Validator::make(array("name"=>""), array("name"=>"attribute_exists"));


回答2:

I use this:

'my_field' => 'present'  


回答3:

In Laravel 5.6 you can use just this:

public function rules()
{
    return [
        'my_field' => 'required|string|nullable'
    ];
}

Might work on older versions as well, I only tried on 5.6



回答4:

i have developed my own way to process optional input. i use associative array for validation.

$rules = array('sltcategoryid' => 'required',   
            'txttitle' => 'required|min:10|max:255',    
            'txtdetail' => 'required|min:10|max:255',   
            'rdocontenttype' => 'required', 
            'rdoislive' => 'required');
         if($request->rdocontenttype=="1" || $request->rdocontenttype=="2" && trim($request->txtcontent)=="")
            $rules["txtcontent"]="required|min:10|max:2048";
         else if ($request->rdocontenttype=="3" && isset($request->fildata)==false)
             $rules["fildata"] ="required|mimes:png,jpg,jpeg,pdf,doc,xls,ppt,bmp,zip";
         $validator = Validator::make($request->all(),$rules);
         if ($validator->fails()) 
                return redirect('content/create')->withErrors($validator)->withInput();
             else 
                return back()->with("message","content processed successfully");