📄 正在查看:twcms/kongphp/ext/upload.class.php
大小:6,085 字节 · 修改:2014-01-23 01:42:52 · 行数:194
1<?php
2/**
3 * Copyright (C) 2013-2014 www.kongphp.com All rights reserved.
4 * Licensed http://www.gnu.org/licenses/lgpl.html
5 * Author: wuzhaohuan <kongphp@gmail.com>
6 */
7
8class upload{
9 private $config; //上传文件配置 共三个参数 maxSize(允许上传最大文件) | allowExt(允许上传的文件后缀) | upDir(上传保存目录)
10 private $file; //上传文件信息
11 private $upDir; //上传文件根目录
12 private $fileName; //上传原文件名
13 private $fileSize; //上传文件大小
14 private $fileType; //上传文件类型
15 private $fileExt; //上传原扩展名
16 private $filePath; //上传文件保存路径 (不包含 $upDir)
17 private $fileState; //上传文件状态
18 private $isImage; //是否图片
19 private $stateMap = array(
20 '0' => 'SUCCESS',
21 '1' => '文件大小超出 upload_max_filesize 限制',
22 '2' => '文件大小超出 MAX_FILE_SIZE 限制',
23 '3' => '文件未被完整上传',
24 '4' => '没有文件被上传',
25 '5' => '上传文件为空',
26 '6' => '缺少临时文件夹',
27 '7' => '写文件失败',
28 '8' => '上传被其它扩展中断',
29 'POST' => '未接收到 $_POST 数据',
30 'FILES' => '未接收到 $_FILES 数据',
31 'SIZE' => '文件大小超出网站限制',
32 'EXT' => '不允许的扩展名',
33 'DIR' => '目录创建失败',
34 'IO' => '文件写入失败',
35 'UNKNOWN' => '未知错误',
36 'MOVE' => '文件保存时出错'
37 );
38
39 public function __construct($config, $formName, $base64=false) {
40 $this->config = $config;
41 $this->upDir = $config['upDir'];
42 $this->fileState = $this->stateMap[0];
43 $this->upFile($base64, $formName);
44 }
45
46 // 获取当前上传成功文件的各项信息
47 public function getFileInfo() {
48 return array(
49 'state' => $this->fileState,
50 'name' => $this->fileName,
51 'size' => $this->fileSize,
52 'type' => $this->fileType,
53 'ext' => $this->fileExt,
54 'path' => $this->filePath,
55 'isimage' => $this->getIsImage()
56 );
57 }
58
59 // 获取是否是图片文件
60 private function getIsImage() {
61 return in_array($this->fileExt, array('gif', 'jpg', 'jpeg', 'png', 'bmp')) ? 1 : 0; // 1为图片 0为文件
62 }
63
64 // 上传文件
65 private function upFile($base64, $formName) {
66 if('base64' == $base64) {
67 if(empty($_POST[$formName])) {
68 $this->fileState = $this->getFileState('POST');
69 return;
70 }
71 $content = $_POST[$formName];
72 $this->base64ToImage($content);
73 return;
74 }
75
76 if(empty($_FILES[$formName])) {
77 $this->fileState = $this->getFileState('FILES');
78 return;
79 }
80 $this->file = $_FILES[$formName];
81 if($this->file['error']) {
82 $this->fileState = $this->getFileState($this->file['error']);
83 return;
84 }
85 if(!is_uploaded_file($this->file['tmp_name'])) {
86 $this->fileState = $this->getFileState('UNKNOWN');
87 return;
88 }
89
90 $this->fileName = $this->file['name'];
91 $this->fileSize = $this->file['size'];
92 $this->fileType = $this->file['type'];
93 $this->fileExt = $this->getFileExt();
94 if(!$this->checkSize()) {
95 $this->fileState = $this->getFileState('SIZE');
96 return;
97 }
98 if(!$this->checkExt()) {
99 $this->fileState = $this->getFileState('EXT');
100 return;
101 }
102 $dir = date('Ym/d/');
103 $updir = $this->upDir.$dir;
104 if(!is_dir($updir) && !mkdir($updir, 0755, true)) {
105 $this->fileState = $this->getFileState('DIR');
106 return;
107 }
108
109 $this->filePath = $dir.$this->getName();
110 if($this->fileState == $this->stateMap[0]) {
111 if(!move_uploaded_file($this->file['tmp_name'] , $this->upDir.$this->filePath)) {
112 $this->fileState = $this->getFileState('MOVE');
113 }
114 }
115 }
116
117 // 处理base64编码的图片上传
118 private function base64ToImage($base64Data) {
119 $img = base64_decode($base64Data);
120
121 $dir = date('Ym/d/');
122 $updir = $this->upDir.$dir;
123 if(!is_dir($updir) && !mkdir($updir, 0755, true)) {
124 $this->fileState = $this->getFileState('DIR');
125 return;
126 }
127 $this->fileName = '';
128 $this->fileSize = strlen($img);
129 $this->fileType = 'image/png';
130 $this->fileExt = 'png';
131 $this->filePath = $dir.$this->getName();
132 if(!file_put_contents($this->upDir.$this->filePath, $img)) {
133 $this->fileState = $this->getFileState('IO');
134 return;
135 }
136 }
137
138 // 检测上传文件大小是否合格
139 private function checkSize() {
140 return $this->fileSize <= ($this->config['maxSize'] * 1024);
141 }
142
143 // 检测文件类型检测是否合格
144 private function checkExt() {
145 return in_array($this->fileExt, $this->getAllowExt());
146 }
147
148 // 获取允许上传的扩展名
149 private function getAllowExt() {
150 $conf = explode(',', $this->config['allowExt']);
151 $arr = array();
152 foreach($conf as $v) {
153 $v = trim($v);
154 if($v) $arr[] = $v;
155 }
156 return $arr;
157 }
158
159 // 获取上传文件状态
160 private function getFileState($errCode) {
161 return empty($this->stateMap[$errCode]) ? $this->stateMap['UNKNOWN'] : $this->stateMap[$errCode];
162 }
163
164 // 获取新的安全文件名
165 private function getName() {
166 // 白名单后缀,其他文件后缀为 .file
167 // 防XSS漏洞需要注意:IE会解析 .jpg .gif .txt 中的 <script>
168 $Exts = array(
169 'gif', 'jpg', 'jpeg', 'png', 'bmp',
170 'swf', 'fla', 'as',
171 'mp3', 'mp4', 'flv', 'wav', 'wma', 'wmv', 'mid', 'avi', 'mpg', 'asf', 'rm', 'rmvb',
172 'wps', 'doc', 'ppt', 'docx', 'xsl', 'xls', 'xlsx',
173 'zip', 'rar', 'tar', 'tar.gz', 'gz', '7z', 'bz', 'bz2', 'iso',
174 'chm', 'torrent', 'ttf', 'font',
175 );
176 $fileExt = in_array($this->fileExt, $Exts) ? '.'.$this->fileExt : '_'.$this->fileExt.'.file';
177 return date('His').uniqid().$this->random(6).$fileExt;
178 }
179
180 // 获取安全的文件扩展名
181 private function getFileExt() {
182 return preg_replace('/\W/', '', strtolower(substr(strrchr($this->file['name'], '.'), 1, 10)));
183 }
184
185 // 随机字符串
186 private function random($length) {
187 $chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
188 for($i = 0, $max = strlen($chars) - 1, $hash = ''; $i < $length; $i++) {
189 $hash .= $chars[mt_rand(0, $max)];
190 }
191 return $hash;
192 }
193}
194