* @created Sep 11, 2019 */ class UploadAction extends Action { /** * 常量:表单数据类型 */ const DATA_TYPE_FORM = 1; /** * 常量: 二进制数据类型 */ const DATA_TYPE_BINARY = 2; /** * @var function * */ public $saveInDatabase; /** * @var integer 限制的最大尺寸 */ public $maxSize; /** * @var array 允许的文件类型(扩展名) */ public $allowType; /** * @var string 文件保存路径 * template /image/jpg/ */ public $path; /** * @var string 数据类型 */ public $dataType; /** * @var bool 是否随机文件名(默认为随机,推荐为随机避免中文文件名导致的问题) */ public $randName = true; /** * @var integer 默认单次最大上传数量(1-20) */ public $maxCount; public function init() { if ($this->maxSize === null) { $this->maxSize = 2048;//默认最大尺寸为2M } if ($this->allowType === null) { $this->allowType = ['*'];//默认允许任何图片类型 } if ($this->maxCount === null) { $this->maxCount = 5;//默认单次最大上传数量为5 } if ($this->dataType === null) { $this->dataType = self::DATA_TYPE_FORM;//默认上传数据类型为表单数据 } } public function run() { Yii::$app->response->format = Response::FORMAT_JSON; $data = []; try { if ($this->dataType == self::DATA_TYPE_FORM) { $file = UploadedFile::getInstanceByName('file'); $this->checkType($file->extension); $this->checkSize($file->size); $savePath = $this->getSavePath(); $fileName = $this->getFileName($file->baseName); $filePath = "$savePath$fileName.{$file->extension}"; $file->saveAs($filePath); // $data[] = ["uploads/$this->path/$fileName.{$file->extension}"]; } else { //TODO 非表单类型的文件上传 throw new NotFoundHttpException('未实现'); // $bin = Yii::$app->request->post('file'); // $head = substr($bin, 0, 2); // $fileExtension = $this->getExtension($head); // $fileName = $this->getFileName(); // $savePath = $this->getSavePath(); // $filePath = "$savePath/$fileName.{$fileExtension}"; // file_put_contents($filePath, $bin); } return ['status' => true, 'path' => "uploads/$this->path$fileName.{$file->extension}"]; } catch (\Error $e) { throw new ServerErrorHttpException($e->getMessage()); // return ['status' => false, 'info' => $e->getMessage()]; } } protected function saveData() { } /** * 检查文件类型是否允许上传 * @param $extension 文件扩展名 * @return bool * @throws Exception */ protected function checkType($extension) { if (in_array('*', $this->allowType)) { return true; } if (!in_array($extension, $this->allowType)) { throw new Exception("类型【{$extension}】不被允许,请在配置项中添加该类型"); } } /** * 检查文件尺寸是否超过最大允许上传尺寸 * @param $size 文件尺寸 * @throws Exception */ protected function checkSize($size) { if ($size / 1024 > $this->maxSize) { throw new Exception("文件大于允许的最大尺寸【{$this->maxSize}】,请修改配置或压缩文件"); } } /** * 根据二进制流头大小判断文件类型 * @param $head * @return mixed * @throws NotFoundHttpException */ protected function getExtension($head) { $fileTypes = array( 7790 => 'exe', 7784 => 'midi', 8297 => 'rar', 255216 => 'jpg', 7173 => 'gif', 6677 => 'bmp', 13780 => 'png' ); if (isset($fileTypes[$head])) { return $fileTypes[$head]; } else { throw new NotFoundHttpException('未找到该文件类型'); } } /** * 获取文件保存路径并创建文件夹 * @return string 文件保存的完成路径 */ protected function getSavePath() { $dirs = explode('/', $this->path); $savePath = Yii::getAlias('@app') . '/web/uploads'; if (!is_dir($savePath)) { mkdir($savePath, 0755); } foreach ($dirs as $dir) { $savePath .= "/$dir"; if (!is_dir($savePath)) { mkdir($savePath, 0755); } } return $savePath; } /** * 利用时间戳加随机数构建新文件名 * @param $originName 源文件名 * @return string */ //TODO 利用原文件名生成新文件名 protected function getFileName($originName = '') { return time() . rand(0, 9999); } }