123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429 |
- <?php
- namespace Think;
- class Upload {
-
- private $config = array(
- 'mimes' => array(),
- 'maxSize' => 0,
- 'exts' => array(),
- 'autoSub' => true,
- 'subName' => array('date', 'Y-m-d'),
- 'rootPath' => './Uploads/',
- 'savePath' => '',
- 'saveName' => array('uniqid', ''),
- 'saveExt' => '',
- 'replace' => false,
- 'hash' => true,
- 'callback' => false,
- 'driver' => '',
- 'driverConfig' => array(),
- );
-
- private $error = '';
-
- private $uploader;
-
- public function __construct($config = array(), $driver = '', $driverConfig = null){
-
- $this->config = array_merge($this->config, $config);
-
- $this->setDriver($driver, $driverConfig);
-
- if(!empty($this->config['mimes'])){
- if(is_string($this->mimes)) {
- $this->config['mimes'] = explode(',', $this->mimes);
- }
- $this->config['mimes'] = array_map('strtolower', $this->mimes);
- }
- if(!empty($this->config['exts'])){
- if (is_string($this->exts)){
- $this->config['exts'] = explode(',', $this->exts);
- }
- $this->config['exts'] = array_map('strtolower', $this->exts);
- }
- }
-
- public function __get($name) {
- return $this->config[$name];
- }
- public function __set($name,$value){
- if(isset($this->config[$name])) {
- $this->config[$name] = $value;
- if($name == 'driverConfig'){
-
-
- $this->setDriver();
- }
- }
- }
- public function __isset($name){
- return isset($this->config[$name]);
- }
-
- public function getError(){
- return $this->error;
- }
-
- public function uploadOne($file){
- $info = $this->upload(array($file));
- return $info ? $info[0] : $info;
- }
-
- public function upload($files='') {
- if('' === $files){
- $files = $_FILES;
- }
- if(empty($files)){
- $this->error = '没有上传的文件!';
- return false;
- }
-
- if(!$this->uploader->checkRootPath($this->rootPath)){
- $this->error = $this->uploader->getError();
- return false;
- }
-
- if(!$this->uploader->checkSavePath($this->savePath)){
- $this->error = $this->uploader->getError();
- return false;
- }
-
- $info = array();
- if(function_exists('finfo_open')){
- $finfo = finfo_open ( FILEINFO_MIME_TYPE );
- }
-
- $files = $this->dealFiles($files);
- foreach ($files as $key => $file) {
- $file['name'] = strip_tags($file['name']);
- if(!isset($file['key'])) $file['key'] = $key;
-
- if(isset($finfo)){
- $file['type'] = finfo_file ( $finfo , $file['tmp_name'] );
- }
-
- $file['ext'] = pathinfo($file['name'], PATHINFO_EXTENSION);
-
- if (!$this->check($file)){
- continue;
- }
-
- if($this->hash){
- $file['md5'] = md5_file($file['tmp_name']);
- $file['sha1'] = sha1_file($file['tmp_name']);
- }
-
- $data = call_user_func($this->callback, $file);
- if( $this->callback && $data ){
- if ( file_exists('.'.$data['path']) ) {
- $info[$key] = $data;
- continue;
- }elseif($this->removeTrash){
- call_user_func($this->removeTrash,$data);
- }
- }
-
- $savename = $this->getSaveName($file);
- if(false == $savename){
- continue;
- } else {
- $file['savename'] = $savename;
- }
-
- $subpath = $this->getSubPath($file['name']);
- if(false === $subpath){
- continue;
- } else {
- $file['savepath'] = $this->savePath . $subpath;
- }
-
- $ext = strtolower($file['ext']);
- if(in_array($ext, array('gif','jpg','jpeg','bmp','png','swf'))) {
- $imginfo = getimagesize($file['tmp_name']);
- if(empty($imginfo) || ($ext == 'gif' && empty($imginfo['bits']))){
- $this->error = '非法图像文件!';
- continue;
- }
- }
-
- if ($this->uploader->save($file,$this->replace)) {
- unset($file['error'], $file['tmp_name']);
- $info[$key] = $file;
- } else {
- $this->error = $this->uploader->getError();
- }
- }
- if(isset($finfo)){
- finfo_close($finfo);
- }
- return empty($info) ? false : $info;
- }
-
- private function dealFiles($files) {
- $fileArray = array();
- $n = 0;
- foreach ($files as $key=>$file){
- if(is_array($file['name'])) {
- $keys = array_keys($file);
- $count = count($file['name']);
- for ($i=0; $i<$count; $i++) {
- $fileArray[$n]['key'] = $key;
- foreach ($keys as $_key){
- $fileArray[$n][$_key] = $file[$_key][$i];
- }
- $n++;
- }
- }else{
- $fileArray = $files;
- break;
- }
- }
- return $fileArray;
- }
-
- private function setDriver($driver = null, $config = null){
- $driver = $driver ? : ($this->driver ? : C('FILE_UPLOAD_TYPE'));
- $config = $config ? : ($this->driverConfig ? : C('UPLOAD_TYPE_CONFIG'));
- $class = strpos($driver,'\\')? $driver : 'Think\\Upload\\Driver\\'.ucfirst(strtolower($driver));
- $this->uploader = new $class($config);
- if(!$this->uploader){
- E("不存在上传驱动:{$name}");
- }
- }
-
- private function check($file) {
-
- if ($file['error']) {
- $this->error($file['error']);
- return false;
- }
-
- if (empty($file['name'])){
- $this->error = '未知上传错误!';
- }
-
- if (!is_uploaded_file($file['tmp_name'])) {
- $this->error = '非法上传文件!';
- return false;
- }
-
- if (!$this->checkSize($file['size'])) {
- $this->error = '上传文件大小不符!';
- return false;
- }
-
-
- if (!$this->checkMime($file['type'])) {
- $this->error = '上传文件MIME类型不允许!';
- return false;
- }
-
- if (!$this->checkExt($file['ext'])) {
- $this->error = '上传文件后缀不允许';
- return false;
- }
-
- return true;
- }
-
- private function error($errorNo) {
- switch ($errorNo) {
- case 1:
- $this->error = '上传的文件超过了 php.ini 中 upload_max_filesize 选项限制的值!';
- break;
- case 2:
- $this->error = '上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值!';
- break;
- case 3:
- $this->error = '文件只有部分被上传!';
- break;
- case 4:
- $this->error = '没有文件被上传!';
- break;
- case 6:
- $this->error = '找不到临时文件夹!';
- break;
- case 7:
- $this->error = '文件写入失败!';
- break;
- default:
- $this->error = '未知上传错误!';
- }
- }
-
- private function checkSize($size) {
- return !($size > $this->maxSize) || (0 == $this->maxSize);
- }
-
- private function checkMime($mime) {
- return empty($this->config['mimes']) ? true : in_array(strtolower($mime), $this->mimes);
- }
-
- private function checkExt($ext) {
- return empty($this->config['exts']) ? true : in_array(strtolower($ext), $this->exts);
- }
-
- private function getSaveName($file) {
- $rule = $this->saveName;
- if (empty($rule)) {
-
- $filename = substr(pathinfo("_{$file['name']}", PATHINFO_FILENAME), 1);
- $savename = $filename;
- } else {
- $savename = $this->getName($rule, $file['name']);
- if(empty($savename)){
- $this->error = '文件命名规则错误!';
- return false;
- }
- }
-
- $ext = empty($this->config['saveExt']) ? $file['ext'] : $this->saveExt;
- return $savename . '.' . $ext;
- }
-
- private function getSubPath($filename) {
- $subpath = '';
- $rule = $this->subName;
- if ($this->autoSub && !empty($rule)) {
- $subpath = $this->getName($rule, $filename) . '/';
- if(!empty($subpath) && !$this->uploader->mkdir($this->savePath . $subpath)){
- $this->error = $this->uploader->getError();
- return false;
- }
- }
- return $subpath;
- }
-
- private function getName($rule, $filename){
- $name = '';
- if(is_array($rule)){
- $func = $rule[0];
- $param = (array)$rule[1];
- foreach ($param as &$value) {
- $value = str_replace('__FILE__', $filename, $value);
- }
- $name = call_user_func_array($func, $param);
- } elseif (is_string($rule)){
- if(function_exists($rule)){
- $name = call_user_func($rule);
- } else {
- $name = $rule;
- }
- }
- return $name;
- }
- }
|