In Laravel 5.3, I'm trying to catch if an uploaded file has a bigger file size than upload_max_filesize. The upload field is not required.
I tried this method, but it doesn't work
public function checkFile($field)
{
if (request()->hasFile($field)){ // check if field is present
$file = request()->file($field);
if (!$file->isValid()){ // now check if it's valid
return back()->with('error', $file->getErrorMessage());
}
}
}
I can't use just if (!$file->isValid())
because file field is optional and i get a Call to a member function isValid() on null
if field is empty.
So I have to check if field is present using if (request()->hasFile($field))
, but this doesn't work for big files, since dd(request()->hasFile('picture'))
returns false
.
Of course I can rely on default Laravel Validator messages, but I get a dummy The picture failed to upload.
that doesn't give any clue to the user.
Laravel Validation will work only if the filesize you are uploading is less than the limit set in php.ini.
If you try to upload a file larger than the limit, PHP will not forward the request to Laravel, and will error straight away. Hence, Laravel cannot do anything in this scenario.
One way to fix this is to set a much larger limit in php.ini and then validating the file size in Laravel.
You should consider using the built in Laravel form request validation system. There is a built in validation rule which lets you specify a max
file size, you can check out the docs here:
https://laravel.com/docs/5.3/validation#rule-max
Your rule would look something like this:
[
'video' => 'max:256'
]
This would fail if the file uploaded was a greater size than 256kb.
You mentioned that you didn't like Laravel's built in validation error messages. No problem! You can change them in the resources/lang/en/validation.php
language file, this is the line you'd need to change:
https://github.com/laravel/laravel/blob/master/resources/lang/en/validation.php#L51
My previous answer handled the case where an uploaded file was bigger than the upload_max_filesize
setting in php.ini
. But failed when the size of the file made the Request be larger than the post_max_size
(another php.ini
setting). This case is harder to handle because the inputs (the $_POST
global, if we handled plain PHP) get cleared.
I think a Middleware is a good place to do this "validation":
public function handle(Request $request, Closure $next)
{
$post_max_size = ini_get('post_max_size') * 1024 * 1024;
$content_length = $request->server('HTTP_CONTENT_LENGTH') ?: $request->server('CONTENT_LENGTH') ?: 0;
$response = $next($request);
if ($content_length > $post_max_size)
{
return redirect()->back()->with('errors', collect([trans('validation.max.file', ['max' => 2000])]));
}
return $response;
}
(As I said, this won't preserve the input.)
Below function is taken from drupal by meustrus author at his stack answer and I taken here as example. Start with post_max_size
// Returns a file size limit in bytes based on the PHP upload_max_filesize
// and post_max_size
$max_size = parse_size(ini_get('post_max_size'));
// If upload_max_size is less, then reduce. Except if upload_max_size is
// zero, which indicates no limit.
$upload_max = parse_size(ini_get('upload_max_filesize'));
if ($upload_max > 0 && $upload_max < $max_size) {
$max_size = $upload_max;
}
//Get max upload file size limit...
$file_upload_max_size = $max_size;
Public function to parse size
public function parse_size($size) {
$unit = preg_replace('/[^bkmgtpezy]/i', '', $size); // Remove the non-unit characters from the size.
$size = preg_replace('/[^0-9\.]/', '', $size); // Remove the non-numeric characters from the size.
if ($unit) {
// Find the position of the unit in the ordered string which is the power of magnitude to multiply a kilobyte by.
return round($size * pow(1024, stripos('bkmgtpezy', $unit[0])));
}
else {
return round($size);
}
}
Set compact for send 'file_upload_max_size' value to blade
return view('YOURBLADEPATH',compact('file_upload_max_size'));
<script type="text/javascript">
document.forms[0].addEventListener('submit', function( evt ) {
var file = document.getElementById('file').files[0];
if(file && file.size < '{$file_upload_max_size}') { // 10 MB (this size is in bytes)
//Submit form
} else {
//Prevent default and display error
evt.preventDefault();
}
}, false);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With