getFile(); $extension = strtolower($file->getOriginalExtension()); $saveFileName = input('key') ?: Storage::name($file->getPathname(), $extension, '', 'md5_file'); // 检查文件名称是否合法 if (strpos($saveFileName, '..') !== false) { $this->error('文件路径不能出现跳级操作!'); } // 检查文件后缀是否被恶意修改 if (strtolower(pathinfo(parse_url($saveFileName, PHP_URL_PATH), PATHINFO_EXTENSION)) !== $extension) { // $this->error('文件后缀异常,请重新上传文件!'); } // 屏蔽禁止上传指定后缀的文件 if (!in_array($extension, str2arr(sysconf('storage.allow_exts|raw')))) { $this->error('文件类型受限,请在后台配置规则!'); } if (in_array($extension, ['sh', 'asp', 'bat', 'cmd', 'exe', 'php'])) { $this->error('文件安全保护,禁止上传可执行文件!'); } try { $safeMode = $this->getSafe(); if (($type = $this->getType()) === 'local') { $local = LocalStorage::instance(); $distName = $local->path($saveFileName, $safeMode); if (PHP_SAPI === 'cli') { is_dir(dirname($distName)) || mkdir(dirname($distName), 0777, true); rename($file->getPathname(), $distName); } else { $file->move(dirname($distName), basename($distName)); } $info = $local->info($saveFileName, $safeMode, $file->getOriginalName()); if (in_array($extension, ['jpg', 'gif', 'png', 'bmp', 'jpeg', 'wbmp'])) { [$width, $height] = getimagesize($distName); if (($width < 1 || $height < 1) && $local->del($saveFileName)) { $this->error('读取图片的尺寸失败!'); } } } else { $bina = file_get_contents($file->getPathname()); $info = Storage::instance($type)->set($saveFileName, $bina, $safeMode, $file->getOriginalName()); } if (isset($info['url'])) { $this->success('文件上传成功!', ['url' => $safeMode ? $saveFileName : $info['url']]); } else { $this->error('文件处理失败,请稍候再试!'); } } catch (HttpResponseException $exception) { throw $exception; } catch (\Exception $exception) { trace_file($exception); $this->error($exception->getMessage()); } } /** * 获取上传类型 * @return boolean */ private function getSafe(): bool { return boolval(input('safe', '0')); } /** * 获取上传方式 * @return string * @throws \think\admin\Exception */ private function getType(): string { $type = strtolower(input('uptype', '')); if (in_array($type, array_keys(Storage::types()))) { return $type; } else { return strtolower(sysconf('storage.type|raw')); } } /** * 获取文件对象 * @return UploadedFile|void */ private function getFile(): UploadedFile { try { $file = $this->request->file('file'); if ($file instanceof UploadedFile) { return $file; } else { $this->error('读取临时文件失败!'); } } catch (HttpResponseException $exception) { throw $exception; } catch (\Exception $exception) { trace_file($exception); $this->error(lang($exception->getMessage())); } } }