data = $data; $this->config = $config; } public function getData() { return $this->data; } /** * 获取根目录 * * @return mixed */ protected function root() { if (!$this->base) { $path = Config::data(); $this->base = Dever::path($path . 'upload/'); } return $this->base; } /** * 验证数据 * * @return mixed */ private function check($param) { foreach ($param as $k => $v) { $method = 'check_' . $v; $this->$method(); if ($this->output['status'] == -1) { break; } } } /** * 验证key是否包含有后续处理的方法 * * @return mixed */ private function check_handle() { if (isset($this->data['key']) && strpos($this->data['key'], '_') !== false) { $temp = explode('_', $this->data['key']); $this->data['key'] = $temp[0]; unset($temp[0]); foreach ($temp as $k => $v) { $this->handle[] = explode('=', $v); } } } /** * 验证文件是否存在 * * @return mixed */ private function check_file() { if ($this->data['file']['tmp_name'] == '') { $this->output['status'] = -1; $this->output['message'] = '没有选择文件'; } } /** * 验证基本配置 * * @return mixed */ private function check_key() { if (trim($this->data['key']) == '') { $this->output['status'] = -1; $this->output['message'] = '请添加配置key'; } /* else { $this->config = Dever::load('upload/upload-one', $this->data['key']); if (!$this->config) { $this->output['status'] = -1; $this->output['message'] = '此配置不存在'; } } */ } /** * 验证文件类型 * * @return mixed */ private function check_type() { if (!$this->ext) { $ext = $this->getExt($this->data['file']['tmp_name']); if (strpos($this->config['type'], $ext) === false) { $this->output['status'] = -1; $this->output['message'] = '文件格式不符合要求'; } $this->ext = '.' . $ext; } } /** * 验证文件大小 * * @return mixed */ private function check_size() { if (!$this->limit && !$this->base64 && ($this->ext == '.jpg' || $this->ext == '.gif' || $this->ext == '.png') && !strstr($this->data['file']['tmp_name'], 'http')) { $this->limit = getimagesize($this->data['file']['tmp_name']); } if (isset($this->data['file']['size'])) { $this->size = $this->data['file']['size']; $this->limit(); } } protected function limit() { # 默认30M $size = $this->config['size'] > 0 ? 1024*1024*$this->config['size'] : 30*1024*1024; if (($size < $this->size) && $size > 0) { $this->output['status'] = -1; $this->output['message'] = '文件不能超过'.$this->config['size'].'MB'; } elseif ($this->limit) { if (isset($this->config['setwh']) && $this->config['setwh'] == 2 && $this->limit[0] < $this->limit[1]) { $this->output['status'] = -1; $this->output['message'] = '图片高度不能超过图片宽度'; } elseif (isset($this->config['setwh']) && $this->config['setwh'] == 3 && $this->limit[0] > $this->limit[1]) { $this->output['status'] = -1; $this->output['message'] = '图片宽度不能超过图片高度'; } elseif ($this->config['width'] > 0 && $this->config['width'] > $this->limit[0]) { $this->output['status'] = -1; $this->output['message'] = '图片宽度不能小于' . $this->config['width'] . 'px'; } elseif ($this->config['height'] > 0 && $this->config['height'] > $this->limit[1]) { $this->output['status'] = -1; $this->output['message'] = '图片高度不能小于' . $this->config['height'] . 'px'; } } $this->size = number_format($this->size/1024, 2); } /** * 上传操作 * * @return mixed */ public function copy() { $this->output['status'] = 1; if (is_string($this->data['file'])) { if (strstr($this->data['file'], 'base64,')) { $temp = explode('base64,', $this->data['file']); $type = str_replace(array('data:', ';'), '', $temp[0]); $file = str_replace(' ', '+', $temp[1]); $file = str_replace('=', '', $temp[1]); $file = base64_decode($file); if (isset($this->data['pic'])) { $name = $this->data['local'] = Dever::local($this->data['pic']); } else { $name = Dever::rand(10); } $size = strlen($file); //$size = number_format(($size - ($size/8)*2)/1024, 2); $size = round(($size - ($size/8)*2)/1024, 2); $this->base64 = true; } elseif (strstr($this->data['file'], 'content,')) { $file = str_replace('content,', '', $this->data['file']); $this->data['content'] = true; } else { $name = urldecode($this->data['file']); } $this->data['file'] = array(); if (isset($this->data['content']) || (!isset($this->data['cropper']) && strstr($name, 'http') && !$this->yun)) { $this->base64 = false; $this->root(); //header('Content-type: text/json; charset=utf-8'); $path = Dever::path($this->base, 'tmp/'); $filename = $name; if (strstr($filename, '?')) { $temp = explode('?', $filename); $filename = $temp[0]; } if (isset($this->data['ext']) && $this->data['ext']) { $this->ext = '.' . $this->data['ext']; } else { $this->ext = '.' . pathinfo($filename, PATHINFO_EXTENSION); } if (isset($this->data['name']) && $this->data['name']) { $this->data['file']['name'] = 'Tmp' . sha1($this->data['name']); } else { $this->data['file']['name'] = 'Tmp' . sha1($filename); } $this->data['file']['tmp_name'] = $path . $this->data['file']['name']; if (!is_file($this->data['file']['tmp_name'])) { if (strstr($name, 'tp=webp')) { $name = str_replace('tp=webp', 'tp=jpeg', $name); } elseif (strstr($name, '.webp')) { $name = str_replace('.webp', '.jpg', $name); } if (!isset($file)) { $file = Dever::curl($name); } if ($this->ext != '.mp4' && stristr($file, 'webp')) { # 将webp图片转成jpg $this->ext = '.jpg'; } if (!isset($file)) { $this->output['status'] = -1; $this->output['message'] = '错误的文件来源'; return $this->output; } $state = file_put_contents($this->data['file']['tmp_name'], $file); if (!$state) { $this->delete(); return $this->output; } } $this->data['file']['size'] = filesize($this->data['file']['tmp_name']); if ($this->data['file']['size'] <= 0) { $this->delete(); return $this->output; } } elseif (isset($file)) { $this->data['file']['name'] = $name; $this->data['file']['tmp_name'] = $file; } else { $this->data['file']['name'] = $name; $this->data['file']['tmp_name'] = $name; } if (isset($type)) { $this->data['file']['type'] = $type; } if (isset($size)) { $this->data['file']['size'] = $size; } if (isset($this->data['param'])) { $this->limit = array($this->data['param']['param_w'], $this->data['param']['param_h']); if (isset($this->data['name'])) { $param = implode('_', array_values($this->data['param'])); $this->data['file']['name'] = '.' . $this->data['name'] . $param; if ($this->base64) { $this->data['name'] = $this->data['file']['name']; } else { $filename = md5($this->data['pic']) . '.' . pathinfo($this->data['pic'], PATHINFO_EXTENSION); $this->path(); $file = Dever::path($this->base . $this->data['key'] . $this->path, $filename); if (!is_file($file)) { $content = Dever::curl($name); file_put_contents($file, $content); } $this->data['name'] = $filename . $this->data['file']['name']; } $this->ext = '.jpg'; } } } else { header("Content-type: application/json; charset=utf-8"); } $this->check(array('handle', 'file', 'key', 'type', 'size')); if ($this->output['status'] == -1) { $this->delete(); return $this->output; } $this->save(); if ($this->output['status'] == -1) { return $this->output; } if (isset($this->handle) && is_array($this->handle)) { foreach ($this->handle as $k => $v) { $method = 'handle_' . $v[0]; if (method_exists($this, $method)) { $this->$method($v); } $this->$method($v[1]); } } elseif (isset($this->config['alter']) && $this->config['alter']) { parse_str($this->config['alter'], $handle); if ($handle) { foreach ($handle as $k => $v) { $method = 'handle_' . $k; if (method_exists($this, $method)) { $this->$method($v); } } } } $this->output['ext'] = $this->ext; $this->output['uploaded'] = true; $this->output['status'] = 1; $this->output['name'] = $this->name; $this->output['source_name'] = $this->data['file']['name']; $this->output['fid'] = $this->id; if ($this->limit) { $this->output['width'] = $this->limit[0]; $this->output['height'] = $this->limit[1]; } if ($this->size) { $this->output['size'] = $this->size; } return $this->output; } protected function update($id) { $param['set_name'] = $this->name; $param['set_source_name'] = $this->data['file']['name']; $param['set_file'] = $this->file; $param['set_key'] = md5($this->output['url']); $param['set_ext'] = $this->ext; if (isset($this->data['cate'])) { $param['set_cate'] = $this->data['cate']; } if ($this->limit) { $param['set_width'] = $this->limit[0]; $param['set_height'] = $this->limit[1]; } if ($this->size) { $param['set_size'] = $this->size; } if (isset($this->data['search']) && $this->data['search']) { $param['search'] = $this->data['search']; } $this->id = $param['where_id'] = $id; Dever::db('upload/file')->update($param); } protected function insert() { $param['add_name'] = $this->name; $param['add_source_name'] = $this->data['file']['name']; $param['add_file'] = $this->file; $param['add_key'] = md5($this->output['url']); $param['add_ext'] = $this->ext; $param['add_upload'] = $this->data['key']; if (isset($this->data['cate'])) { $param['add_cate'] = $this->data['cate']; } if ($this->limit) { $param['add_width'] = $this->limit[0]; $param['add_height'] = $this->limit[1]; } if ($this->size) { $param['add_size'] = $this->size; } $param['add_state'] = 1; //file_put_contents(DEVER_PATH . 'data/test', var_export($param,true)); if (isset($this->data['search']) && $this->data['search']) { $param['search'] = $this->data['search']; } $this->id = Dever::db('upload/file')->insert($param); } protected function img() { $this->img = isset($this->img) ? $this->img : new Img(); $this->img->setType('im'); return $this->img; } protected function getName() { $this->name($this->data['file']['name'])->path()->ext()->file(); } protected function path() { # 覆盖原文件 检查文件是否存在 $this->path = ''; if ($this->config['cover'] == 1) { $info = Dever::db('upload/file')->one(array('name' => $this->name, 'upload' => $this->data['key'])); if ($info && $info['file'] && strstr($info['file'], $this->name)) { # 如果存在,直接使用旧文件 if (strstr($info['file'], 'http')) { $config = parse_url($info['file']); } else { $config['path'] = $info['file']; } $temp = explode($this->name, $config['path']); $this->path = ltrim($temp[0], '/'); } } if (!$this->path) { $date = explode('-', date("Y-m-d")); if (isset($this->data['id']) && $this->data['id']) { $this->path = $this->config['id'] . '/' . Dever::pathId($this->data['id']); } else { $this->path = $this->config['id'] . '/' . $date[0] . '/' . $date[1] . '/' . $date[2] . '/'; } } return $this; } protected function name($name) { if (isset($this->data['name'])) { $this->name = $this->data['name']; } else { $this->name = md5($name); } return $this; } protected function ext() { $this->ext = $this->ext ? $this->ext : '.' . pathinfo($this->data['file']['name'], PATHINFO_EXTENSION); if ($this->ext == '.') { $this->ext = '.jpg'; } return $this; } protected function yun() { $yun = $this->config['yun']; $this->host = $yun['host']; $this->data['host'] = $this->host; $this->getName(); $file = $this->file; if ($this->config['cover'] == 3) { $this->name($this->output['file'] . '_' . microtime() . '_' . rand(0,1000))->file(); $file = $this->file; } return array($yun, $file); } /** * getExt * * @return mixed */ protected function getExt($filename) { if (strstr($filename, 'http')) { $temp = explode('.', $filename); $ext = $temp[count($temp)-1]; } elseif (isset($this->data['file']['type'])) { $ext = $this->getExtByMine($this->data['file']['type']); } elseif (function_exists('finfo_open')) { $finfo = finfo_open(FILEINFO_MIME); // 返回 mime 类型 $code = finfo_file($finfo, $filename); finfo_close($finfo); $temp = explode(';', $code); $ext = $this->getExtByMine($temp[0]); } else { $ext = $this->getExtByByte($filename); } if (!$ext || $ext == 'txt' || $ext == 'exe') { if (isset($this->data['file']['type'])) { $ext = $this->getExtByMine($this->data['file']['type']); } if (!$ext || $ext == 'txt' || $ext == 'exe') { $ext = $this->getExtByByte($filename); } } return $ext; } public function delete() { @unlink($this->data['file']['tmp_name']); } /** * 根据mime类型获取文件扩展名 * * @return mixed */ protected function getExtByMine($mine) { $mine = trim($mine); $config = array ( 'application/envoy' => 'evy', 'application/fractals' => 'fif', 'application/futuresplash' => 'spl', 'application/hta' => 'hta', 'application/internet-property-stream' => 'acx', 'application/mac-binhex40' => 'hqx', 'application/msword' => 'doc', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'xlsx', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 'docx', 'video/x-m4v' => 'mp4', 'video/mp4' => 'mp4', 'application/octet-stream' => 'exe', 'application/oda' => 'oda', 'application/olescript' => 'axs', 'application/pdf' => 'pdf', 'application/pics-rules' => 'prf', 'application/pkcs10' => 'p10', 'application/pkix-crl' => 'crl', 'application/postscript' => 'ai', 'application/postscript' => 'eps', 'application/postscript' => 'ps', 'application/rtf' => 'rtf', 'application/set-payment-initiation' => 'setpay', 'application/set-registration-initiation' => 'setreg', 'application/vnd.ms-excel' => 'xls', 'application/vnd.ms-outlook' => 'msg', 'application/vnd.ms-pkicertstore' => 'sst', 'application/vnd.ms-pkiseccat' => 'cat', 'application/vnd.ms-pkistl' => 'stl', 'application/vnd.ms-powerpoint' => 'ppt', 'application/vnd.ms-project' => 'mpp', 'application/vnd.ms-works' => 'wps', 'application/winhlp' => 'hlp', 'application/x-bcpio' => 'bcpio', 'application/x-cdf' => 'cdf', 'application/x-compress' => 'z', 'application/x-compressed' => 'tgz', 'application/x-cpio' => 'cpio', 'application/x-csh' => 'csh', 'application/x-director' => 'dir', 'application/x-dvi' => 'dvi', 'application/x-gtar' => 'gtar', 'application/x-gzip' => 'gz', 'application/x-hdf' => 'hdf', 'application/x-internet-signup' => 'isp', 'application/x-iphone' => 'iii', 'application/x-javascript' => 'js', 'application/x-latex' => 'latex', 'application/x-msaccess' => 'mdb', 'application/x-mscardfile' => 'crd', 'application/x-msclip' => 'clp', 'application/x-msdownload' => 'dll', 'application/x-msmediaview' => 'mvb', 'application/x-msmetafile' => 'wmf', 'application/x-msmoney' => 'mny', 'application/x-mspublisher' => 'pub', 'application/x-msschedule' => 'scd', 'application/x-msterminal' => 'trm', 'application/x-mswrite' => 'wri', 'application/x-netcdf' => 'cdf', 'application/x-netcdf' => 'nc', 'application/x-perfmon' => 'pma', 'application/x-pkcs12' => 'p12', 'application/x-pkcs12' => 'pfx', 'application/x-pkcs7-certificates' => 'p7b', 'application/x-pkcs7-certreqresp' => 'p7r', 'application/x-pkcs7-mime' => 'p7c', 'application/x-pkcs7-signature' => 'p7s', 'application/x-sh' => 'sh', 'application/x-shar' => 'shar', 'application/x-shockwave-flash' => 'swf', 'application/x-stuffit' => 'sit', 'application/x-sv4cpio' => 'sv4cpio', 'application/x-sv4crc' => 'sv4crc', 'application/x-tar' => 'tar', 'application/x-tcl' => 'tcl', 'application/x-tex' => 'tex', 'application/x-texinfo' => 'texi', 'application/x-texinfo' => 'texinfo', 'application/x-troff' => 'roff', 'application/x-troff' => 't', 'application/x-troff' => 'tr', 'application/x-troff-man' => 'man', 'application/x-troff-me' => 'me', 'application/x-troff-ms' => 'ms', 'application/x-ustar' => 'ustar', 'application/x-wais-source' => 'src', 'application/x-x509-ca-cert' => 'cer', 'application/ynd.ms-pkipko' => 'pko', 'application/zip' => 'zip', 'audio/basic' => 'au', 'audio/basic' => 'snd', 'audio/mid' => 'mid', 'audio/mid' => 'rmi', 'audio/mpeg' => 'mp3', 'audio/mp3' => 'mp3', 'audio/x-aiff' => 'aif', 'audio/x-aiff' => 'aifc', 'audio/x-aiff' => 'aiff', 'audio/x-mpegurl' => 'm3u', 'audio/x-pn-realaudio' => 'ram', 'audio/x-wav' => 'wav', 'image/png' => 'png', 'image/bmp' => 'bmp', 'image/cis-cod' => 'cod', 'image/gif' => 'gif', 'image/ief' => 'ief', 'image/jpeg' => 'jpg', 'image/pipeg' => 'jfif', 'image/svg+xml' => 'svg', 'image/tiff' => 'tif', 'image/tiff' => 'tiff', 'image/x-cmu-raster' => 'ras', 'image/x-cmx' => 'cmx', 'image/x-icon' => 'ico', 'image/x-portable-anymap' => 'pnm', 'image/x-portable-bitmap' => 'pbm', 'image/x-portable-graymap' => 'pgm', 'image/x-portable-pixmap' => 'ppm', 'image/x-rgb' => 'rgb', 'image/x-xbitmap' => 'xbm', 'image/x-xpixmap' => 'xpm', 'image/x-xwindowdump' => 'xwd', 'message/rfc822' => 'mht', 'message/rfc822' => 'mhtml', 'message/rfc822' => 'nws', 'text/css' => 'css', 'text/h323' => '323', 'text/html' => 'html', 'text/iuls' => 'uls', 'text/plain' => 'txt', 'text/richtext' => 'rtx', 'text/scriptlet' => 'sct', 'text/tab-separated-values' => 'tsv', 'text/webviewhtml' => 'htt', 'text/x-component' => 'htc', 'text/x-setext' => 'etx', 'text/x-vcard' => 'vcf', 'video/mpeg' => 'mpeg', 'video/quicktime' => 'mov', 'video/x-ms-asf' => 'asx', 'video/x-msvideo' => 'avi', 'video/x-sgi-movie' => 'movie', 'x-world/x-vrml' => 'flr', 'application/x-rar' => 'rar', 'application/vnd.android.package-archive' => 'apk', 'audio/webm' => 'webm', 'video/webm' => 'webm', 'audio/x-m4a' => 'm4a', 'image/webp' => 'webp', ); if (isset($config[$mine])) { return $config[$mine]; } else { return false; } } /** * getExt * * @return mixed */ protected function getExtByByte($filename) { $file = fopen($filename,"rb"); $bin = fread($file,2); fclose($file); $strInfo = @unpack("c2chars",$bin); $typeCode = intval($strInfo['chars1'].$strInfo['chars2']); $fileType = ''; switch ($typeCode) { case 7790: $fileType = 'exe'; break; case 7784: $fileType = 'midi'; break; case 8297: $fileType = 'rar'; break; case 255216: $fileType = 'jpg'; break; case 7173: $fileType = 'gif'; break; case 13780: $fileType = 'png'; break; case 6677: $fileType = 'bmp'; break; case 6787: $fileType = 'swf'; break; case 6063; $fileType = 'php|xml'; break; case 6033: $fileType = 'html|htm|shtml'; break; case 8075: $fileType = 'zip'; break; case 6782: case 1310: $fileType = 'txt'; break; case 4742: $fileType = 'js'; break; case 8273: $fileType = 'wav'; break; case 7368: $fileType = 'mp3'; break; case 3780: $fileType = 'pdf'; break; case 4545: $fileType = 'pem'; break; case 7597: $fileType = 'fbx'; break; default: $fileType = 'unknown'.$typeCode; break; } if ($strInfo['chars1'] == '-1' && $strInfo['chars2'] == '-40') { return 'jpg'; } if ($strInfo['chars1'] == '-119' && $strInfo['chars2'] == '80') { return 'png'; } if ($strInfo['chars1'] == '-48' && $strInfo['chars2'] == '-49') { return 'msi'; } return $fileType; } }