From 0ab483d67b1ca74c9f5b7e8ee8a4e0bc08250b03 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Sat, 7 May 2016 10:15:16 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=B9=E8=BF=9BInput=E7=B1=BB=E5=AF=B9file?= =?UTF-8?q?=E7=9A=84=E6=94=AF=E6=8C=81=20Validate=E7=B1=BB=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0file=20fileSize=20fileExt=20fileMime=E9=AA=8C=E8=AF=81?= =?UTF-8?q?=E8=A7=84=E5=88=99=20=E5=A2=9E=E5=8A=A0File=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- library/think/{UploadFile.php => File.php} | 61 +++++++------- library/think/Input.php | 42 ++++++++-- library/think/Validate.php | 94 ++++++++++++++++++++++ 3 files changed, 163 insertions(+), 34 deletions(-) rename library/think/{UploadFile.php => File.php} (63%) diff --git a/library/think/UploadFile.php b/library/think/File.php similarity index 63% rename from library/think/UploadFile.php rename to library/think/File.php index f809902a..639bbe1c 100644 --- a/library/think/UploadFile.php +++ b/library/think/File.php @@ -11,26 +11,22 @@ namespace think; -class UploadFile +use SplFileObject; + +class File extends SplFileObject { /** - * 上传文件信息 - * @var array - */ - protected $info = []; - - /** - * 上传错误信息 + * 错误信息 * @var string */ private $error = ''; - public function __construct($file) - { - $this->info = $file; - } - + /** + * 检查目录是否可写 + * @param string $path 目录 + * @return boolean + */ protected function checkPath($path) { @@ -46,20 +42,34 @@ class UploadFile } } + /** + * 获取文件类型信息 + * @return string + */ + public function getMime() + { + $finfo = finfo_open(FILEINFO_MIME_TYPE); + return finfo_file($finfo, $this->getRealPath()); + } + /** * 移动文件 * @param string $path 保存路径 * @param string $savename 保存的文件名 * @param boolean $replace 同名文件是否覆盖 - * @return boolean 保存状态,true-成功,false-失败 + * @return false|SplFileInfo false-失败 否则返回SplFileInfo实例 */ - public function moveTo($path, $savename = '', $replace = true) + public function move($path, $savename = '', $replace = true) { + if (!is_uploaded_file($this->getRealPath())) { + return false; + } + if (false === $this->checkPath($path)) { return false; } - $savename = $savename ?: $this->info['name']; + $savename = $savename ?: $this->getFilename(); /* 不覆盖同名文件 */ if (!$replace && is_file($path . $savename)) { $this->error = '存在同名文件' . $path . $savename; @@ -67,25 +77,20 @@ class UploadFile } /* 移动文件 */ - if (!move_uploaded_file($this->info['tmp_name'], $path . $savename)) { + if (!move_uploaded_file($this->getRealPath(), $path . $savename)) { $this->error = '文件上传保存错误!'; return false; } - $this->info['path'] = $path; - $this->info['savename'] = $savename; - return true; + + return new SplFileInfo($path . $savename); } /** - * 获取文件信息 - * @param string $path 保存路径 - * @param string $savename 保存的文件名 - * @param boolean $replace 同名文件是否覆盖 - * @return mixed 保存状态,true-成功,false-失败 + * 获取错误信息 + * @return mixed */ - public function getInfo($name = '') + public function getError() { - return isset($this->info[$name]) ? $this->info[$name] : $this->info; + return $this->error; } - } diff --git a/library/think/Input.php b/library/think/Input.php index 57a84d42..f41555df 100644 --- a/library/think/Input.php +++ b/library/think/Input.php @@ -12,6 +12,7 @@ namespace think; use think\Config; +use think\File; class Input { @@ -128,6 +129,9 @@ class Input */ public static function session($name = '', $default = null, $filter = null, $merge = false) { + if (PHP_SESSION_DISABLED == session_status()) { + session_start(); + } return self::data($_SESSION, $name, $default, $filter, $merge); } @@ -205,14 +209,40 @@ class Input /** * 获取$_FILES * @param string $name 数据名称 - * @param string $default 默认值 - * @param string $filter 过滤方法 - * @param boolean $merge 是否与默认的过虑方法合并 - * @return mixed + * @return \think\File|array */ - public static function file($name = '', $default = null, $filter = null, $merge = false) + public static function file($name = '') { - return self::data($_FILES, $name, $default, $filter, $merge); + if (!empty($_FILES)) { + if ('' === $name) { + // 获取全部文件 + $file = []; + foreach ($_FILES as $name => $val) { + if (empty($val['tmp_name'])) { + continue; + } + if (is_array($val['tmp_name'])) { + foreach ($val['tmp_name'] as $item) { + $file[] = new File($item); + } + } else { + $file[] = new File($val['tmp_name']); + } + } + return $file; + } elseif (!empty($_FILES[$name]['tmp_name'])) { + if (is_array($_FILES[$name]['tmp_name'])) { + $file = []; + foreach ($_FILES[$name]['tmp_name'] as $item) { + $file[] = new File($item); + } + return $file; + } else { + return new File($_FILES[$name]['tmp_name']); + } + } + } + return null; } /** diff --git a/library/think/Validate.php b/library/think/Validate.php index d6a639c1..5ff0929d 100644 --- a/library/think/Validate.php +++ b/library/think/Validate.php @@ -11,6 +11,8 @@ namespace think; +use think\Input; + class Validate { // 实例 @@ -40,6 +42,7 @@ class Validate 'array' => ':attribute必须是数组', 'accepted' => ':attribute必须是yes、on或者1', 'date' => ':attribute格式不符合', + 'file' => ':attribute不是有效的上传文件', 'alpha' => ':attribute只能是字母', 'alphaNum' => ':attribute只能是字母和数字', 'alphaDash' => ':attribute只能是字母、数字和下划线_及破折号-', @@ -69,6 +72,9 @@ class Validate 'regex' => ':attribute不符合指定规则', 'method' => '无效的请求类型', 'token' => '令牌数据无效', + 'fileSize' => '上传文件大小不符', + 'fileExt' => '上传文件后缀不符', + 'fileMime' => '上传文件类型不符', ]; // 当前验证场景 @@ -524,6 +530,10 @@ class Validate // 是否为数组 $result = is_array($value); break; + case 'file': + $file = Input::file($value); + $result = !empty($file); + break; default: if (isset(self::$type[$rule])) { // 注册的验证规则 @@ -563,6 +573,90 @@ class Validate return $this->filter($value, FILTER_VALIDATE_IP, 'ipv6' == $rule ? FILTER_FLAG_IPV6 : FILTER_FLAG_IPV4); } + /** + * 验证上传文件后缀 + * @access protected + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @return bool + */ + protected function fileExt($value, $rule) + { + $file = Input::file($value); + if (empty($file)) { + return false; + } + if (is_string($rule)) { + $rule = explode(',', $rule); + } + if (is_array($file)) { + foreach ($file as $item) { + if (!in_array(strtolower($item->getExtension()), $rule)) { + return false; + } + } + return true; + } else { + return in_array(strtolower($file->getExtension()), $rule); + } + } + + /** + * 验证上传文件类型 + * @access protected + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @return bool + */ + protected function fileMime($value, $rule) + { + $file = Input::file($value); + if (empty($file)) { + return false; + } + if (is_string($rule)) { + $rule = explode(',', $rule); + } + if (is_array($file)) { + foreach ($file as $item) { + if (!in_array(strtolower($item->getMime()), $rule)) { + return false; + } + } + return true; + } else { + return in_array(strtolower($file->getMime()), $rule); + } + } + + /** + * 验证上传文件大小 + * @access protected + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @return bool + */ + protected function fileSize($value, $rule) + { + $file = Input::file($value); + if (empty($file)) { + return false; + } + if (is_string($rule)) { + $rule = explode(',', $rule); + } + if (is_array($file)) { + foreach ($file as $item) { + if ($item->getSize() > $rule) { + return false; + } + } + return true; + } else { + return $file->getSize() <= $rule; + } + } + /** * 验证请求类型 * @access protected