小程序前端上传图片直传七牛云不存储服务器

news2024/11/27 10:25:24

 fastadmin文件API接口文件下的common修改默认的upload方法,直接替换即可

  /**
     * 上传文件
     * @ApiMethod (POST)
     * @param File $file 文件流
     */
    public function upload()
    {
        $file = $this->request->file('file');
        if (empty($file)) {
            $this->error(__('No  file  upload  or  server  upload  limit  exceeded'));
        }

        //判断是否已经存在附件
        $sha1 = $file->hash();

        $upload = Config::get('upload');

        preg_match('/(\d+)(\w+)/', $upload['maxsize'], $matches);
        $type = strtolower($matches[2]);
        $typeDict = ['b' => 0, 'k' => 1, 'kb' => 1, 'm' => 2, 'mb' => 2, 'gb' => 3, 'g' => 3];
        $size = (int)$upload['maxsize'] * pow(1024, isset($typeDict[$type]) ? $typeDict[$type] : 0);
        $fileInfo = $file->getInfo();
        $suffix = strtolower(pathinfo($fileInfo['name'], PATHINFO_EXTENSION));
        $suffix = $suffix && preg_match("/^[a-zA-Z0-9]+$/", $suffix) ? $suffix : 'file';

        $mimetypeArr = explode(',', strtolower($upload['mimetype']));
        $typeArr = explode('/', $fileInfo['type']);

        //禁止上传PHP和HTML文件
        if (in_array($fileInfo['type'], ['text/x-php', 'text/html']) || in_array($suffix, ['php', 'html', 'htm'])) {
            $this->error(__('Uploaded  file  format  is  limited'));
        }
        //验证文件后缀
        if ($upload['mimetype'] !== '*' &&
            (
                !in_array($suffix, $mimetypeArr)
                || (stripos($typeArr[0] . '/', $upload['mimetype']) !== false && (!in_array($fileInfo['type'], $mimetypeArr) && !in_array($typeArr[0] . '/*', $mimetypeArr)))
            )
        ) {
            $this->error(__('Uploaded  file  format  is  limited'));
        }
        //验证是否为图片文件
        $imagewidth = $imageheight = 0;
        if (in_array($fileInfo['type'], ['image/gif', 'image/jpg', 'image/jpeg', 'image/bmp', 'image/png', 'image/webp']) || in_array($suffix, ['gif', 'jpg', 'jpeg', 'bmp', 'png', 'webp'])) {
            $imgInfo = getimagesize($fileInfo['tmp_name']);
            if (!$imgInfo || !isset($imgInfo[0]) || !isset($imgInfo[1])) {
                $this->error(__('Uploaded  file  is  not  a  valid  image'));
            }
            $imagewidth = isset($imgInfo[0]) ? $imgInfo[0] : $imagewidth;
            $imageheight = isset($imgInfo[1]) ? $imgInfo[1] : $imageheight;
        }
        $replaceArr = [
            '{year}' => date("Y"),
            '{mon}' => date("m"),
            '{day}' => date("d"),
            '{hour}' => date("H"),
            '{min}' => date("i"),
            '{sec}' => date("s"),
            '{random}' => Random::alnum(16),
            '{random32}' => Random::alnum(32),
            '{filename}' => $suffix ? substr($fileInfo['name'], 0, strripos($fileInfo['name'], '.')) : $fileInfo['name'],
            '{suffix}' => $suffix,
            '{.suffix}' => $suffix ? '.' . $suffix : '',
            '{filemd5}' => md5_file($fileInfo['tmp_name']),
        ];
        $savekey = $upload['savekey'];
        $savekey = str_replace(array_keys($replaceArr), array_values($replaceArr), $savekey);

        $uploadDir = substr($savekey, 0, strripos($savekey, '/') + 1);
        $fileName = substr($savekey, strripos($savekey, '/') + 1);
        //
        $splInfo = $file->validate(['size' => $size])->move(ROOT_PATH . '/public' . $uploadDir, $fileName);
        if ($splInfo) {
            $params = array(
                'admin_id' => 0,
                'user_id' => (int)$this->auth->id,
                'filesize' => $fileInfo['size'],
                'imagewidth' => $imagewidth,
                'imageheight' => $imageheight,
                'imagetype' => $suffix,
                'imageframes' => 0,
                'mimetype' => $fileInfo['type'],
                'url' => $uploadDir . $splInfo->getSaveName(),
                'uploadtime' => time(),
                'storage' => 'local',
                'sha1' => $sha1,
            );
            $attachment = new  Attachment();
            $attachment->data(array_filter($params));
            $attachment->save();
            //  文件上传至七牛云
            $config = get_addon_config('qiniu');
            $filePath = $splInfo->getRealPath() ?: $splInfo->getPathname();
            $policy = array(
                'saveKey' => ltrim($savekey, '/'),
            );
            $auth = new  \Qiniu\Auth($config['accessKey'], $config['secretKey']);
            $token = $auth->uploadToken($config['bucket'], null, $config['expire'], $policy);
            $multipart = [
                ['name' => 'token', 'contents' => $token],
                [
                    'name' => 'file',
                    'contents' => fopen($filePath, 'r'),
                    'filename' => $fileName,
                ]
            ];
            try {
                $client = new  \GuzzleHttp\Client();
                $res = $client->request('POST', $config['uploadurl'], [
                    'multipart' => $multipart
                ]);
                $code = $res->getStatusCode();
                //成功不做任何操作
            } catch (\GuzzleHttp\Exception\ClientException  $e) {
                $attachment->delete();
                unlink($filePath);
                $this->error("上传失败");
            }
            //上传成功后将存储变更为qiniu
            $attachment->storage = 'qiniu';
            $attachment->save();
            \think\Hook::listen("upload_after", $attachment);
            $this->success(__('Upload  successful'), [
                'url' => $uploadDir . $splInfo->getSaveName(),
                'fullurl' => cdnurl($uploadDir . $splInfo->getSaveName(), true)
            ]);
        } else {
            //  上传失败获取错误信息
            $this->error($file->getError());
            Config::set('default_return_type', 'json');
            //必须设定cdnurl为空,否则cdnurl函数计算错误
            Config::set('upload.cdnurl', '');
            $chunkid = $this->request->post("chunkid");
            if ($chunkid) {
                if (!Config::get('upload.chunking')) {
                    $this->error(__('Chunk file disabled'));
                }
                $action = $this->request->post("action");
                $chunkindex = $this->request->post("chunkindex/d");
                $chunkcount = $this->request->post("chunkcount/d");
                $filename = $this->request->post("filename");
                $method = $this->request->method(true);
                if ($action == 'merge') {
                    $attachment = null;
                    //合并分片文件
                    try {
                        $upload = new Upload();
                        $attachment = $upload->merge($chunkid, $chunkcount, $filename);
                    } catch (UploadException $e) {
                        $this->error($e->getMessage());
                    }
                    $this->success(__('Uploaded successful'), ['url' => $attachment->url, 'fullurl' => cdnurl($attachment->url, true)]);
                } elseif ($method == 'clean') {
                    //删除冗余的分片文件
                    try {
                        $upload = new Upload();
                        $upload->clean($chunkid);
                    } catch (UploadException $e) {
                        $this->error($e->getMessage());
                    }
                    $this->success();
                } else {
                    //上传分片文件
                    //默认普通上传文件
                    $file = $this->request->file('file');
                    try {
                        $upload = new Upload($file);
                        $upload->chunk($chunkid, $chunkindex, $chunkcount);
                    } catch (UploadException $e) {
                        $this->error($e->getMessage());
                    }
                    $this->success();
                }
            } else {
                $attachment = null;
                //默认普通上传文件
                $file = $this->request->file('file');
                try {
                    $upload = new Upload($file);
                    $attachment = $upload->upload();
                } catch (UploadException $e) {
                    $this->error($e->getMessage());
                }

                $this->success(__('Uploaded successful'), ['url' => $attachment->url, 'fullurl' => cdnurl($attachment->url, true)]);
            }

        }
    }

注意:

        

后台七牛云插件中需要修改的地方 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/724233.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IDEA中使用Git拉取项目时设置重新输入用户名和密码

1、选择:file ----> setting ---->passwords 2、选中这个Do not save 3、点击OK 4、重新使用Git拉取代码会提示重新输入用户名和密码

培训报名小程序报名列表页开发

目录 1 创建页面2 组件搭建3 设置URL参数4 设置筛选条件5 首页跳转6 最终的效果总结 这节我们来开发报名列表功能,先看原型 1 创建页面 功能要在页面上呈现,需要先创建页面。打开我们的培训报名小程序,在页面区,点击创建页面的…

Golang每日一练(leetDay0115) 重新安排行程、递增的三元子序列

目录 332. 重新安排行程 Reconstruct Itinerary 🌟🌟🌟 334. 递增的三元子序列 Increasing Triplet Subsequence 🌟🌟 🌟 每日一练刷题专栏 🌟 Rust每日一练 专栏 Golang每日一练 专栏 P…

【数据挖掘从入门到实战】——专栏导读

目录 1、专栏大纲 🐋基础部分 🐋实战部分 🐋竞赛部分 2、代码附录 数据挖掘专栏,包含基本的数据挖掘算法分析和实战,数据挖掘竞赛干货分享等。数据挖掘是从大规模数据集中发现隐藏模式、关联和知识的过程。它结合…

CE-Net

一、贡献 (1)提出DAC模块和RMP模块,以捕获更多高级特征并保留更多空间信息 (2)将所提出的DAC模块和RMP模块与编码器-解码器结构集成在一起,用于医学图像分割 二、方法 (b)部分是shortcut mechanism 空洞卷积 公式化为: 空洞率r对应于对输…

写一个函数求某个数对应的二进制中1的个数(牛客)

[该题的牛客链接](https://www.nowcoder.com/questionTerminal/8ee967e43c2c4ec193b040ea7fbb10b8? 一、方法一:%/达到二进制位右移的效果1.1用>>操作符实现1.2方法一代码的改进(针对负数情况) 二、方法二:按位与1&#x…

基于PyQt5的桌面图像调试仿真平台开发(14)色彩增强

系列文章目录 基于PyQt5的桌面图像调试仿真平台开发(1)环境搭建 基于PyQt5的桌面图像调试仿真平台开发(2)UI设计和控件绑定 基于PyQt5的桌面图像调试仿真平台开发(3)黑电平处理 基于PyQt5的桌面图像调试仿真平台开发(4)白平衡处理 基于PyQt5的桌面图像调试仿真平台开发(5)…

VSCode编译github上面的C++项目

1、下载cmake 在这里下载对应的版本 https://cmake.org/download/ 测试下载的是这个 下载完成后安装,安装都比较简单 2、安装CMake工具扩展 3、安装C扩展 4、下载github项目 例如:下载这个项目 https://gitcode.net/mirrors/zrax/pycdc?utm_source…

Axure教程—菜单滚动切换交互

本文接受的是用Axure中的动态面板和热区制作菜单滚动切换交互 效果 预览地址:https://u5ircj.axshare.com 功能 页面滚动到某一内容部分,显示其相应的菜单。 制作 一、所需元件 矩形、动态面板、热区 二、制作过程 拖入一个矩形元件,其大小…

CSO 们关注的软件供应链安全十个关键问题

写在前面 自从和几个小伙伴一起创办墨菲安全以来,有一年半多的时间了,创业对于我来说,很有意思的一个地方,就是有机会可以和各行各业很多非常有意思的人一起交流,在这个交流的过程中能够不断的提升自己的认知&#xf…

【Java基础教程】(四)程序概念篇 · 中:探索Java编程基础,解析各类运算符功能、用法及其应用场景~

Java基础教程之程序概念 中 本节学习目标1️⃣ 运算符1.1 关系运算符1.2 算术运算符1.3 三目运算符1.4 逻辑运算1.4.1 与操作1.4.2 或操作1.4.3 非操作 1.5 位运算🔍位运算规则1.5.1 位与运算1.5.2 位或运算 🌾 总结 本节学习目标 掌握Java中各类运算符…

MSF安装使用指导案例

零.简介 Metasploit(MSF)是一个免费的、可下载的框架,它本身附带数百个已知软件漏洞,是一款专业级漏洞攻击工具。当H.D. Moore在2003年发布Metasploit时,计算机安全状况也被永久性地改变了,仿佛一夜之间&a…

选择排序--简单选择排序,堆排序(大根堆,小根堆的建立,堆排序,插入删除元素)包含程序

选择排序:每一趟从待排序列中选择最小的元素作为有序子序列中的元素,待元素只剩下一个,就不用选了。 一,简单选择排序 1.过程:假设以A[]表示数组 1.1最开始定义一个变量用来存储数组数组第一个元素的序号 i 0; min…

赛效:怎么无损压缩Word文档

1:在电脑上打开PDF猫,在导航栏的“文件压缩”菜单里点击“Word压缩”。 2:点击或者拖拽Word文档上传。 3:文件添加成功后,点击右下角“开始转换”。 4:转换成功后,文件下方有下载按钮&#xff0…

快速搭建专属于自己的单商户商城系统!

<系统简介> 基于ThinkPHP6.0、Vue、uni-app、PHP8.0、MySQL5.7、element-ui等主流通用技术开发的一套likeshop单商户商城系统&#xff0c;真正做到好懂&#xff0c;易改&#xff0c;不绕弯 代码全开源 极易二开 可免费商用 系统适用于B2C、单商户、自营商城场景。完…

SOLIDWORKS电控柜设计插件

电控柜设备的种类有很多种&#xff0c;但它们大体都是箱柜式的结构。电控柜是有标准的&#xff0c;但对于公司产品而言&#xff0c;针对不同的项目&#xff0c;如果都使用同一种规格的电控柜&#xff0c;又有可能空间太大&#xff0c;造成浪费&#xff0c;因此一般来说&#xf…

Postman 连接/请求超时(远程服务/接口访问不上)

一、问题情况 二、解决思路 接口访问不了&#xff0c;先看请求方式&#xff0c;然后看IP地址&#xff0c;发现都对着&#xff0c;但请求接口对应的端口号发现连接不上&#xff0c;于是想到是不是防火墙没有关&#xff08;不过理论上严谨一点&#xff0c;是只要把这个端口给开放…

机器学习27:使用 Pandas 和 TensorFlow 进行数据建模编程实践

本文将详细介绍基于 Pandas 和 TensorFlow 探索、清理以及转换用于训练模型的数据集的方法&#xff0c;辅以代码和图片。 学习目标&#xff1a; 了解使用 Pandas 进行数据清理和处理丢失数据的基础知识。使用校准图评估模型性能。使用各种特征转换训练模型。使用可视化来了解…

前端学习——jsDay5

对象 对象使用 小练习 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"width…

科技力量赋予 SK5 代理 HTTP 代理 IP 网络无限可能

第一部分&#xff1a;智能网络加速技术 智能缓存&#xff1a;SK5 代理 HTTP 代理 IP 利用智能缓存技术&#xff0c;将经常访问的资源缓存在代理服务器中&#xff0c;从而实现更快速的资源加载和页面响应。这种智能化的缓存策略有效减少了对远程服务器的依赖&#xff0c;提升了用…