使用Laravel 4验证多文件上传

4

如何在Laravel 4中验证上传文件的数组?我已经在表单中设置允许多个文件,并测试了存在于Input :: file('files')数组中的文件。但是如何对每个文件进行验证呢?

以下是我尝试过的:

$notesData = array(
            'date' => Input::get('date'),
            'files' => Input::file('files')
    );


    // Declare the rules for the form validation.
    $rules = array(
            'date'  => 'Required|date_format:Y-m-d',
            'files'  => 'mimes:jpeg,bmp,png,pdf,doc'
    );

    // Validate the inputs.
    $validator = Validator::make($notesData, $rules);

    // Check if the form validates with success.
    if ($validator->passes())
    {
        // Redirect to homepage
        return Redirect::to('')->with('success', 'Validation passed!');
    }

    // Something went wrong.
    return Redirect::to(URL::previous())->withErrors($validator)->withInput(Input::all());

我本来以为Validator会抱怨在数据数组中传递文件数组,但即使我发送的文件是mp3格式,它也通过了验证。当我尝试上传多个文件时,它会给出一个不相关的错误,说需要输入日期字段(尽管日期字段已自动填充)。
我对Laravel很陌生,我该如何解决这个问题?
更新:我发现问题的一部分是我的upload_max_filesize和post_max_size,我已经进行了修复。我还尝试动态地将文件添加到数组中,如下所示:
$notesData = array(
            'date' => Input::get('date')
    );
    $i=0;
    foreach(\Input::file('files') as $file){
        $notesData['file'.++$i] = $file;
    }

    // Declare the rules for the form validation.
    $rules = array(
            'date'  => 'Required|date_format:Y-m-d'
    );
    for($j=1; $j<=$i; $j++){
        $rules['file'.$j] ='mimes:jpeg,bmp,png,doc'; 
    }

但现在我遇到了以下错误:

不允许对 'Symfony\Component\HttpFoundation\File\UploadedFile' 进行序列化

我现在无法解决这个问题。您有什么建议?

4个回答

11

我认为这基本上是您最初的解决方案。对于仍然感到困惑的人,以下是一些适用于我的代码...

// Handle upload(s) with input name "files[]" (array) or "files" (single file upload)

if (Input::hasFile('files')) {
    $all_uploads = Input::file('files');

    // Make sure it really is an array
    if (!is_array($all_uploads)) {
        $all_uploads = array($all_uploads);
    }

    $error_messages = array();

    // Loop through all uploaded files
    foreach ($all_uploads as $upload) {
        // Ignore array member if it's not an UploadedFile object, just to be extra safe
        if (!is_a($upload, 'Symfony\Component\HttpFoundation\File\UploadedFile')) {
            continue;
        }

        $validator = Validator::make(
            array('file' => $upload),
            array('file' => 'required|mimes:jpeg,png|image|max:1000')
        );

        if ($validator->passes()) {
            // Do something
        } else {
            // Collect error messages
            $error_messages[] = 'File "' . $upload->getClientOriginalName() . '":' . $validator->messages()->first('file');
        }
    }

    // Redirect, return JSON, whatever...
    return $error_messages;
} else {
    // No files have been uploaded
}

这对我有用。 不要忘记使用*enctype="multipart/form-data"*打开表单,例如:{{ Form::open(['files'=>true]) }} - PJunior

3

我不太确定是什么原因导致了错误,但在验证器中尝试了一下后,我发现不能一次传递所有文件。相反,我创建了一个新的数组,将每个文件与 'file0','file1' 等键相关联。然后,使用 foreach 循环为每个文件设置规则,并将这些文件传递给验证器。之后,验证器按预期工作。但它还不够灵活,最终我使用了非 Laravel 解决方案。


6
我想我可能已经找出了导致序列化错误的原因。如果验证失败,我总是将输入重定向到以前的页面,但显然文件输入不能被序列化,所以我必须使用"withInput(Input::except('files')"而不是"withInput(Input::all())"。 - Chris
2
那个评论救了我,@chris!发现得好。谢谢! - zgosalvez

1
这可能不是你问题的直接答案,但你可以通过以下方式对类型进行简单的验证检查:
$file = Input::file('files');

switch($file->getClientMimeType()){
      case 'application/pdf':
           // upload stuff
      break;
}

谢谢,但不完全是我想要的。最终我还是写了自己的解决方案,而不是使用验证器。 - Chris

0
foreach(Request::file('photos') as $key => $value) {
    $rules['photos.'.$key]="mimes:jpeg,jpg,png,gif|required|max:10000";
    $friendly_names['photos.'.$key]="photos";
}

这在 Laravel 5.2 中对我有效


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接