| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473 |
- <?php
- if (! defined ( 'IS_INITPHP' ))
- exit ( 'Access Denied!' );
- /**
- * *******************************************************************************
- * InitPHP 3.3 国产PHP开发框架 扩展类库-文件上传
- * -------------------------------------------------------------------------------
- * 版权所有: CopyRight By initphp.com
- * 您可以自由使用该源码,但是在使用过程中,请保留作者信息。尊重他人劳动成果就是尊重自己
- * -------------------------------------------------------------------------------
- * $Author:zhuli
- * $Dtime:2013-5-29
- * *********************************************************************************
- */
- class uploadInit {
- const UPLOAD_ERR_INI_SIZE = 1;
- const INPUT_MAX_FILE_SIZE = 2;
- const UPLOAD_HALF = 3;
- const UPLOAD_ERR_NO_TMP_DIR = 4;
- private $params; // 参数
- private $defaultMaxSize = 2048; // 上传文件默认最大值
- private $defaultAllowFileType = array (
- 'gif',
- 'jpeg',
- 'jpg',
- 'png',
- 'bmp',
- 'swf',
- 'txt'
- );
- private $errorCodeArr = array (
- 'upload_error' => - 1, // 上传失败
- 'not_upload_files' => - 2, // 不是通过HTTP POST方法上传
- 'not_an_allowed_type' => - 3, // 不允许的上传类型
- 'file_size_is_large' => - 4, // 文件太大
- 'upload_err_ini_size' => - 5, // 上传文件超过服务器上传限制
- 'input_max_file_size' => - 6, // 上传文件超过表达最大上传限制
- 'upload_half' => - 7, // 只上传了一半文件
- 'upload_err_no_tmp_dir' => - 8, // 上传的临时目录出错
- 'illegal_file_type' => - 9, // 新的文件名,命名不合法
- 'upload_content_error' => - 10 // 上传的内容不合法
- ); // 错误码
-
- /**
- * 上传文件 主函数
- *
- * @param $name 上传文件名
- * @param $newName 新的文件名
- * 不需要类型
- * @param $path 目录
- * @param $params 参数配置
- * @return array
- */
- public function upload($name, $newName, $path, $params = array()) {
- $this->params = $this->parseParams ( $params );
- $uploadInfo = $this->init ( $name, $newName, $path );
- if (! $uploadInfo)
- return $this->error ( 'upload_error' ); // 是否正常上传
- $errorVal = $this->checkUpload ( $uploadInfo ['error'] );
- if ($errorVal !== true)
- return $this->error ( $errorVal ); // 检测上传错误码
- if (! $this->checkIsUploadFile ( $uploadInfo ['tmp_name'] ))
- return $this->error ( 'not_upload_files' ); // 是否通过HTTP POST上传
- $filetype=$this->checkFileType($uploadInfo['tmp_name']);
- if (! $this->checkType ( $filetype))
- return $this->error ( 'not_an_allowed_type' ); // 是否允许上传的类型
- $filetype=$uploadInfo['ext'];
- if (! $this->checkType ( $filetype))
- return $this->error ( 'not_an_allowed_type' ); // 是否允许上传的类型
- if (! $this->checkSize ( $uploadInfo ['size'] ))
- return $this->error ( 'file_size_is_large' ); // 文件大小
- if (! $this->checkNewName ( $newName ))
- return $this->error ( 'illegal_file_type' ); // 新文件名是否合法
- $result = $this->save ( $uploadInfo ['tmp_name'], $uploadInfo ['source'], $uploadInfo ['path'] );
- if ($result == false) {
- return $this->error ( 'upload_error' );
- } else {
- $checkContentResult = $this->checkContent ( $uploadInfo );
- if ($checkContentResult !== true)
- return $this->error ( $checkContentResult ); // 检测上传错误码
- return $uploadInfo;
- }
- }
- /**
- * 读取文件前几个字节 判断文件类型
- *
- * @return string
- */
- function checkFileType($filename) {
- $file = fopen ( $filename, 'rb' );
- $bin = fread ( $file, 2 ); // 只读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 8075:
- $fileType = 'zip';
- break;
- case 7173 :
- $fileType = 'gif';
- break;
- case 6677 :
- $fileType = 'bmp';
- break;
- case 13780 :
- $fileType = 'png';
- break;
- default :
- $fileType = 'unknown' . $typeCode;
- break;
- }
- // Fix
- if ($strInfo ['chars1'] == '-1' && $strInfo ['chars2'] == '-40') {
- return 'jpg';
- }
- if ($strInfo ['chars1'] == '-119' && $strInfo ['chars2'] == '80') {
- return 'png';
- }
- return $fileType;
- }
- /**
- * 参数设置
- *
- * @param array $params
- * array('maxSize' => 文件上传最大,'allowFileType' => 允许上传的文件类型)
- * @return
- *
- */
- public function setParams($params) {
- $this->params = $this->parseParams ( $params );
- }
-
- /**
- * 装载上传文件的信息
- *
- * @param string $name
- * 上传文件名
- * @return array
- */
- private function init($name, $newName, $path) {
- $newName = $this->escapeStr ( $newName );
- $path = $this->escapeDir ( $path );
- $file = $_FILES [$name];
- if (! $file ['tmp_name'] || $file ['tmp_name'] == '')
- return false;
- $file ['name'] = $this->escapeStr ( $file ['name'] );
- $file ['ext'] = strtolower ( substr ( strrchr ( $file ['name'], '.' ), 1 ) );
- $file ['size'] = intval ( $file ['size'] );
- $file ['type'] = $file ['type'];
- $file ['tmp_name'] = $file ['tmp_name'];
- $file ['source'] = $path . '/' . $newName . '.' . $file ['ext']; // 路径
- $file ['path'] = $path; // 目录
- $file ['newName'] = $newName . '.' . $file ['ext']; // 文件名
- return $file;
- }
-
- /**
- * 参数处理
- *
- * @param array $params
- * 文件上传配置参数
- * @return
- *
- */
- private function parseParams(array $params) {
- $temp = array ();
- $temp ['maxSize'] = (isset ( $params ['maxSize'] )) ? ( int ) $params ['maxSize'] : $this->defaultMaxSize;
- $temp ['allowFileType'] = (is_array ( $params ['allowFileType'] )) ? $params ['allowFileType'] : $this->defaultAllowFileType;
- return $temp;
- }
-
- /**
- * 保存文件
- *
- * @param $name 上传文件名
- * @param $newName 新的文件名
- * 1
- * @param $path 目录
- * @return bool
- */
- private function save($tmpName, $filename, $path) {
- $this->createFolder ( $path ); // 创建目录
- if (function_exists ( "move_uploaded_file" ) && @move_uploaded_file ( $tmpName, $filename )) {
- @chmod ( $filename, 0777 );
- return true;
- } elseif (@copy ( $tmpName, $filename )) {
- @chmod ( $filename, 0777 );
- return true;
- }
- return false;
- }
-
- /**
- * 错误码检测
- *
- * @param int $error
- * 错误状态
- * @return string
- */
- private function checkUpload($error) {
- if ($error == uploadInit::UPLOAD_ERR_INI_SIZE) { // 上传是否超过ini设置
- return 'upload_err_ini_size';
- } elseif ($error == uploadInit::INPUT_MAX_FILE_SIZE) { // 上传是否超过表单设置
- return 'input_max_file_size';
- } elseif ($error == uploadInit::UPLOAD_HALF) { // 上传一半
- return 'upload_half';
- } elseif ($error == uploadInit::UPLOAD_ERR_NO_TMP_DIR) { // 上传临时目录创建错误
- return 'upload_err_no_tmp_dir';
- } else {
- return true;
- }
- }
-
- /**
- * 文件类型检测
- *
- * @param string $uploadType
- * 类型
- * @return bool
- */
- private function checkType($uploadType) {
- return (empty ( $uploadType ) || ! in_array ( $uploadType, $this->params ['allowFileType'] )) ? false : true;
- }
-
- /**
- * 文件大小检测
- *
- * @param int $uploadSize
- * 大小
- * @return bool
- */
- private function checkSize($uploadSize) {
- return ($uploadSize < 1 || $uploadSize > ($this->params ['maxSize'] * 1024)) ? false : true;
- }
-
- /**
- * 检测新的文件名
- *
- * @param string $newName
- * 新文件名
- * @return bool
- */
- private function checkNewName($newName) {
- $newName = strtolower ( $newName );
- return (strpos ( $newName, '..' ) !== false || strpos ( $newName, '.php.' ) !== false || eregi ( "\.php$", $newName )) ? false : true;
- }
-
- /**
- * 检测是否是上传的文件
- *
- * @param $tmpName 临时文件名
- * @return bool
- */
- private function checkIsUploadFile($tmpName) {
- if (! $tmpName || $tmpName == 'none') {
- return false;
- } elseif (function_exists ( 'is_uploaded_file' ) && ! is_uploaded_file ( $tmpName ) && ! is_uploaded_file ( str_replace ( '\\\\', '\\', $tmpName ) )) {
- return false;
- } else {
- return true;
- }
- }
-
- /**
- * 文件上传后检测文件内容是否合法
- *
- * @param string $uploadInfo
- * 文件信息
- * @param string $source
- * 文件源目录
- * @return bool
- */
- private function checkContent($uploadInfo) {
- if ($uploadInfo ['ext'] == 'txt') {
- if (preg_match ( '/(onload|submit|post|form)/i', $this->readover ( $uploadInfo ['source'] ) )) {
- @unlink ( $uploadInfo ['source'] );
- return 'upload_content_error';
- }
- } elseif (in_array ( $uploadInfo ['ext'], array (
- 'gif',
- 'jpg',
- 'jpeg',
- 'png',
- 'bmp',
- 'swf'
- ) )) {
- if (! $img_size = $this->getImgSize ( $uploadInfo ['source'], $uploadInfo ['ext'] )) {
- @unlink ( $uploadInfo ['source'] );
- return 'upload_content_error';
- }
- }
- return true;
- }
-
- /**
- * 创建目录 如果目录存在,则不创建,不存在则创建 static
- *
- * @param $path 路径
- * @return
- *
- */
- public static function createFolder($path) {
- if (! is_dir ( $path )) {
- uploadInit::createFolder ( dirname ( $path ) );
- @mkdir ( $path );
- @chmod ( $path, 0777 );
- @fclose ( @fopen ( $path . '/index.html', 'w' ) );
- @chmod ( $path . '/index.html', 0777 );
- }
- }
-
- /**
- * 读取文件
- *
- * @param string $fileName
- * 文件绝对路径
- * @param string $method
- * 读取模式
- */
- private function readover($fileName, $method = 'rb') {
- $fileName = $this->escapePath ( $fileName );
- $data = '';
- if ($handle = @fopen ( $fileName, $method )) {
- flock ( $handle, LOCK_SH );
- $data = @fread ( $handle, filesize ( $fileName ) );
- fclose ( $handle );
- }
- return $data;
- }
-
- /**
- * 获取图片的大小
- *
- * @param string $srcFile
- * 图片地址
- * @param string $srcExt
- * 图片类型
- * @return
- *
- */
- private function getImgSize($srcFile, $srcExt = null) {
- empty ( $srcExt ) && $srcExt = strtolower ( substr ( strrchr ( $srcFile, '.' ), 1 ) );
- $srcdata = array ();
- if (function_exists ( 'read_exif_data' ) && in_array ( $srcExt, array (
- 'jpg',
- 'jpeg',
- 'jpe',
- 'jfif'
- ) )) {
- $datatemp = @read_exif_data ( $srcFile );
- $srcdata ['width'] = $datatemp ['COMPUTED'] ['Width'];
- $srcdata ['height'] = $datatemp ['COMPUTED'] ['Height'];
- $srcdata ['type'] = 2;
- unset ( $datatemp );
- }
- ! $srcdata ['width'] && list ( $srcdata ['width'], $srcdata ['height'], $srcdata ['type'] ) = @getimagesize ( $srcFile );
- if (! $srcdata ['type'] || ($srcdata ['type'] == 1 && in_array ( $srcExt, array (
- 'jpg',
- 'jpeg',
- 'jpe',
- 'jfif'
- ) ))) { // noizy fix
- return false;
- }
- return $srcdata;
- }
-
- /**
- * 字符转换
- *
- * @param string $string
- * 转换的字符串
- * @return string 返回转换后的字符串
- */
- private function escapeStr($string) {
- $string = str_replace ( array (
- "\0",
- "%00",
- "\r"
- ), '', $string );
- $string = preg_replace ( array (
- '/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F]/',
- '/&(?!(#[0-9]+|[a-z]+);)/is'
- ), array (
- '',
- '&'
- ), $string );
- $string = str_replace ( array (
- "%3C",
- '<'
- ), '<', $string );
- $string = str_replace ( array (
- "%3E",
- '>'
- ), '>', $string );
- $string = str_replace ( array (
- '"',
- "'",
- "\t",
- ' '
- ), array (
- '"',
- ''',
- ' ',
- ' '
- ), $string );
- return $string;
- }
-
- /**
- * 目录转换
- *
- * @param string $dir
- * @return string
- */
- private function escapeDir($dir) {
- $dir = str_replace ( array (
- "'",
- '#',
- '=',
- '`',
- '$',
- '%',
- '&',
- ';'
- ), '', $dir );
- return rtrim ( preg_replace ( '/(\/){2,}|(\\\){1,}/', '/', $dir ), '/' );
- }
-
- /**
- * 私用路径转换
- *
- * @param
- * $fileName
- * @param
- * $ifCheck
- * @return boolean
- */
- private function escapePath($fileName, $ifCheck = true) {
- $tmpname = strtolower ( $fileName );
- $tmparray = array (
- '://',
- "\0"
- );
- $ifCheck && $tmparray [] = '..';
- if (str_replace ( $tmparray, '', $tmpname ) != $tmpname) {
- return false;
- }
- return true;
- }
-
- /**
- * 上传错误提示
- *
- * @param unknown_type $msgType
- */
- private function error($errorCode) {
- return $this->errorCodeArr [$errorCode];
- }
- }
|