fileupload.class.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. <?php
  2. /**
  3. * 文件上传类
  4. *
  5. * 文件上传功能必须使用此类
  6. *
  7. * @createtime 2018/03/01
  8. * @author 空竹
  9. * @copyright 芝麻开发 (http://www.zhimawork.com)
  10. */
  11. // PHP ini中关于上传的限制
  12. // post_max_size 最大post数据大小
  13. // upload_max_filesize搜索 最大能上传多大的文件
  14. class FileUpload{
  15. //允许的后缀
  16. private $allowext = array(
  17. //office
  18. 'doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx',
  19. //压缩包
  20. 'zip', 'rar' , '7z' ,
  21. //文档
  22. 'txt', 'pdf' ,
  23. //图片
  24. 'jpg', 'jpeg', 'gif', 'png',
  25. //音频视频
  26. 'mp3', 'mp4' , 'flv', 'swf'
  27. );
  28. //禁止的后缀
  29. private $forbidext = array(
  30. //程序语言
  31. 'jsp', 'php', 'asp', 'py', 'js', 'css', 'html', 'htm', 'aspx', 'cgi', 'sql', 'c',
  32. //Windows执行文件
  33. 'exe', 'dll', 'com', 'reg', 'bat', 'cmd'
  34. );
  35. private $allowsize = 0;
  36. //构造函数,,,
  37. //allowsize:文件最大值(单位M,形如 8M);$allowext: 数组,可以为空
  38. public function __construct($allowsize = 0, $allowext = array()) {
  39. if(!empty($allowext)) $this->allowext = $allowext;
  40. if(!$allowsize) $allowsize = '8M';
  41. $this->allowsize = $this->getMByte($allowsize);
  42. }
  43. //参数$elename : file域的名称。<input type='file' name='elename'/>
  44. //$newname --上传以后的名字;可以为空。
  45. //$savepath --文件保存路径,一定要以 “/” 结尾。
  46. //$auto_rename 是否自动重命名
  47. //如果$newname 为空 且 auto_rename 为false ,将保留原来的文件名字
  48. function upload($elename, $savepath, $newname = '', $auto_rename = false){
  49. //2016/10/26根据szc的意见修改
  50. if(empty($_FILES[$elename])) throw new Exception('没有上传文件或文件大小超过系统限制', 981);
  51. // $f_name = basename($_FILES[$elename]["name"]); //被上传文件的名称(这种用法错误,因为basename方法不支持中文名)
  52. $f_name = preg_replace('/^.+[\\\\\\/]/', '', $_FILES[$elename]["name"]); //被上传文件的名称
  53. $f_type = $_FILES[$elename]["type"]; //被上传文件的类型
  54. $f_size = $_FILES[$elename]["size"]; //被上传文件的大小,以字节计
  55. $f_tmpname = $_FILES[$elename]["tmp_name"]; //存储在服务器的文件的临时副本的名称
  56. $f_error = $_FILES[$elename]["error"]; //由文件上传导致的错误代码
  57. //是否发生错误
  58. if($f_error) $this->uploadFileError($f_error);
  59. //文件后缀
  60. $f_ext = $this->getFileExt($f_name);
  61. //检查上传类型
  62. //--是否在禁止列表
  63. $forbidext = $this->forbidext;
  64. if(in_array($f_ext, $forbidext)) {
  65. throw new Exception('文件类型禁止上传', 901);
  66. }
  67. //--是否在允许列表
  68. $allowext = $this->allowext;
  69. if(!in_array($f_ext, $allowext)) {
  70. throw new Exception('文件类型未被允许', 902);
  71. }
  72. //文件大小是否允许
  73. $allowsize = $this->allowsize;
  74. if($f_size > $allowsize) {
  75. throw new Exception('文件超过允许的大小', 903);
  76. }
  77. //文件是否是上传的文件
  78. if(!is_uploaded_file($f_tmpname)) {
  79. throw new Exception('非上传的文件', 904);
  80. }
  81. //文件重命名
  82. if(empty($newname) && $auto_rename)
  83. $new_name = $this->setFileNameByDate().'.'.$f_ext;
  84. elseif(!empty($newname))
  85. $new_name = $newname.'.'.$f_ext;
  86. else
  87. $new_name = $f_name;
  88. //保存文件
  89. $f_path = $savepath.$new_name;
  90. if(move_uploaded_file($f_tmpname, $f_path)){
  91. return array('new_name'=>$new_name, 'old_name'=>$f_name);//上传成功,返回文件名。
  92. }else{
  93. throw new Exception('文件写入失败,请检查上传目录是否可写', 905);
  94. }
  95. }
  96. //生成一个日期命名的文件名
  97. private function setFileNameByDate(){
  98. return date('YmdHis').rand(1000,9999);
  99. }
  100. //得到文件的后缀
  101. private function getFileExt($filename){
  102. //return strtolower(preg_replace('/.*\.(.*[^\.].*)*/iU', '\\1', $filename));
  103. $fext = pathinfo($filename, PATHINFO_EXTENSION);
  104. $fext = strtolower($fext);
  105. return $fext;
  106. }
  107. private function uploadFileError($err){
  108. switch($err){
  109. case 0:
  110. $info = '文件上传成功';
  111. break;
  112. case 1:
  113. $info = '文件大小超过了PHP.ini中upload_max_filesize的值('.$this->getMaxFileSize(true).')';
  114. break;
  115. case 2:
  116. $info = '文件大小HTML表单中MAX_FILE_SIZE选项指定的值';
  117. break;
  118. case 3:
  119. $info = '文件未上传完整';
  120. break;
  121. case 4:
  122. $info = '没有文件上传';
  123. break;
  124. case 5:
  125. $info = '文件大小为0';
  126. break;
  127. case 6:
  128. $info = '找不到临时文件夹';
  129. break;
  130. case 7:
  131. $info = '文件写入失败,请检查目录写权限';
  132. break;
  133. default:
  134. $info = '未知的上传错误';
  135. break;
  136. }
  137. throw new Exception($info, $err);
  138. }
  139. //将Byte数变为KB、MB
  140. public function getUploadSizeStr($bytes){
  141. if($bytes > 1048576){
  142. $bytes = $bytes / 1048576;
  143. $bytes = number_format($bytes, 2)."MB";
  144. }else{
  145. $bytes = $bytes / 1024;
  146. $bytes = intval($bytes)."KB";
  147. }
  148. return $bytes;
  149. }
  150. //从例如8M or 8MB 变成字节数
  151. private function getMByte($size){
  152. $size = strtoupper($size);
  153. $size = str_replace('M' , '', $size);
  154. $size = str_replace('MB', '', $size);
  155. $size = trim($size);
  156. $size = $size * 1024 * 1024;
  157. return $size;
  158. }
  159. //get系统最大POST量 ,单位byte
  160. public function getMaxPost($origin = false){
  161. $size = ini_get('post_max_size');
  162. if($origin)
  163. return $size;
  164. else
  165. return $this->getMByte($size);
  166. }
  167. //get系统最大上传,单位byte
  168. public function getMaxFileSize($origin = false){
  169. $size = ini_get('upload_max_filesize');
  170. if($origin)
  171. return $size;
  172. else
  173. return $this->getMByte($size);
  174. }
  175. //get允许的文件后缀
  176. public function getAllowExt(){
  177. return $this->allowext;
  178. }
  179. }
  180. ?>