【问题标题】:How to catch PostTooLargeException in Laravel?如何在 Laravel 中捕获 PostTooLargeException?
【发布时间】:2017-03-19 05:14:38
【问题描述】:

要重现错误,只需将文件上传到 Laravel 中超过 php.ini 配置中的 post_max_size 的任何 POST 路由。

我的目标是简单地捕获错误,以便通知用户他上传的文件太大。说:

public function postUploadAvatar(Request $request)
  try {
    // Do something with $request->get('avatar')
    // Maybe validate file, store, whatever.
  } catch (PostTooLargeException $e) {
    return 'File too large!';
  }
}

以上代码在标准 Laravel 5 (PSR-7) 中。它的问题是一旦注入的请求发生错误,该函数就无法执行。从而无法在函数内部捕获它。那么如何捕捉呢?

【问题讨论】:

    标签: php laravel post error-handling


    【解决方案1】:

    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);
    }
    

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

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

    希望这会有所帮助!

    【讨论】:

    • 谢谢!对我来说似乎是一个好的开始。现在调查它。我会用这个更新我的发现。
    • 这会捕获错误,允许我以某种方式处理它。但在返回响应的同时,PHP 还回显消息“警告:POST Content-Length of 18156282 bytes 超出了 Unknown on line 0 中 8388608 bytes 的限制”。现在我该如何处理呢?
    • @doncadavona 您使用的是什么版本或 PHP,您使用的是什么版本的 Laravel,您的应用环境设置为什么?
    • 我有 PHP 7.0.5,Laravel 5.4。这是一个宅基地环境。设置为本地环境。调试已启用。但即使我禁用调试,警告仍然出现。
    • @doncadavona 这很奇怪,因为(除非我弄错了)Laravel 应该将 display_errors 设置为“关闭”,除非你在测试中。您是否在任何地方明确将display_errors 设置为“开启”?
    【解决方案2】:

    如果您希望向用户添加更多内容更丰富的响应,您还可以重定向到您选择的 Laravel 视图。

    public function render($request, Exception $exception)
    {
        if ($exception instanceof \Illuminate\Http\Exceptions\PostTooLargeException)
            return response()->view('errors.post-too-large');
    
        return parent::render($request, $exception);
    }
    

    另请注意: 对于要捕获的异常,您应该确保通过使用 use Illuminate\Http\Exceptions\PostTooLargeException; 导入语句导入类或像我的示例中那样编写完整路径来提供到 PostTooLargeException 的正确路径。

    【讨论】:

      【解决方案3】:

      异常在 Session 开始之前呈现,因此您无法通过错误消息重定向回来。

      您可以像这样创建一个新的刀片文件并在那里重定向:

      public function render($request, Throwable $exception)
      {
          if ($exception instanceof \Illuminate\Http\Exceptions\PostTooLargeException) {
              return $this->showCustomErrorPage();
          }
      
          return parent::render($request, $exception);
      }
      
      protected function showCustomErrorPage()
      {
          return view('errors.errors_page');
          //you can also return a response like: "return response('File too large!', 422);"
      
      }
      

      使用会话显示静态消息:

      1.您必须将ValidatePostSize 类从middleware 数组移动到middlewareGroups 数组中,直接在StartSession 之后。

              \Illuminate\Session\Middleware\StartSession::class,
              \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
      
      1. Handler.php之后你可以这样做:

         public function render($request, Throwable $exception)
         {
         if ($exception instanceof \Illuminate\Http\Exceptions\PostTooLargeException) {
             return $this->showCustomErrorPage();
         }
             return parent::render($request, $exception);
         }
        
         protected function showCustomErrorPage()
         {
             return \Illuminate\Support\Facades\Redirect::back()->withErrors(['max_upload' => 'The Message']);
         }
        
      2. 像这样在控制器上显示消息:

         @error('max_upload')
         <div class="alert" id="create-news-alert-image">{{ $message }}</div>
         @enderror
        

      【讨论】:

        猜你喜欢
        • 2018-09-07
        • 1970-01-01
        • 2019-08-31
        • 1970-01-01
        • 1970-01-01
        • 2021-07-26
        • 1970-01-01
        • 1970-01-01
        • 2018-01-05
        相关资源
        最近更新 更多