205 lines
6.3 KiB
PHP
205 lines
6.3 KiB
PHP
<?php
|
|
|
|
namespace storage;
|
|
|
|
use FceskyUpload\contract\FileInfo;
|
|
use FceskyUpload\UploadManager;
|
|
use FceskyUpload\drivers\LocalDriver;
|
|
|
|
class LocalUploader
|
|
{
|
|
private $config = [];
|
|
private $domain = "";
|
|
private $_error = "";
|
|
|
|
public function __construct($conf = [])
|
|
{
|
|
$this->config = [
|
|
'disks' => [
|
|
'local' => [
|
|
'driver' => LocalDriver::class, //上传类
|
|
'save_dir' => app()->getRootPath() . 'public/attachment', //上传保存路径
|
|
'file_path' => '/attachment', //上传保存路径
|
|
'tmp_dir' => root_path('runtime' . DIRECTORY_SEPARATOR . 'uploadtmp'),//临时目录
|
|
'slice_first' => 0, //从第几片开始
|
|
],
|
|
//继续添加其它仓库
|
|
],
|
|
'default' => [
|
|
'disk' => 'local', //默认磁盘
|
|
'extensions' => 'jpg,png,mp4', //后缀
|
|
'mimeTypes' => 'image/*,video/*', //类型
|
|
'middlewares' => [], //中间件数组
|
|
'maxSize' => 1 * 1024 * 1024, //单包最大上传大小 2M
|
|
]
|
|
];
|
|
|
|
}
|
|
|
|
|
|
/**文件上传
|
|
* @param $data
|
|
* @param $file
|
|
* @return array
|
|
*/
|
|
public function uploadFile($data, $file)
|
|
{
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
|
|
exit; // finish preflight CORS requests here
|
|
}
|
|
|
|
try {
|
|
//处理部分数据
|
|
$data['size'] = $file->getSize();
|
|
$data['name'] = $file->getOriginalName();
|
|
$data['ext'] = $file->extension();
|
|
//检测文件大小
|
|
if (!$this->checkSize($data['size'])) {
|
|
$this->_error = "超出文件上传大小限制";
|
|
return ['code' => -1, 'data' => []];
|
|
}
|
|
$config = $this->config;
|
|
$uploadManager = new UploadManager($config);
|
|
$fileInfo = new FileInfo();
|
|
$fileInfo->identifier = $data['hash'];
|
|
$fileInfo->filename = $data['name'];
|
|
|
|
$fileInfo->chunkNumber = $data['chunk'] ?? 0;;
|
|
$fileInfo->chunkNumber = intval($fileInfo->chunkNumber ?? 0);
|
|
|
|
//未设置分片数量 则默认总数为1 当前为0
|
|
$fileInfo->totalChunks = $data['chunks'] ?? 1;
|
|
$fileInfo->totalChunks = intval($fileInfo->totalChunks ?? 1);
|
|
$fileInfo->totalChunks = ($fileInfo->totalChunks > 0) ? $fileInfo->totalChunks : 1;
|
|
$fileInfo->totalSize = $data['size'];
|
|
//获取后缀
|
|
|
|
$fileInfo->ext = $data['ext'];
|
|
if (!$this->checkFileType($fileInfo->ext)) {
|
|
$this->_error = "禁止上传的文件类型";
|
|
return ['code' => -1, 'data' => []];
|
|
}
|
|
|
|
$upload = $uploadManager->uploadFile($fileInfo);
|
|
//如果文件较小 直接上传完成
|
|
if (isset($upload['savepath']) && $upload['code'] == 0) {
|
|
$upload = $this->buildFileUrl($upload);
|
|
return ['code' => 1, 'data' => $upload, 'msg' => '成功'];
|
|
}
|
|
$check = $uploadManager->checkFile($fileInfo);
|
|
//如果上传完成
|
|
if (isset($check['savepath']) && $check['code'] == 0) {
|
|
$check = $this->buildFileUrl($check);
|
|
return ['code' => 1, 'data' => $check];
|
|
} else {
|
|
$this->_error = "文件包不完整";
|
|
return ['code' => 0, 'data' => $check];
|
|
}
|
|
} catch (\Exception $e) {
|
|
$this->_error = $e->getMessage();
|
|
return ['code' => -1, 'data' => $e->getMessage()];
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* 处理文件
|
|
* 扩展包存在问题 ,考虑后续更新 尽量不更改扩展包,在这里做文件的处理
|
|
*/
|
|
public function buildFileUrl($data)
|
|
{
|
|
|
|
if (isset($data['savepath']) && $data['savepath'] != '') {
|
|
|
|
$conf = $this->config;
|
|
//获取除域名外的文件路径
|
|
$save_dir = $conf['disks'][$conf['default']['disk']]['save_dir'];
|
|
$file_path = str_replace($save_dir, '', $data['savepath']);
|
|
//拼接域名
|
|
$data['save_path'] = $conf['disks'][$conf['default']['disk']]['file_path'] . $file_path;
|
|
$data['file_path'] = $this->domain . $data['save_path'];
|
|
//删除多余的信息
|
|
unset($data['savepath']);
|
|
unset($data['code']);
|
|
}
|
|
return $data;
|
|
}
|
|
|
|
//检测文件上传大小
|
|
public function checkSize($file_size)
|
|
{
|
|
|
|
if ($file_size > $this->config['default']['maxSize']) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
/**检测文件类型
|
|
* @param $file_ext
|
|
* @return array|bool
|
|
*/
|
|
public function checkFileType($file_ext)
|
|
{ //获取配置信息
|
|
$extensions = $this->config['default']['extensions'];
|
|
|
|
//为空或者为 * 表示不过滤
|
|
if ($extensions == "" || $extensions == '*') {
|
|
return true;
|
|
}
|
|
//字符转换成数组
|
|
$exts = explode(',', $extensions);
|
|
if (in_array($file_ext, $exts)) {
|
|
$this->_error = "禁止上传该类型文件";
|
|
return ['code' => 0, 'data' => ''];
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
/**
|
|
* 检测文件分片情况
|
|
*/
|
|
public function checkFile($hash,$count){
|
|
|
|
$filePath = $this->config['disks'][$this->config['default']['disk']]['tmp_dir'] . $hash; //临时分片文件路径
|
|
|
|
// dump($filePath);
|
|
//检查分片是否存在
|
|
$chunkExists = [];
|
|
for ($index = 0; $index < $count; $index++) {
|
|
if (file_exists("{$filePath}_{$index}")) {
|
|
array_push($chunkExists, $index);
|
|
}
|
|
}
|
|
//分片有缺失,返回已存在的分片
|
|
$res['uploaded'] = $chunkExists;
|
|
return $res;
|
|
}
|
|
|
|
|
|
/**
|
|
* 删除文件
|
|
* @param $path
|
|
*/
|
|
public function deleteFile($path){
|
|
$path = app()->getRootPath() . 'public'.$path;
|
|
if (file_exists($path)){
|
|
@unlink($path);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* 返回报错
|
|
* @return string
|
|
*/
|
|
public function getError()
|
|
{
|
|
return $this->_error;
|
|
}
|
|
|
|
}
|