Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handle Laravel 4 upload big file exception

My target is to manage the max upload file exception, and show a client side friendly message, but I don´t know where is the best place to controll this. This is my controller method:

public function upload_file()
    {
        if (!Input::hasFile('file'))
            return;

        $utils = App::make('utils');
        $file = Input::file('file');

        $name = Input::get('name');
        $size = $file->getSize();

        if ($size > FileModel::$max_file_size)
            return json_encode(array('success'=>false, 'message'=>sprintf('The file size should be lower than %smb.',FileModel::$max_file_size/1000000)));

        $original_file_name = $file->getClientOriginalName();

        $destination_directory = "";

        $final_file_name = $utils->copy_file_to_location($file);

        return json_encode(array('success'=>true, 'file'=>$original_file_name));
    }

And this is the utils copy_file_to_location method:

public function copy_file_to_location($file, $destination_directory = "")
    {
        if (!isset($file))
            return;
        $file_name = time()."_".$file->getClientOriginalName();

        $file->move(app_path().'/storage/files/'.$destination_directory, $file_name);
        return $file_name;
    }

I don't knwo where to handle the exception that is raised when uploading files that have a grater size than the server max upload file size variable. Where and how should I handle this to show a user friendly message and do not lock the user interface. By the way I'm using ExtJs 4 in the client side. Thanks.


EDIT


I found a related question that helps a lot (it is the same problem), but I need to know where, inside Laravel, should I check this.

like image 470
Raúl Otaño Avatar asked Jan 07 '14 15:01

Raúl Otaño


3 Answers

There are two case: the file size is greater than the php variable upload_max_filesize and the second one is when it is grater than post_max_size variable. In the first one an exception is raised so an easy way it is catching it. In the second case there are not exception and I used this question for solving it.

Now, where check this code: in the Laravel controller aciton method. I thought that code in the controller's action never was excecuted, but I was wrong. So finally this is a way to solve this:

    public function upload_file()
    {
        $file_max = ini_get('upload_max_filesize');
        $file_max_str_leng = strlen($file_max);
        $file_max_meassure_unit = substr($file_max,$file_max_str_leng - 1,1);
        $file_max_meassure_unit = $file_max_meassure_unit == 'K' ? 'kb' : ($file_max_meassure_unit == 'M' ? 'mb' : ($file_max_meassure_unit == 'G' ? 'gb' : 'unidades'));
        $file_max = substr($file_max,0,$file_max_str_leng - 1);
        $file_max = intval($file_max);

        //handle second case
        if((empty($_FILES) && empty($_POST) && isset($_SERVER['REQUEST_METHOD']) && strtolower($_SERVER['REQUEST_METHOD']) == 'post'))
        { //catch file overload error...
             //grab the size limits...
            return json_encode(array('success'=>false, 'message'=>sprintf('The file size should be lower than %s%s.',$file_max,$file_max_meassure_unit)));
        }

        try{

            if (!Input::hasFile('file'))
                return;

            $utils = App::make('utils');
            $file = Input::file('file');

            $name = Input::get('name');
            $size = $file->getSize();

            if ($size > $file_max)
                return json_encode(array('success'=>false, 'message'=>sprintf('El tamaño del archivo debe ser menor que %smb.',$file_max)));

            $original_file_name = $file->getClientOriginalName();

            $destination_directory = "";

            $final_file_name = $utils->copy_file_to_location($file);       

            return json_encode(array('success'=>true, 'file'=>$original_file_name));
        }
        catch (Exception $e)
        {
            //handle first case
            return json_encode(array('success'=>false, 'message'=>sprintf('The file size should be lower than %s%s.',$file_max,$file_max_meassure_unit)));
        }
    } 
like image 106
Raúl Otaño Avatar answered Nov 06 '22 15:11

Raúl Otaño


Old post but still a relevant issue. use the \Illuminate\Foundation\Http\Middleware\VerifyPostSize middleware and handle the error inside the Handler.php render() method check the middleware doc https://laravel.com/docs/5.5/middleware#registering-middleware

That's my method inside Handler.php:

    public function render($request, \Exception $exception)
        {
         //thats the json your client will recieve as a response, can be anything you need
            $response = [
                'code'    => 500,
                'status'  => 'error',
                'message' => 'Internal server error.',
                'exception' => get_class($exception),
                'exception_message' => $exception->getMessage(),
                'url' => $request->decodedPath(),
                'method' => $request->method(),
            ];

            if (env('APP_ENV') === 'local') {
                $response['trace'] = $exception->getTrace();
            }

            if ($exception instanceof PostTooLargeException) {
                $response['code'] = 413; //Payload too large
                $response['message'] = $response['message'] .' The maximum request size is: ' .ini_get('post_max_size');
            }

            return response()->json($response, $response['code']);
        }
like image 31
Leandro Gomes Martinez Avatar answered Nov 06 '22 16:11

Leandro Gomes Martinez


The settings "upload_max_filesize" and "post_max_size" you see in the related question is not being handled by Laravel, it is part of the php.ini config file which is located in your PHP installation.

like image 1
Stromgren Avatar answered Nov 06 '22 17:11

Stromgren