首页 文章

不能使用布尔验证laravel 5

提问于
浏览
3

我正在使用Laravel 5.2,正如文档所说:

boolean验证字段必须能够转换为布尔值 . 接受的输入为true,false,1,0,“1”和“0” .

所以我创建了一个checkbox (styled like a switch from materialize),在打开时返回true,在关闭时返回false . 刀片:

{!! Form::hidden('eh_capa', 0) !!}
Want to select as a graph cover?
<label>
    Off
    <input name="cover" type="checkbox" checked>
    <span class="lever"></span>
    on
</label>

当然,此代码位于表单标记内 . 我在一个Request类中进行验证,如laravel文档的this part所述,这是我的规则方法:

public function rules()
{
    $this['cover'] = $this['cover'] === 'on' ? 1 : 0;
    $this['obra_id'] = $this->route('obra');
    $this['arquivo'] = $this->hasFile('arquivo') ? $this->file('arquivo') : NULL;
    dd($this);
    return [
        'cover' => 'required|boolean',
        'obra_id' => 'exists:obras',
        'path' => 'required',
        'arquivo' => 'required|file|max:2048|mimes:pdf',
    ];
}

dd()函数返回我的请求,如下所示:

StoreGraficoPostRequest {#441 ▼
  #container: Application {#3 ▶}
  #redirector: Redirector {#448 ▶}
  #redirect: null
  #redirectRoute: null
  #redirectAction: null
  #errorBag: "default"
  #dontFlash: array:2 [▶]
  #json: null
  #convertedFiles: array:1 [▶]
  #userResolver: Closure {#355 ▶}
  #routeResolver: Closure {#354 ▶}
  +attributes: ParameterBag {#443 ▶}
  +request: ParameterBag {#440 ▼
    #parameters: array:5 [▼
      "_token" => "bZIpGW6UCcYHlCTZuIZMtmOrpCodWyfcbO1HgQid"
      "path" => "hello.pdf"
      "cover" => 1
      "obra_id" => "29"
      "arquivo" => UploadedFile {#438 ▶}
    ]
  }
  +query: ParameterBag {#442 ▶}
  +server: ServerBag {#446 ▶}
  +files: FileBag {#445 ▶}
  +cookies: ParameterBag {#444 ▶}
  +headers: HeaderBag {#447 ▶}
  #content: ""
  #languages: null
  #charsets: null
  #encodings: null
  #acceptableContentTypes: null
  #pathInfo: null
  #requestUri: null
  #baseUrl: null
  #basePath: null
  #method: "POST"
  #format: null
  #session: Store {#394 ▶}
  #locale: null
  #defaultLocale: "en"
}

但是当我评论dd函数时,验证返回封面必须为true或false . 如果我将cover字段的值更改为true,“1”和“true”更改为on,则会发生同样的情况 . 我在网上搜索了任何有帮助但什么都没有的东西......我开始认为这是一个Laravel的bug ...

3 回答

  • 0

    好吧,我有办法做到这一点 . 诀窍就是将此代码添加到我的Request类中:

    protected function getValidatorInstance()
    {
        $data = $this->all();
        $data['eh_capa'] = $data['eh_capa'] === 'on' ? 1 : 0;
        $data['obra_id'] = $this->route('obra');
        $this->getInputSource()->replace($data);
    
        /* modify data before send to validator */
    
        return parent::getValidatorInstance();
    }
    

    然后,我的规则方法仅以返回结束 .

  • 0

    您正在错误的位置修改输入 . 您应该覆盖请求类中的all()函数,并在那里修改您的输入 .

    public function rules()
    {
        return [
            'cover' => 'required|boolean',
            'obra_id' => 'exists:obras',
            'path' => 'required',
            'arquivo' => 'required|file|max:2048|mimes:pdf',
        ];
    }
    
    public function all()
    {
        $input = parent::all();
    
        $input['cover'] = $input['cover'] === 'on' ? 1 : 0;
        $input['obra_id'] = ...
        $input['arquivo'] = ...
    
        return $input;
    }
    
  • 2

    我遇到了同样的问题并决定创建一个小的静态类来解析规则中标记为boolean的所有值 .

    优点是它只会解析规则规定为布尔值的布尔值 . 任何其他输入值将保持不变,如果您愿意,仍然可以发布值为“true”的字符串 .

    <?php
    
    namespace App\Helpers;
    
    use Illuminate\Http\Request;
    use Illuminate\Support\Facades\Validator;
    
    class ValidationHelper {
    
        /**
        * A recursive funciton to loop over any input and parse them to true booleans.
        */
        private static function _getObj(&$inputs, $idPath) {
            $idPart = array_shift($idPath);
    
            if (count($idPath) > 0) {
                if ($idPart == '*') {
                    for ($i = 0; $i < count($inputs); $i++) {
                        ValidationHelper::_getObj($inputs[$i], $idPath);
                    }
                }
                else {
                    ValidationHelper::_getObj($inputs[$idPart], $idPath);
                }
            }
            else {
                $currentValue = $inputs[$idPart];
                if ($currentValue == 1 || strtolower($currentValue) == 'true') {
                    $inputs[$idPart] = true;
                }
                else if ($currentValue == 0 || strtolower($currentValue) == 'false') {
                    $inputs[$idPart] = false;
                }
                else {  // any other value will be left untouched
                    $inputs[$idPart] = $currentValue;
                }
            }
        }
    
        /**
        * Will validate a request against the given rules.
        * Will also help fix any booleans that otherwise are parsed as 'true' strings.
        * @param Request $request   
        * @param Array $rules       
        * @return void
        */
        public static function validateRequest(Request $request, $rules) {
            // Find any rules demanding booleans:
            $booleanIDs = [];
            foreach ($rules as $id => $rule) {
                if (is_string($rule)) {
                    $rule = explode('|', $rule);
                }
                if (in_array('boolean', $rule)) {
                    $booleanIDs[] = $id;
                }
            }
    
            if (isset($booleanIDs)) {
                // Set all inputs to a bindable array:
                $inputs = [];
                foreach ($request->all() as $key => $value) {
                    $inputs[$key] = $value;
                }
    
                // Recursively loop through the boolean-ids
                foreach ($booleanIDs as $id) {
                    $idPath = explode('.', $id);
                    ValidationHelper::_getObj($inputs, $idPath);
                }
    
                // Make sure the booleans are not just validated correctly but also stay cast when accessing them through the $request later on.
                $request->replace($inputs);
            }
            else {
                $inputs = $request->all();
            }
    
            $validator = Validator::make($inputs, $rules);
            if ($validator->fails()) {
                throw new \Exception('INVALID_ARGUMENTS', $validator->errors()->all());
            }
        }
    
    }
    

    规则可以设置为数组或字符串(正常),甚至可以使用嵌套值:

    ValidationHelper::validateRequest($request, [
                ['foo'] => ['nullable', 'boolean'],
                ['bar'] => ['required', 'boolean'],
                ['item.*.isFoo'] => ['nullable', 'boolean'],
                ['item.*.isBar'] => 'required|boolean'],
            ]);
    

相关问题