在开发环境中 经常使用到 上传文件 或附件 刚开发时使用的本地上传 某天客户又要开发一个上传oss
又要单独去重新开发 或替换掉之前的上传设置 和 控制器
这样 就可以使用 下面这种 服务驱动类
首先 在 commom 中创建 UploadService 服务类
app\common\service\UploadService;
里面放入 我们 常用的上传类型 比如 image video file 等 上传类
thinkphp 6 自动创建service
php think make:service common@UploadService
根目录 app/common/service/UploadService.php
代码:
declare (strict_types = 1);
namespace app\common\service;
use app\common\service\storage\Driver as StorageDriver;
use think\App;
/**
**************************************
* @title 上传组件服务
* @package app\common\service
* @class UploadService
* @author Xiaobin
* @Time 2023-02-23
***************************************
*/
class UploadService
{
protected array $config;
protected $request;
/**
* 构造函数
*/
public function __construct(array $config = []){
$this->request = App()->request;
// 上传配置信息
$this->config = [
'default' => isset($config['defalut']) ? $config['defalut'] : Config('upload.default'),
'engine' => isset($config['engine']) ? $config['engine'] : Config('upload.engine')
];
}
/**
**************************************
* @title 上传图片
* @return void
***************************************
* @author Xiaobin
* @Email [email protected]
* @CreateTime 2023/2/23 9:46:55
****************************************
*/
public function image( string $filename = 'file')
{
try {
// 实例化上传类
$StorageDriver = new StorageDriver($this->config);
// 设置上传文件
$StorageDriver->setUploadFile($filename);
// 执行上传
return $StorageDriver->upload();
} catch (\think\Exception $e)
{
// 统一返回错误
throw new \think\Exception($e->getMessage());
}
}
}
.env 配置:
APP_DEBUG = true
[APP]
DEFAULT_TIMEZONE = Asia/Shanghai
[DATABASE]
TYPE = mysql
HOSTNAME = 127.0.0.1
DATABASE = test
USERNAME = username
PASSWORD = password
HOSTPORT = 3306
CHARSET = utf8
DEBUG = true
// 主要是这里 配置默认本地引擎驱动
[FILESYSTEM]
driver = public
[LANG]
default_lang = zh-cn
创建
config/upload.php
return [
// 默认上传
'default' => 'local',
// 上传引擎
'engine' => [
// 本地驱动
'default' => 'local', // 引擎驱动
'local' => []
// 阿里云oss
// 'default' => 'aliyun',
// 'aliyun' => [
// 'bucket' => '阿里云bucket',
// 'access_key' => '阿里云秘钥',
// 'secret_key' => 'key',
// 'domain' => '阿里云地址'
// ]
]
// 。。。。其他驱动
];
接下来 创建 app\common\service\storage\Driver 自动驱动
或 手动创建 根目录/app/common/service/storage/Driver.php
php think make:service common@service/storage/Driver
declare (strict_types = 1);
namespace app\common\service\storage;
class Driver
{
private array $config; // 上传配置信息
private object $engine; // 当前存储引擎
/**
* 构造方法
*/
public function __construct( array $config , string $storage = null )
{
$this->config = $config;
$this->engine = $this->getEngineClass($storage);
}
/**
**************************************
* @title 设置上传文件信息
* @return void
***************************************
* @author Xiaobin
* @Email [email protected]
* @CreateTime 2023/2/23 10:13:05
****************************************
*/
public function setUploadFile(string $filename = 'file')
{
return $this->engine->setUploadFile($filename);
}
/**
**************************************
* @title 执行上传
* @return void
***************************************
* @author Xiaobin
* @Email [email protected]
* @CreateTime 2023/2/23 10:41:03
****************************************
*/
public function upload(string $save_dir = 'toppic'){
return $this->engine->upload($save_dir);
}
/**
**************************************
* @title 获取当前存储引擎
* @param string $storage
* @return object
***************************************
* @author Xiaobin
* @Email [email protected]
* @CreateTime 2023/2/23 10:03:50
****************************************
*/
private function getEngineClass( string $storage = null ) : object
{
$engineName = is_null($storage) ? $this->config['default'] : $storage;
$classSpace = __NAMESPACE__ . '\\engine\\' . ucfirst($engineName);
if(!class_exists($classSpace))
{
throw new \think\Exception("未找到存储引擎类 : ${classSpace}");
}
return new $classSpace($this->config['engine'][$engineName]);
}
}
接下来 创建一个 公共引擎驱动 控制一些验证信息
手动创建: 根目录/app/common/service/storage/engine/Server.php注意 这里是个抽象类
php think make:service common@service/storage/engine/Server
declare (strict_types = 1);
namespace app\common\service\storage\engine;
/**
**************************************
* @title 公共存储 抽象类
* @package app\common\service\storage\engine
* @class Server
* @author Xiaobin
* @Time 2023-02-23
***************************************
*/
use think\App;
use think\Exception;
abstract class Server
{
protected $request;
// 上传的文件信息
protected $file;
// 上传文件属性
protected $fileInfo;
public function __construct()
{
$this->request = App()->request;
}
/**
**************************************
* @title 设置上传信息
* @return void
***************************************
* @author Xiaobin
* @Email [email protected]
* @CreateTime 2023/2/23 10:14:29
****************************************
*/
public function setUploadFile( string $filename = 'file'){
if($this->request->method() == 'GET')
{
throw new Exception('请使用POST请求上传文件!!!');
}
// 接受上传文件
$this->file = $this->request->file($filename);
if(empty($this->file))
{
throw new Exception('未找到上传的文件信息');
}
$ExtFile = ['jpg','png'];
// 验证文件类型
if(!in_array($this->file->extension(),$ExtFile))
{
throw new Exception('不允许的上传文件后缀' . $this->file->extension());
}
// 验证文件大小
// 文件信息
$this->fileInfo = [
'ext' => $this->file->extension(),
'size' => $this->file->getSize(),
'mime' => $this->file->getMime(),
'name' => $this->file->getOriginalName(),
'realPath' => $this->file->getRealPath(),
];
}
/**
**************************************
* @title 执行上传
* @return mixed
***************************************
* @author Xiaobin
* @Email [email protected]
* @CreateTime 2023/2/23 10:42:05
****************************************
*/
abstract protected function upload(string $save_dir = null);
}
配置 本地上传服务
手动创建 : 根目录/app/common/
php think make:service common@service/storage/engine/Loacl
declare (strict_types = 1);
namespace app\common\service\storage\engine;
use think\Filesystem;
/**
**************************************
* @title 本地存储引擎
* @package app\common\service\storage\engine
* @class Local
* @author Xiaobin
* @Time 2023-02-23
***************************************
*/
class Local extends Server
{
public function __construct()
{
parent::__construct();
}
/**
**************************************
* @title 上传文件
* @param string|null $save_dir
* @return mixed|void
***************************************
* @author Xiaobin
* @Email [email protected]
* @CreateTime 2023/2/23 10:45:39
****************************************
*/
public function upload( $save_dir = 'topic')
{
$config = Config('filesystem');
$url = isset($config['disks'][$config['default']]['url']) ? $config['disks'][$config['default']]['url'] : '';
$savename = \think\facade\Filesystem::putFile( $save_dir, $this->file);
// 如果是 阿里云 等配置 可以设置为:
// 下面的信息可以放入数据库 file 中去哦
$array = [
'uri' => 'http://阿里云地址.com/' . $url. DIRECTORY_SEPARATOR . $savename,
'url' => $url. DIRECTORY_SEPARATOR . $savename , // 阿里云中删除使用这个地址
'md5' => $this->file->hash('md5') , // hash 散列
'hash' => $this->file->hash('sha1'),
// 图片信息
'size' => $this->fileInfo['size'] , // 文件大小
'ext' => $this->fileInfo['ext'] , //文件后缀
'mime' => $this->fileInfo['mime'], // 文件类型
'name' => $this->fileInfo['name'] , // 文件名称
];
return $array;
return $url. DIRECTORY_SEPARATOR . $savename;
}
}
// 其他上传方式
declare (strict_types = 1);
namespace app\admin\controller;
use think\Request;
// 上传服务
use app\common\service\UploadService;
class Upload
{
/**
**************************************
* @title 上传图片
* @return void
***************************************
* @author Xiaobin
* @Email [email protected]
* @CreateTime 2023/2/23 9:323
****************************************
*/
public function image()
{
try {
echo $reslut;
$param = Request()->param();
$param['tp1'] = (new UploadService) -> image('tp1');
} catch (\think\Exception $e)
{
dump($e);
}
}
}