改进File类,增加文件上传验证机制

This commit is contained in:
thinkphp
2016-07-17 21:59:17 +08:00
parent 199084e027
commit 03707ae445
2 changed files with 171 additions and 55 deletions

View File

@@ -25,6 +25,8 @@ class File extends SplFileObject
protected $filename; protected $filename;
// 文件上传命名规则 // 文件上传命名规则
protected $rule = 'date'; protected $rule = 'date';
// 文件上传验证规则
protected $validate = [];
// 单元测试 // 单元测试
protected $isTest; protected $isTest;
// 上传文件信息 // 上传文件信息
@@ -108,6 +110,17 @@ class File extends SplFileObject
return $this; return $this;
} }
/**
* 设置上传文件的验证规则
* @param array $rule 验证规则
* @return $this
*/
public function validate($rule = [])
{
$this->validate = $rule;
return $this;
}
/** /**
* 检测是否合法的上传文件 * 检测是否合法的上传文件
* @return bool * @return bool
@@ -120,6 +133,106 @@ class File extends SplFileObject
return is_uploaded_file($this->filename); return is_uploaded_file($this->filename);
} }
/**
* 检测上传文件
* @param array $rule 验证规则
* @return bool
*/
public function check($rule = [])
{
$rule = $rule ?: $this->validate;
/* 检查文件大小 */
if (isset($rule['size']) && !$this->checkSize($rule['size'])) {
$this->error = '上传文件大小不符!';
return false;
}
/* 检查文件Mime类型 */
if (isset($rule['type']) && !$this->checkMime($rule['type'])) {
$this->error = '上传文件MIME类型不允许';
return false;
}
/* 检查文件后缀 */
if (isset($rule['ext']) && !$this->checkExt($rule['ext'])) {
$this->error = '上传文件后缀不允许';
return false;
}
/* 检查图像文件 */
if (!$this->checkImg()) {
$this->error = '非法图像文件!';
return false;
}
return true;
}
/**
* 检测上传文件后缀
* @param array|string $ext 允许后缀
* @return bool
*/
public function checkExt($ext)
{
if (is_string($ext)) {
$ext = explode(',', $ext);
}
$extension = strtolower(pathinfo($this->getInfo('name'), PATHINFO_EXTENSION));
if (!in_array($extension, $ext)) {
return false;
}
return true;
}
/**
* 检测图像文件
* @return bool
*/
public function checkImg()
{
$extension = strtolower(pathinfo($this->getInfo('name'), PATHINFO_EXTENSION));
/* 对图像文件进行严格检测 */
if (in_array($extension, array('gif', 'jpg', 'jpeg', 'bmp', 'png', 'swf'))) {
$imginfo = getimagesize($this->filename);
if (empty($imginfo) || ('gif' == $extension && empty($imginfo['bits']))) {
return false;
}
}
return true;
}
/**
* 检测上传文件大小
* @param integer $size 最大大小
* @return bool
*/
public function checkSize($size)
{
if ($this->getSize() > $size) {
return false;
}
return true;
}
/**
* 检测上传文件类型
* @param array|string $mime 允许类型
* @return bool
*/
public function checkMime($mime)
{
if (is_string($mime)) {
$mime = explode(',', $mime);
}
if (!in_array(strtolower($this->getMime()), $mime)) {
return false;
}
return true;
}
/** /**
* 移动文件 * 移动文件
* @param string $path 保存路径 * @param string $path 保存路径
@@ -135,6 +248,10 @@ class File extends SplFileObject
return false; return false;
} }
// 验证上传
if (!$this->check()) {
return false;
}
$path = rtrim($path, DS) . DS; $path = rtrim($path, DS) . DS;
// 文件保存命名规则 // 文件保存命名规则
$savename = $this->getSaveName($savename); $savename = $this->getSaveName($savename);
@@ -189,12 +306,12 @@ class File extends SplFileObject
$savename = call_user_func($this->rule); $savename = call_user_func($this->rule);
} }
} }
if (!strpos($savename, '.')) {
$savename .= '.' . pathinfo($this->getInfo('name'), PATHINFO_EXTENSION);
}
} elseif ('' === $savename) { } elseif ('' === $savename) {
$savename = $this->getInfo('name'); $savename = $this->getInfo('name');
} }
if (!strpos($savename, '.')) {
$savename .= '.' . pathinfo($this->getInfo('name'), PATHINFO_EXTENSION);
}
return $savename; return $savename;
} }

View File

@@ -11,7 +11,6 @@
namespace think; namespace think;
use think\Exception;
use think\Request; use think\Request;
class Validate class Validate
@@ -50,7 +49,7 @@ class Validate
'activeUrl' => ':attribute不是有效的域名或者IP', 'activeUrl' => ':attribute不是有效的域名或者IP',
'chs' => ':attribute只能是汉字', 'chs' => ':attribute只能是汉字',
'chsAlpha' => ':attribute只能是汉字、字母', 'chsAlpha' => ':attribute只能是汉字、字母',
'chsAlphaNum'=> ':attribute只能是汉字、字母和数字', 'chsAlphaNum' => ':attribute只能是汉字、字母和数字',
'chsDash' => ':attribute只能是汉字、字母、数字和下划线_及破折号-', 'chsDash' => ':attribute只能是汉字、字母、数字和下划线_及破折号-',
'url' => ':attribute不是有效的URL地址', 'url' => ':attribute不是有效的URL地址',
'ip' => ':attribute不是有效的IP地址', 'ip' => ':attribute不是有效的IP地址',
@@ -630,13 +629,13 @@ class Validate
} }
if (is_array($file)) { if (is_array($file)) {
foreach ($file as $item) { foreach ($file as $item) {
if (!in_array(strtolower($item->getExtension()), $rule)) { if (!$item->checkExt($rule)) {
return false; return false;
} }
} }
return true; return true;
} else { } else {
return in_array(strtolower($file->getExtension()), $rule); return $file->checkExt($rule);
} }
} }
@@ -658,13 +657,13 @@ class Validate
} }
if (is_array($file)) { if (is_array($file)) {
foreach ($file as $item) { foreach ($file as $item) {
if (!in_array(strtolower($item->getMime()), $rule)) { if (!$item->checkMime($rule)) {
return false; return false;
} }
} }
return true; return true;
} else { } else {
return in_array(strtolower($file->getMime()), $rule); return $file->checkMime($rule);
} }
} }
@@ -686,13 +685,13 @@ class Validate
} }
if (is_array($file)) { if (is_array($file)) {
foreach ($file as $item) { foreach ($file as $item) {
if ($item->getSize() > $rule) { if (!$item->checkExt($rule)) {
return false; return false;
} }
} }
return true; return true;
} else { } else {
return $file->getSize() <= $rule; return $file->checkSize($rule);
} }
} }