我使用下面的代码进行文件验证。奇怪的是,如果我试图上传超过大小限制的文件,我得到的不是空错误而不是与大小限制相关的错误。谁能解释问题出在哪里?
$validate = Validate::factory($_FILES);
$validate->rules('image',
array(
'Upload::valid' => array(),
'Upload::not_empty' => array(),
'Upload::type' =>array('Upload::type' => array('jpg','png','gif')),
'Upload::size' => array('1M'))
);
if ($validate->check())
{
//ok
$directory = DOCROOT.'uploads/';
$filepath = Upload::save($_FILES['image'], '123zxhahaxdfdgsdfsdha.jpg', $directory);
Request::instance()->redirect($redirect);
}
else
{
//error
$this->errors = $validate->errors('errors');
$errors = $this->errors;
//echo $errors;
}
答案 0 :(得分:2)
您可以通过更改验证数组中元素的顺序来修复此问题,即更改
$validate->rules(
'image',
array(
'Upload::valid' => array(),
'Upload::not_empty' => array(),
'Upload::type' =>array('Upload::type' => array('jpg','png','gif')),
'Upload::size' => array('1M'),
)
);
到
$validate->rules(
'image',
array(
'Upload::valid' => array(),
'Upload::size' => array('1M'),
'Upload::not_empty' => array(),
'Upload::type' =>array('Upload::type' => array('jpg','png','gif')),
)
);
“Wagwan?”你问。好吧,验证规则在Kohana中处理的方式,检查器停止检查更多规则。如果您想亲眼看到这一点,请在system/classes/kohana/validate.php
中找到这些行:
//This field has an error, stop executing rules.
break;
您可以在Kohana 3.0中找到它们,您似乎正在使用它们,但也会在当前的3.3中找到它们。
大概是,您通过上传文件来测试您的应用程序,该文件的大小足以被PHP甚至您的Web服务器阻止。最可能的罪魁祸首是PHP的upload_max_filesize
值,在默认的PHP安装中只有2M,参见this page from the PHP manual。这意味着文件上传是空的(因为没有文件),因为被PHP阻止太大了。
这可以解释为什么您的代码会提供您报告的行为。但Kohana的Upload::size
函数(当然!)足够聪明,可以检测到文件太大 - 你会在system/classes/kohana/upload.php
找到这些行:
if ($file['error'] === UPLOAD_ERR_INI_SIZE)
{
// Upload is larger than PHP allowed size
return FALSE;
}
因此,如果它检查第一个,它将在该规则上失败,这就是为什么我的代码重新洗牌应该摆脱你报告的不需要的行为。
另外两个,切线,备注:
首先,在system/classes/kohana/upload.php
中,您会注意到此评论:
If you _do_ require a file to be uploaded, add
the [Upload::not_empty] rule before this rule.
但是在重新排序验证规则时我没有考虑before
,因为TBH我认为它有误导性/不正确:当然你要检查上传是否有效,即所有数组字段设置,之前对这些字段的值进行测试。
其次,请注意Upload::not_empty
不检查文件大小是否大于零;为此,您可以使用以下内容创建application/classes/upload.php
:
class Upload extends Kohana_Upload {
public static function not_empty(array $file)
{
return (parent::not_empty($file)
AND $file['size']);
}
}