在Laravel 5.3中,我试图捕获上传文件的文件大小是否大于upload_max_filesize。上传字段不是必需的。
我尝试了这种方法,但它不起作用
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());
}
}
}
我不能只使用if (!$file->isValid())
,因为文件字段是可选的,如果字段为空,我会得到Call to a member function isValid() on null
。
因此,我必须使用if (request()->hasFile($field))
检查字段是否存在,但这不适用于大文件,因为dd(request()->hasFile('picture'))
会返回false
。
当然,我可以依赖默认的Laravel Validator消息,但是我得到一个假的The picture failed to upload.
,它不会给用户任何线索。
答案 0 :(得分:5)
仅当您上传的文件大小小于php.ini中设置的限制时,Laravel验证才有效。
如果您尝试上传大于限制的文件,PHP将不会将请求转发给Laravel,并且会立即出错。因此,Laravel在这种情况下无能为力。
解决此问题的一种方法是在php.ini中设置一个更大的限制,然后在Laravel中验证文件大小。
答案 1 :(得分:4)
您应该考虑使用内置的Laravel表单请求验证系统。内置验证规则允许您指定max
文件大小,您可以在此处查看文档:
https://laravel.com/docs/5.3/validation#rule-max
你的规则看起来像这样:
[
'video' => 'max:256'
]
如果上传的文件大于256kb,则会失败。
您提到您不喜欢Laravel的内置验证错误消息。没问题!您可以在resources/lang/en/validation.php
语言文件中更改它们,这是您需要更改的行:
https://github.com/laravel/laravel/blob/master/resources/lang/en/validation.php#L51
答案 2 :(得分:2)
My previous answer处理了上传文件大于Args...
中Args&...
设置的情况。但是当文件大小使请求大于upload_max_filesize
(另一个php.ini
设置)时失败。这种情况更难处理,因为输入(post_max_size
全局,如果我们处理普通的PHP)被清除。
我认为中间件是一个做这件事的好地方"验证":
php.ini
(正如我所说,这不会保留输入。)
答案 3 :(得分:1)
下面的函数来自meustrus作者在stack answer的drupal,我在这里作为例子。 以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 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);
}
}
为发送&#39; file_upload_max_size&#39;设置紧凑刀片的价值
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);
答案 4 :(得分:-1)
Laravel文件验证程序的默认行为是,如果上载不正常,则无论出于何种原因拒绝该文件。然后不应用验证规则,因此“最大”规则无法帮助您。 在这种情况下,您显然需要针对此类错误的自定义消息(超出最大文件大小)。我认为扩展Validator类是一个优雅的解决方案。
use Illuminate\Http\UploadedFile;
use Illuminate\Validation\Validator;
class UploadSizeValidator extends Validator
{
protected function validateAttribute($attribute, $rule)
{
$value = $this->getValue($attribute);
if ($value instanceof UploadedFile && $value->getError() != UPLOAD_ERR_OK) {
switch ($value->getError()) {
case UPLOAD_ERR_INI_SIZE:
return $this->addFailure($attribute, 'max_file_size_exceeded', []);
// check additional UPLOAD_ERR_XXX constants if you want to handle other errors
}
}
return parent::validateAttribute($attribute, $rule);
}
}
现在,您如何告诉框架使用验证器而不是默认验证器?您可以在Validator Factory上设置解析器功能:
// do this in a 'boot' method of a ServiceProvider
use Illuminate\Support\Facades\Validator;
Validator::resolver(function($translator, $data, $rules, $messages, $customAttributes) {
return new UploadSizeValidator($translator, $data, $rules, $messages, $customAttributes);
});
最后在validation.php
lang文件中为密钥“max_file_size_exceeded”设置适当的消息。