【问题标题】:How to Validate File Upload in Laravel [duplicate]如何在 Laravel 中验证文件上传 [重复]
【发布时间】:2019-04-30 03:57:30
【问题描述】:

我已完成tutorial 上传图片文件。当用户上传大于 2MB 的文件时,如何在视图中验证文件上传?

create.blade.php

@if (count($errors) > 0)
    <div class="alert alert-danger">
        <strong>Whoops!</strong> Errors.<br><br>
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif
@if(session('success'))
    <div class="alert alert-success">
        {{ session('success') }}
    </div>
@endif
<div class="form-group">
    <input type="file" name="photos[]" multiple aria-describedby="fileHelp"/>
    <small id="fileHelp" class="form-text text-muted">jpeg, png, bmp - 2MB.</small>
</div>

规则

public function rules()
{
    $rules = [
        'header' => 'required|max:255',
        'description' => 'required',
        'date' => 'required',
    ];
    $photos = $this->input('photos');
    foreach (range(0, $photos) as $index) {
        $rules['photos.' . $index] = 'image|mimes:jpeg,bmp,png|max:2000';
    }

    return $rules;
}

一切正常,但是当我尝试上传大于 2MB 的文件时,出现错误:

Illuminate\Http\Exceptions\PostTooLargeException 无消息

我怎样才能解决这个问题并保护这个异常?

【问题讨论】:

    标签: laravel laravel-validation laravel-filesystem


    【解决方案1】:

    在 laravel 中,您无法在控制器中处理这种情况,因为它不会到达控制器/自定义请求,并且将在中间件中处理,因此您可以在 ValidatePostSize.php 文件中处理:

    public function handle($request, Closure $next)
     {
      //       if ($request->server('CONTENT_LENGTH') > $this->getPostMaxSize()) 
                {
                 //            throw new PostTooLargeException;
      //        }
    
       return $next($request);
     }
    
    
    
    /**
     * Determine the server 'post_max_size' as bytes.
     *
     * @return int
     */
    protected function getPostMaxSize()
    {
        if (is_numeric($postMaxSize = ini_get('post_max_size'))) {
            return (int) $postMaxSize;
        }
    
        $metric = strtoupper(substr($postMaxSize, -1));
    
        switch ($metric) {
            case 'K':
                return (int) $postMaxSize * 1024;
            case 'M':
                return (int) $postMaxSize * 1048576;
            default:
                return (int) $postMaxSize;
        }
    }
    

    带有您的自定义消息

    或在 App\Exceptions\Handler 中:

       public function render($request, Exception $exception)
       {
          if ($exception instanceof \Illuminate\Http\Exceptions\PostTooLargeException) {
            // handle response accordingly
          }
          return parent::render($request, $exception);
       }
    

    其他需要更新php.ini

    upload_max_filesize = 10MB
    

    如果您不使用上述任何解决方案,您可以使用客户端验证,例如使用 jQuery,例如:

    $(document).on("change", "#elementId", function(e) {
     if(this.files[0].size > 7244183)  //set required file size 2048 ( 2MB )
      { 
         alert("The file size is too larage");
        $('#elemendId').value = ""; 
      }
    });
    

    <script type="text/javascript"> 
     function ValidateSize(file) { 
       var FileSize = file.files[0].size / 1024 / 1024; // in MB 
       if (FileSize > 2) { 
         alert('File size exceeds 2 MB'); 
          $(file).val(''); //for clearing with Jquery 
       } else { 
    
       } 
     } 
    </script>
    

    【讨论】:

    • 我只是在尝试您的提示,但前两个没有带来任何效果。我会尝试 JQuery
    • 让我更新我的第一个选项的答案,如果它有效,请再试一次,并相应地使用值@Giacomo
    • 好的,更好:警告:10185211 字节的 POST 内容长度超过了第 0 行未知中 8388608 字节的限制。我在上传请求中将图像限制为 2MB。现在怎么办? :P
    • 现在您可以在受保护的函数中操作文件大小的值。需要从该函数返回文件大小,当上传超过该大小的文件时,您可以返回 back()->with('error','Custom error for user');
    • 文件中的逻辑是如果你想使用'post_max_size'并据此更改值,但如果你不想要,只需返回一个大小值以在顶部函数中进行比较。
    【解决方案2】:

    您已在 $rules 中验证图像。试试这个代码:

    $this->validate($request,[
                    'header' => 'required|max:255',
                    'description' => 'required',
                    'date' => 'required',
                    'photos.*' => 'image|mimes:jpeg,bmp,png|max:2000',
        ]);
    

    【讨论】:

    • AFAIK,这不会修复它,异常会在到达验证器之前被抛出。
    【解决方案3】:

    Laravel 使用它的 ValidatePostSize 中间件来检查请求的 post_max_size,如果请求的 CONTENT_LENGTH 太大,则抛出 PostTooLargeException。这意味着如果在到达控制器之前抛出异常。

    您可以在 App\Exceptions\Handler 中使用 render() 方法,例如

    public function render($request, Exception $exception){
       if ($exception instanceof PostTooLargeException) {
          return response('File too large!', 422);
       }
    
       return parent::render($request, $exception);
    }
    

    请注意,你必须从这个方法返回一个响应,你不能像从控制器方法中那样只返回一个字符串。

    上面的响应是复制返回'File too large!';您在问题的示例中有,您显然可以将其更改为其他内容。

    希望这会有所帮助!

    【讨论】:

      【解决方案4】:

      您可以尝试将自定义消息放入 message() 消息中或在 Handler 类中添加 PostTooLargeException 处理程序。类似的东西:

      public function render($request, Exception $exception)
      {
      ...
          if($exception instanceof PostTooLargeException){
                      return redirect()->back()->withErrors("Size of attached file should be less ".ini_get("upload_max_filesize")."B", 'addNote');
              }
      ...
      }
      

      【讨论】:

        猜你喜欢
        • 2014-06-30
        • 2013-03-13
        • 2018-06-03
        • 2017-02-12
        • 2023-03-03
        • 2020-11-29
        • 2016-02-25
        • 2020-06-21
        • 1970-01-01
        相关资源
        最近更新 更多