| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315 | <?php/*** Simple Ajax Uploader* Version 2.6.2* https://github.com/LPology/Simple-Ajax-Uploader** Copyright 2012-2017 LPology, LLC* Released under the MIT license** View the documentation for an example of how to use this class.*/class FileUpload {    private $fileName;                    // Filename of the uploaded file    private $fileSize;                    // Size of uploaded file in bytes    private $fileExtension;               // File extension of uploaded file    private $fileNameWithoutExt;    private $savedFile;                   // Path to newly uploaded file (after upload completed)    private $errorMsg;                    // Error message if handleUpload() returns false (use getErrorMsg() to retrieve)    private $isXhr;    public $uploadDir;                    // File upload directory (include trailing slash)    public $allowedExtensions;            // Array of permitted file extensions    public $sizeLimit = 10485760;         // Max file upload size in bytes (default 10MB)    public $newFileName;                  // Optionally save uploaded files with a new name by setting this    public $corsInputName = 'XHR_CORS_TARGETORIGIN';    public $uploadName = 'uploadfile';    function __construct($uploadName = null) {        if ($uploadName !== null) {            $this->uploadName = $uploadName;        }        if (isset($_FILES[$this->uploadName])) {            $this->isXhr = false;            if ($_FILES[$this->uploadName]['error'] === UPLOAD_ERR_OK) {                $this->fileName = $_FILES[$this->uploadName]['name'];                $this->fileSize = $_FILES[$this->uploadName]['size'];            } else {                $this->setErrorMsg($this->errorCodeToMsg($_FILES[$this->uploadName]['error']));            }        } elseif (isset($_SERVER['HTTP_X_FILE_NAME']) || isset($_GET[$this->uploadName])) {            $this->isXhr = true;            $this->fileName = isset($_SERVER['HTTP_X_FILE_NAME']) ?                                    $_SERVER['HTTP_X_FILE_NAME'] : $_GET[$this->uploadName];            if (isset($_SERVER['CONTENT_LENGTH'])) {                $this->fileSize = (int)$_SERVER['CONTENT_LENGTH'];            } else {                throw new Exception('Content length is empty.');            }        }        if ($this->fileName) {            $this->fileName = $this->sanitizeFilename($this->fileName);            //弃用原生pathinfo(),原因在低版本的php环境下无法正确读取文件名称。            //$pathinfo = pathinfo($this->fileName);            $pathinfo = $this->mb_pathinfo($this->fileName);            if (isset($pathinfo['extension']) &&                isset($pathinfo['filename']))            {                $this->fileExtension = strtolower($pathinfo['extension']);                $this->fileNameWithoutExt = $pathinfo['filename'];            }        }    }    private function sanitizeFilename($name) {        $name = trim($this->basename(stripslashes($name)), ".\x00..\x20");        // Use timestamp for empty filenames        if (!$name) {            $name = str_replace('.', '-', microtime(true));        }        return $name;    }    private function basename($filepath, $suffix = null) {        $splited = preg_split('/\//', rtrim($filepath, '/ '));        return substr(basename('X'.$splited[count($splited)-1], $suffix), 1);    }    private function mb_pathinfo($filepath) {        preg_match('%^(.*?)[\\\\/]*(([^/\\\\]*?)(\.([^\.\\\\/]+?)|))[\\\\/\.]*$%im',$filepath,$m);        if($m[1]) $ret['dirname']=$m[1];        if($m[2]) $ret['basename']=$m[2];        if($m[5]) $ret['extension']=$m[5];        if($m[3]) $ret['filename']=$m[3];        return $ret;    }    public function getFileName() {        return $this->fileName;    }    public function getFileSize() {        return $this->fileSize;    }    public function getFileNameWithoutExt() {        return $this->fileNameWithoutExt;    }    public function getExtension() {        return $this->fileExtension;    }    public function getErrorMsg() {        return $this->errorMsg;    }    public function getSavedFile() {        return $this->savedFile;    }    private function errorCodeToMsg($code) {        switch($code) {            case UPLOAD_ERR_INI_SIZE:                $message = '文件大小超出限制。';                break;            case UPLOAD_ERR_PARTIAL:                $message = '上传的文件只是部分上传。';                break;            case UPLOAD_ERR_NO_FILE:                $message = '没有上传文件。';                break;            case UPLOAD_ERR_NO_TMP_DIR:                $message = '缺少临时文件夹。';                break;            case UPLOAD_ERR_CANT_WRITE:                $message = '无法将文件写入磁盘。';                break;            case UPLOAD_ERR_EXTENSION:                $message = '通过扩展停止文件上传。';                break;            default:                $message = '未知上传错误。';                break;        }        return $message;    }    private function checkExtension($ext, $allowedExtensions) {        if (!is_array($allowedExtensions))            return false;        if (!in_array(strtolower($ext), array_map('strtolower', $allowedExtensions)))            return false;        return true;    }    private function setErrorMsg($msg) {        if (empty($this->errorMsg))            $this->errorMsg = $msg;    }    private function fixDir($dir) {        if (empty($dir))            return $dir;        $slash = DIRECTORY_SEPARATOR;        $dir = str_replace('/', $slash, $dir);        $dir = str_replace('\\', $slash, $dir);        return substr($dir, -1) == $slash ? $dir : $dir . $slash;    }    // escapeJS and jsMatcher are adapted from the Escaper component of    // Zend Framework, Copyright (c) 2005-2013, Zend Technologies USA, Inc.    // https://github.com/zendframework/zf2/tree/master/library/Zend/Escaper    private function escapeJS($string) {        return preg_replace_callback('/[^a-z0-9,\._]/iSu', $this->jsMatcher, $string);    }    private function jsMatcher($matches) {        $chr = $matches[0];        if (strlen($chr) == 1)            return sprintf('\\x%02X', ord($chr));        if (function_exists('iconv'))            $chr = iconv('UTF-16BE', 'UTF-8', $chr);        elseif (function_exists('mb_convert_encoding'))            $chr = mb_convert_encoding($chr, 'UTF-8', 'UTF-16BE');        return sprintf('\\u%04s', strtoupper(bin2hex($chr)));    }    public function corsResponse($data) {        if (isset($_REQUEST[$this->corsInputName])) {            $targetOrigin = $this->escapeJS($_REQUEST[$this->corsInputName]);            $targetOrigin = htmlspecialchars($targetOrigin, ENT_QUOTES, 'UTF-8');            return "<script>window.parent.postMessage('$data','$targetOrigin');</script>";        }        return $data;    }    public function getMimeType($path) {        $finfo = new finfo(FILEINFO_MIME_TYPE);        $fileContents = file_get_contents($path);        $mime = $finfo->buffer($fileContents);        $fileContents = null;        return $mime;    }    public function isWebImage($path) {        $pathinfo = pathinfo($path);        if (isset($pathinfo['extension'])) {            if (!in_array(strtolower($pathinfo['extension']), array('gif', 'png', 'jpg', 'jpeg')))                return false;        }        $type = exif_imagetype($path);        if (!$type)            return false;        return ($type == IMAGETYPE_GIF || $type == IMAGETYPE_JPEG || $type == IMAGETYPE_PNG);    }    private function saveXhr($path) {        if (false !== file_put_contents($path, fopen('php://input', 'r')))            return true;        return false;    }    private function saveForm($path) {        if (move_uploaded_file($_FILES[$this->uploadName]['tmp_name'], $path))            return true;        return false;    }    private function save($path) {        if (true === $this->isXhr)            return $this->saveXhr($path);        return $this->saveForm($path);    }    public function handleUpload($uploadDir = null, $allowedExtensions = null) {        if (!$this->fileName) {            $this->setErrorMsg('上传文件不正确或没有上传文件');            return false;        }        if ($this->fileSize == 0) {            $this->setErrorMsg('文件是空的');            return false;        }        if ($this->fileSize > $this->sizeLimit) {            $this->setErrorMsg('文件大小超出限制');            return false;        }        if (!empty($uploadDir))            $this->uploadDir = $uploadDir;        $this->uploadDir = $this->fixDir($this->uploadDir);        if (!file_exists($this->uploadDir)) {            $this->setErrorMsg('上传目录不存在');            return false;        } else if (!is_writable($this->uploadDir)) {            $this->setErrorMsg('上载目录存在,但不可写。');            return false;        }        if (is_array($allowedExtensions))            $this->allowedExtensions = $allowedExtensions;        if (!empty($this->allowedExtensions)) {            if (!$this->checkExtension($this->fileExtension, $this->allowedExtensions)) {                $this->setErrorMsg('无效的文件类型');                return false;            }        }        $this->savedFile = $this->uploadDir . $this->fileName;        if (!empty($this->newFileName)) {            $this->fileName = $this->newFileName;            $this->savedFile = $this->uploadDir . $this->fileName;            $this->fileNameWithoutExt = null;            $this->fileExtension = null;            $pathinfo = pathinfo($this->fileName);            if (isset($pathinfo['filename']))                $this->fileNameWithoutExt = $pathinfo['filename'];            if (isset($pathinfo['extension']))                $this->fileExtension = strtolower($pathinfo['extension']);        }        if (!$this->save($this->savedFile)) {            $this->setErrorMsg('文件无法保存');            return false;        }        return true;    }}
 |