[ /* 文件上传的根目录 */ //'rootPath' => $_SERVER['DOCUMENT_ROOT'], /* 上传图片配置项 */ "imageActionName" => "uploadimage", /* 执行上传图片的action名称 */ "imageFieldName" => "file", /* 提交的图片表单名称 */ "imageMaxSize" => 20480000, /* 上传大小限制,单位B */ "imageAllowFiles" => [ ".png", ".jpg", ".jpeg", ".gif", ".ico", ".bmp" ], /* 上传图片格式显示 */ "imageCompressEnable" => true, /* 是否压缩图片,默认是true */ "imageCompressBorder" => 800, /* 图片压缩最长边限制 */ "imageInsertAlign" => "none", /* 插入的图片浮动方式 */ "imageUrlPrefix" => "", /* 图片访问路径前缀 */ "imagePathFormat" => "/upload/image/{yyyy}/{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */ /* {filename} 会替换成原文件名,配置这项需要注意中文乱码问题 */ /* {rand:6} 会替换成随机数,后面的数字是随机数的位数 */ /* {time} 会替换成时间戳 */ /* {yyyy} 会替换成四位年份 */ /* {yy} 会替换成两位年份 */ /* {mm} 会替换成两位月份 */ /* {dd} 会替换成两位日期 */ /* {hh} 会替换成两位小时 */ /* {ii} 会替换成两位分钟 */ /* {ss} 会替换成两位秒 */ /* 非法字符 \ => * ? " < > | */ /* 具请体看线上文档=> fex.baidu.com/ueditor/#use-format_upload_filename */ /* 涂鸦图片上传配置项 */ "scrawlActionName" => "uploadscrawl", /* 执行上传涂鸦的action名称 */ "scrawlFieldName" => "file", /* 提交的图片表单名称 */ "scrawlPathFormat" => "/upload/image/{yyyy}/{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */ "scrawlMaxSize" => 2048000, /* 上传大小限制,单位B */ "scrawlUrlPrefix" => "", /* 图片访问路径前缀 */ "scrawlInsertAlign" => "none", /* 截图工具上传 */ "snapscreenActionName" => "uploadimage", /* 执行上传截图的action名称 */ "snapscreenPathFormat" => "/upload/image/{yyyy}/{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */ "snapscreenUrlPrefix" => "", /* 图片访问路径前缀 */ "snapscreenInsertAlign" => "none", /* 插入的图片浮动方式 */ /* 抓取远程图片配置 */ "catcherLocalDomain" => [ "127.0.0.1", "localhost", "img.baidu.com" ], "catcherActionName" => "catchimage", /* 执行抓取远程图片的action名称 */ "catcherFieldName" => "source", /* 提交的图片列表表单名称 */ "catcherPathFormat" => "/upload/image/{yyyy}/{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */ "catcherUrlPrefix" => "", /* 图片访问路径前缀 */ "catcherMaxSize" => 2048000, /* 上传大小限制,单位B */ "catcherAllowFiles" => [ ".png", ".jpg", ".jpeg", ".gif", ".ico", ".bmp" ], /* 抓取图片格式显示 */ /* 上传视频配置 */ "videoActionName" => "uploadvideo", /* 执行上传视频的action名称 */ "videoFieldName" => "file", /* 提交的视频表单名称 */ "videoPathFormat" => "/upload/video/{yyyy}/{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */ "videoUrlPrefix" => "", /* 视频访问路径前缀 */ "videoMaxSize" => 5120000, /* 上传大小限制,单位B,默认100MB */ "videoAllowFiles" => [ ".flv", // ".swf", // ".mkv", // ".avi", // ".rm", ".rmvb", ".mpeg", ".mpg", // ".ogg", // ".ogv", // ".mov", ".wmv", ".mp4", // ".webm", ".mp3", ".wav", // ".mid" ], /* 上传视频格式显示 */ /* 上传文件配置 */ "fileActionName" => "uploadfile", /* controller里,执行上传视频的action名称 */ "fileFieldName" => "file", /* 提交的文件表单名称 */ "filePathFormat" => "/upload/file/{yyyy}/{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */ "fileUrlPrefix" => "", /* 文件访问路径前缀 */ "fileMaxSize" => 51200000, /* 上传大小限制,单位B,默认50MB */ "fileAllowFiles" => [ ".png", ".jpg", ".jpeg", ".gif", ".ico", ".bmp", ".flv", //".swf", //".mkv", ".avi", //".rm", ".rmvb", //".mpeg", //".mpg", ".ogg", //".ogv", //".mov", ".wmv", ".mp4", //".webm", ".mp3", ".wav", //".mid", ".rar", ".zip", //".tar", //".gz", //".7z", //".bz2", //".cab", //".iso", ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml" ], /* 上传文件格式显示 */ /* 列出指定目录下的图片 */ "imageManagerActionName" => "listimage", /* 执行图片管理的action名称 */ "imageManagerListPath" => "/upload/image/", /* 指定要列出图片的目录 */ "imageManagerListSize" => 20, /* 每次列出文件数量 */ "imageManagerUrlPrefix" => "", /* 图片访问路径前缀 */ "imageManagerInsertAlign" => "none", /* 插入的图片浮动方式 */ "imageManagerAllowFiles" => [ ".png", ".jpg", ".jpeg", ".gif", ".ico", ".bmp" ], /* 列出的文件类型 */ /* 列出指定目录下的文件 */ "fileManagerActionName" => "listfile", /* 执行文件管理的action名称 */ "fileManagerListPath" => "/upload/file/", /* 指定要列出文件的目录 */ "fileManagerUrlPrefix" => "", /* 文件访问路径前缀 */ "fileManagerListSize" => 20, /* 每次列出文件数量 */ "fileManagerAllowFiles" => [ ".png", ".jpg", ".jpeg", ".gif", ".ico", ".bmp", ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg", ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid", ".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso", ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml" ] /* 列出的文件类型 */ ] ]; public function actionIndex() { //设置允许的跨域header header('Access-Control-Allow-Headers: X-Requested-With,X_Requested_With'); $action = Yii::$app->request->get("action"); $action = htmlspecialchars($action); switch ($action) { case 'config': $result = json_encode($this->uploadConfig['uploadFile']); break; /* 上传图片 */ case 'uploadimage': /* 上传涂鸦 */ case 'uploadscrawl': /* 上传视频 */ case 'uploadvideo': /* 上传文件 */ case 'uploadfile': if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] == "OPTIONS") { //判断实际发送的请求是否安全 $result = ""; } else { if (Yii::$app->request->isPost && !empty($_FILES)) { //上传 $currentFileInfo = $this->uploadFile($action); $result = json_encode($currentFileInfo); } else { $result = ""; } } break; /* 列出图片 */ case 'listimage': if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] == "OPTIONS") { $result = ""; } else { //返回结果 $result = $this->getFileList($action); } break; /* 列出文件 */ case 'listfile': if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] == "OPTIONS") { $result = ""; } else { //返回结果 $result = $this->getFileList($action); } break; /* 抓取远程文件 */ case 'catchimage': if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] == "OPTIONS") { $result = ""; } else { //返回结果 $result = $this->crawlerImage($action); } break; default: $result = json_encode(array( 'state' => '请求地址出错' )); break; } /* 输出结果 */ if (isset($_GET["callback"])) { if (preg_match("/^[\w_]+$/", $_GET["callback"])) { echo htmlspecialchars($_GET["callback"]) . '(' . $result . ')'; } else { echo json_encode(array( 'state' => 'callback参数不合法' )); } } else { echo $result; } } // //上传图片 // public function actionImage($rfmt = 'default') // { // if(!\Yii::$app->request->isPost){ // $data = [ // 'code' => 1, // 'msg' => "Invalid Request" // ]; // return $this->responseHandler($data); // } // $action = "uploadimage"; // $fileInfo = $this->uploadFile($action); // if($rfmt == 'default'){ // if($fileInfo["state"] == "SUCCESS"){ // $data = [ // 'code' => 0, // 'msg' => 'success', // 'data' => [ // 'url' => $fileInfo['url'], // 'extension' => $fileInfo["type"], // 'size' => $fileInfo["size"], // 'type' => $this->getFileType(trim($fileInfo['type'],".")) // ] // ]; // } else { // $data = [ // 'code' => 1, // 'msg' => $fileInfo["state"] // ]; // } // } else if($rfmt == 'wangeditor'){ // if($fileInfo["state"] == "SUCCESS"){ // $data = [ // 'errno' => 0, // 'message' => 'success', // 'data' => [ // 'url' => $fileInfo['url'], // 'alt' => '', // 'href' => '', // 'extension' => $fileInfo["type"], // 'size' => $fileInfo["size"], // 'type' => $this->getFileType(trim($fileInfo['type'],".")) // ] // ]; // } else { // $data = [ // 'errno' => 1, // 'message' => $fileInfo["state"] // ]; // } // } // return $this->responseHandler($data); // } //上传图片到OSS public function actionImage() { if (!\Yii::$app->request->isPost) { $data = [ 'code' => 1, 'msg' => "Invalid Request" ]; return $this->responseHandler($data); } if (empty($_FILES['file']['name'])) { $data = [ 'code' => 1, 'msg' => "请选择要上传的文件" ]; return $this->responseHandler($data); } // 上传文件的目录 $upload_dir = "/web/uploads/1/"; if (!is_dir($upload_dir)) { mkdir(\Yii::$app->basePath . '/web/upload/1', 0777, true); } $file = md5($_FILES['file']['name']); // 上传文件的全名 $upload_file = \Yii::$app->basePath . '/web/upload/1/' . $file . '.png'; // 将上传的文件从临时目录移动到指定目录 if (!move_uploaded_file($_FILES['file']['tmp_name'], $upload_file)) { $data = [ 'code' => 1, 'msg' => "文件上传失败" ]; } else { $oss = new Oss(); $file = '/web/upload/1/' . $file . '.png'; //上传文件目录 $oss_data = $oss->upload($upload_file, $file); if ($oss == false) { $data = [ 'code' => 1, 'msg' => "文件上传失败" ]; } else { $data = [ 'code' => 0, 'msg' => 'success', 'data' => [ 'url' => $oss_data, ] ]; } } return $this->responseHandler($data); } //上传文件 public function actionFile($rfmt = 'default') { if (!\Yii::$app->request->isPost) { $data = [ 'code' => 1, 'msg' => "Invalid Request" ]; return $this->responseHandler($data); } $action = "uploadfile"; $fileInfo = $this->uploadFile($action); if ($rfmt == 'default') { if ($fileInfo["state"] == "SUCCESS") { $data = [ 'code' => 0, 'msg' => 'success', 'data' => [ 'url' => $fileInfo['url'], 'extension' => $fileInfo["type"], 'size' => $fileInfo["size"], 'type' => $this->getFileType(trim($fileInfo['type'], ".")) ] ]; } else { $data = [ 'code' => 1, 'msg' => $fileInfo["state"] ]; } } else if ($rfmt == 'wangeditor') { if ($fileInfo["state"] == "SUCCESS") { $data = [ 'errno' => 0, 'message' => 'success', 'data' => [ 'url' => $fileInfo['url'], 'alt' => '', 'href' => '', 'extension' => $fileInfo["type"], 'size' => $fileInfo["size"], 'type' => $this->getFileType(trim($fileInfo['type'], ".")) ] ]; } else { $data = [ 'errno' => 1, 'message' => $fileInfo["state"] ]; } } return $this->responseHandler($data); } //上传视频 public function actionVideoFile() { if (!\Yii::$app->request->isPost) { $data = [ 'code' => 1, 'msg' => "Invalid Request" ]; } $action = "uploadvideo"; $fileInfo = $this->uploadFile($action); if ($fileInfo["state"] == "SUCCESS") { $data = [ 'code' => 0, 'msg' => 'success', 'data' => [ 'url' => $fileInfo['url'], 'extension' => $fileInfo["type"], 'size' => $fileInfo["size"], 'type' => $this->getFileType(trim($fileInfo['type'], ".")) ] ]; } else { $data = [ 'code' => 1, 'msg' => $fileInfo["state"] ]; } return $this->responseHandler($data); } /** * @TODO 扩展上传至第三方存储 * 文件上传 */ private function uploadFile($action) { //获取上传配置 $uploadConfig = $this->getUploadConfig($action); $path = $uploadConfig["path"]; $_config = $uploadConfig["config"]; /* 上传配置 */ $base64 = "upload"; switch ($action) { case 'uploadimage': $_config['imagePathFormat'] = $path . $_config['imagePathFormat']; $config = array( "pathFormat" => $_config['imagePathFormat'], "maxSize" => $_config['imageMaxSize'], "allowFiles" => $_config['imageAllowFiles'] ); $fieldName = $_config['imageFieldName']; break; case 'uploadscrawl': $_config['scrawlPathFormat'] = $path . $_config['scrawlPathFormat']; $config = array( "pathFormat" => $_config['scrawlPathFormat'], "maxSize" => $_config['scrawlMaxSize'], "allowFiles" => $_config['scrawlAllowFiles'], "oriName" => "scrawl.png" ); $fieldName = $_config['scrawlFieldName']; $base64 = "base64"; break; case 'uploadvideo': $_config['videoPathFormat'] = $path . $_config['videoPathFormat']; $config = array( "pathFormat" => $_config['videoPathFormat'], "maxSize" => $_config['videoMaxSize'], "allowFiles" => $_config['videoAllowFiles'] ); $fieldName = $_config['videoFieldName']; break; case 'uploadfile': default: $_config['filePathFormat'] = $path . $_config['filePathFormat']; $config = array( "pathFormat" => $_config['filePathFormat'], "maxSize" => $_config['fileMaxSize'], "allowFiles" => $_config['fileAllowFiles'] ); $fieldName = $_config['fileFieldName']; break; } /* 生成上传实例对象并完成上传 */ $up = new Uploader($fieldName, $config, $base64); /** * 得到上传文件所对应的各个参数,数组结构 * array( * "state" => "", //上传状态,上传成功时必须返回"SUCCESS" * "url" => "", //返回的地址 * "title" => "", //新文件名 * "original" => "", //原始文件名 * "type" => "" //文件类型 * "size" => "", //文件大小 * ) */ /* 返回数据 */ $fileInfo = $up->getFileInfo(); if ($fileInfo["state"] == "SUCCESS") { $this->imageCompress($fileInfo); $model = new UploadFile(); $model->user_id = Model::getUserId(); $model->file_url = $fileInfo["url"]; $model->extension = trim($fileInfo["type"], "."); $model->type = $this->getFileType($model->extension); $model->size = $fileInfo["size"]; $model->group_id = \Yii::$app->request->get("group_id"); $model->group_id = $model->group_id ? $model->group_id : 0; $model->save(); } return $fileInfo; } private function imageCompress(&$fileInfo) { $filetype = $this->getFileType(trim($fileInfo["type"], ".")); if ($filetype != "image") return; $imageCompressConfig = $this->getImageCompressConfig(); $filename = trim($fileInfo["url"], '/'); if ($imageCompressConfig['imageCompressEnable'] && file_exists($filename)) { try { $gumletImagic = new ImageResize($filename); $gumletImagic->resizeToLongSide($imageCompressConfig['imageCompressBorder']); $gumletImagic->save($filename); clearstatcache(); } catch (ImageResizeException $ex) { } } $fileInfo["size"] = filesize($filename); } private function mkDir($dir, $mode = 0777) { return is_dir($dir) or $this->mkDir(dirname($dir), $mode) and mkdir($dir, $mode); } private function getImageCompressConfig() { $config = []; $imageCompressEnable = \Yii::$app->request->get('imageCompressEnable'); if ($imageCompressEnable !== null) { $config['imageCompressEnable'] = $imageCompressEnable == 1 ? true : false; } else { $config['imageCompressEnable'] = $this->uploadConfig['uploadFile']['imageCompressEnable']; } $imageCompressBorder = \Yii::$app->request->get('imageCompressBorder'); if ($imageCompressBorder !== null && is_numeric($imageCompressBorder)) { $imageCompressBorder = (int)$imageCompressBorder; $config['imageCompressBorder'] = $imageCompressBorder; } else { $config['imageCompressBorder'] = $this->uploadConfig['uploadFile']['imageCompressBorder']; } return $config; } private function getFileType($extension) { $type_list = [ 'image' => ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'ico'], 'video' => ['mp4', 'flv', 'ogg', 'mov',], ]; foreach ($type_list as $type => $exs) { if (in_array($extension, $exs)) { return $type; } } return ''; } /** * 获取已经上传的文件列表 */ private function getFileList($action) { //获取上传配置 $uploadConfig = $this->getUploadConfig($action); $_path = $uploadConfig["path"]; $_config = $uploadConfig["config"]; /* 判断类型 */ switch ($action) { /* 列出文件 */ case 'listfile': $_config['fileManagerListPath'] = $_path . $_config['fileManagerListPath']; $allowFiles = $_config['fileManagerAllowFiles']; $listSize = $_config['fileManagerListSize']; $path = $_config['fileManagerListPath']; break; /* 列出图片 */ case 'listimage': default: $_config['imageManagerListPath'] = $_path . $_config['imageManagerListPath']; $allowFiles = $_config['imageManagerAllowFiles']; $listSize = $_config['imageManagerListSize']; $path = $_config['imageManagerListPath']; } $allowFiles = substr(str_replace(".", "|", join("", $allowFiles)), 1); /* 获取参数 */ $size = isset($_GET['size']) ? htmlspecialchars($_GET['size']) : $listSize; $start = isset($_GET['start']) ? htmlspecialchars($_GET['start']) : 0; $end = $start + $size; /* 获取文件列表 */ $path = $_SERVER['DOCUMENT_ROOT'] . (substr($path, 0, 1) == "/" ? "" : "/") . $path; $files = $this->getfiles($path, $allowFiles); if (!count($files)) { return json_encode(array( "state" => "no match file", "list" => array(), "start" => $start, "total" => count($files) )); } /* 获取指定范围的列表 */ $len = count($files); for ($i = min($end, $len) - 1, $list = array(); $i < $len && $i >= 0 && $i >= $start; $i--) { $list[] = $files[$i]; } //倒序 //for ($i = $end, $list = array(); $i < $len && $i < $end; $i++){ // $list[] = $files[$i]; //} /* 返回数据 */ $result = json_encode(array( "state" => "SUCCESS", "list" => $list, "start" => $start, "total" => count($files) )); return $result; } /** * 遍历获取目录下的指定类型的文件 * @param $path * @param array $files * @return array */ private function getfiles($path, $allowFiles, &$files = array()) { if (!is_dir($path)) return null; if (substr($path, strlen($path) - 1) != '/') $path .= '/'; $handle = opendir($path); while (false !== ($file = readdir($handle))) { if ($file != '.' && $file != '..') { $path2 = $path . $file; if (is_dir($path2)) { $this->getfiles($path2, $allowFiles, $files); } else { if (preg_match("/\.(" . $allowFiles . ")$/i", $file)) { $files[] = array( 'url' => substr($path2, strlen($_SERVER['DOCUMENT_ROOT'])), 'mtime' => filemtime($path2) ); } } } } return $files; } /** * 获取上传路径前缀,及配置信息 */ private function getUploadConfig($action) { $path = UploadHelper::getUploadPath(); $config = $this->uploadConfig['uploadFile']; return array( "path" => $path, "config" => $config ); } /** * 抓取远程图片 */ private function crawlerImage($action) { set_time_limit(0); //获取上传配置 $uploadConfig = $this->getUploadConfig($action); $_path = $uploadConfig["path"]; $_config = $uploadConfig["config"]; /* 上传配置 */ $_config['catcherPathFormat'] = $_path . $_config['catcherPathFormat']; $config = array( "pathFormat" => $_config['catcherPathFormat'], "maxSize" => $_config['catcherMaxSize'], "allowFiles" => $_config['catcherAllowFiles'], "oriName" => "remote.png" ); $fieldName = $_config['catcherFieldName']; /* 抓取远程图片 */ $list = array(); if (isset($_POST[$fieldName])) { $source = $_POST[$fieldName]; } else { $source = $_GET[$fieldName]; } foreach ($source as $imgUrl) { $item = new Uploader($imgUrl, $config, "remote"); $info = $item->getFileInfo(); array_push($list, array( "state" => $info["state"], "url" => $info["url"], "size" => $info["size"], "title" => htmlspecialchars($info["title"]), "original" => htmlspecialchars($info["original"]), "source" => htmlspecialchars($imgUrl) )); } /* 返回抓取数据 */ return json_encode(array( 'state' => count($list) ? 'SUCCESS' : 'ERROR', 'list' => $list )); } public function actionVideo() { set_time_limit(0); $params = \Yii::$app->request->post(); $tempDir = './temp/upload/video/chunks/' . date('Ymd', time()) . '/' . md5($params['name']); if (!file_exists($tempDir)) $this->mk_dir($tempDir); if (!isset($params['chunk'])) { $params['chunk'] = 0; } if (!isset($params['chunks'])) { $params['chunks'] = 1; } //获取上传配置 $action = 'uploadvideo'; $uploadConfig = $this->getUploadConfig($action); $config = array( "pathFormat" => $tempDir . '/' . $params['chunk'], "maxSize" => $uploadConfig['config']['videoMaxSize'], "allowFiles" => $uploadConfig['config']['videoAllowFiles'] ); $base64 = "upload"; /* 生成上传实例对象并完成上传 */ $up = new Uploader('file', $config, $base64); $fileInfo = $up->getFileInfo(); $chunk = strval($params['chunk']); $chunkCount = strval($params['chunks']); if ($chunk + 1 == $chunkCount) { //合并 $targetDir = './upload/video/' . date('Ymd', time()) . '/' . md5($params['name']); if (!file_exists($targetDir)) $this->mk_dir($targetDir); $finalName = $targetDir . $fileInfo['type']; if (file_exists($finalName)) unlink($finalName); $file = fopen($finalName, 'wb'); for ($index = 0; $index < $chunkCount; $index++) { $tmpFile = $tempDir . '/' . $index . $fileInfo['type']; $chunkFile = fopen($tmpFile, 'rb'); $content = fread($chunkFile, filesize($tmpFile)); fclose($chunkFile); fwrite($file, $content); //删除chunk文件 unlink($tmpFile); } fclose($file); //删除chunk文件夹 rmdir($targetDir); $fileInfo['url'] = $finalName; } /* 返回数据 */ \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; return $fileInfo; } private function mk_dir($dir, $mode = 0777) { return is_dir($dir) or $this->mk_dir(dirname($dir), $mode) and mkdir($dir, $mode); } }