Thinkphp-商城项目之oss文件上传及web端直传

news/2024/2/21 10:51:32

4.3头像上传

一般商城网站都会把文件上传到第三方云,例如阿里云(oss),腾讯云(cos),当然如果公司有足够的实力,可以自己部署一台文件服务器,用于文件的保存。

头像上传一般是用户在用户中心上传的,后台管理员可以编辑用户资料,其中就有头像上传,因此这个模块就先讲讲文件上传这个知识点。

源码:https://gitee.com/myha/demo-shop

4.3.1阿里云OSS

首先打开官方文档https://help.aliyun.com/zh/oss/product-overview/?spm=a2c4g.11186623.0.0.625b6f1bjn1FsU。还是按照我们之前阅读文档的重点:概述、快速开始、提供的例子

第一、购买服务

https://help.aliyun.com/zh/oss/getting-started/console-quick-start?spm=a2c4g.11186623.0.0.4d425d6bcx5NWi根据文档这一章节的步骤来

打开https://www.aliyun.com/product/oss?spm=a2c4g.11186623.J_4VYgf18xNlTAyFFbOuOQe.32.5e134425TurhoY,注册/登录阿里云账号

在这里插入图片描述

在这里插入图片描述

购买成功后我们创建一个bucket,

在这里插入图片描述

4.3.2上传实现

首先第一步就是安装

composer require aliyuncs/oss-sdk-php

接下来就把它提供的代码示例抄下来修改即可:https://help.aliyun.com/zh/oss/developer-reference/simple-upload?spm=a2c4g.11186623.0.0.6c745d6bfD4WM5

app->common->lib目录下新建oss->OSs.php

<?php
// +----------------------------------------------------------------------
// | OSS存储
// +----------------------------------------------------------------------
namespace app\common\lib\oss;use OSS\OssClient;
use OSS\Core\OssException;
use think\facade\Log;class Oss{//初始化oss客户端private static function createOssClient(){$accessKeyId = env('oss.access_key_id');$accessKeySecret = env('oss.access_key_secret');$endpoint = env('oss.endpoint');try {return new OssClient($accessKeyId, $accessKeySecret, $endpoint);} catch (OssException $e) {Log::error("初始化oss客户端异常:".$e->getMessage());serviceException();}}/*** 上传文件* @param  string     $object     目标文件* @param  string     $filePath    源文件*/public static function uploadFile($object,$filePath){$bucket = env('oss.bucket');try {$ossClient = self::createOssClient();$result = $ossClient->uploadFile($bucket, $object, $filePath);return $result['info'];}catch (OssException $e) {Log::error("OSS上传文件失败:".$e->getMessage());serviceException();}}/*** 上传文件* @param  string     $object     目标文件* @param  string     $content    字符串*/public static function putFile($object,$content){$bucket = env('oss.bucket');try {$ossClient = self::createOssClient();$result = $ossClient->putObject($bucket, $object, $content);return $result['info'];}catch (OssException $e) {Log::error("OSS上传文件失败:".$e->getMessage());serviceException();}}
}

这里主要封装了两个上传方法,一个是上传文件,一个是把字符串的内容写到文件里并上传,这两种方式是很常用的,因此我这里就一并封装了。

我们上传头像是上传图片,所有等下调用的是uploadFile()方法。

这里需要注意的是

$accessKeyId = env('oss.access_key_id');
$accessKeySecret = env('oss.access_key_secret');
$endpoint = env('oss.endpoint');
// 这个我们之前创建的bucket
$bucket = env('oss.bucket');

这些配置在.env的值是怎么来的

登录控制台,这里可以获取$accessKeyId$accessKeySecret

在这里插入图片描述

还是在控制台找到菜单Bucket 列表,找到刚才我们创建的bucket,然后点击它进去,之后访问概览

在这里插入图片描述

这里要注意一下,如果你们上线的代码是部署在阿里云的话,可以选择内网访问。

在控制器app->admin->controller->User.php,新增如下方法

//上传头像
public function uploadAvatar(){$file = $this->request->file('file');$pathName = $file->getPathname();$originalName = $file->getOriginalExtension();$object = "avatar/".$file->hash('md5').".".$originalName;return success(Oss::uploadFile($object,$pathName));
}

然后添加路由:app->admin->route->app.php

//路由分组
Route::group('user', function(){//导出Route::get('export','user/export');//上传头像Route::post('uploadAvatar','user/uploadAvatar');
})->middleware(app\admin\middleware\Auth::class);

最后我们测试一下接口

在这里插入图片描述

4.3.3客户端直传

客户端直传指的是前端直接把文件上传到oss,就不通过后端服务了,客户端直传避免了业务服务器中转文件,提高了上传速度,节省了服务器资源 ,因此我们一般也是要求前端直传。

文档:https://help.aliyun.com/zh/oss/use-cases/client-direct-transmission-overview?spm=a2c4g.11186623.0.0.40c97b93j8YYOR

客户端直传,我们服务端唯一要做的是要提供一个临时密钥,因为$accessKeyId$accessKeySecret不能直接在前端配置,这东西绝对不能配置,因此我们在app->common->lib->oss->OSs.php后面添加一个获取临时密钥的方法

//获取临时密钥
public static function getTemKey(){$id = env('oss.access_key_id');$key = env('oss.access_key_secret');// $host的格式为 bucketname.endpoint,请替换为您的真实信息。$host = 'http://'.env('oss.bucket').env('oss.endpoint');// $callbackUrl为上传回调服务器的URL,请将下面的IP和Port配置为您自己的真实URL信息。$callbackUrl = '';$dir = 'test/';          // 用户上传文件时指定的前缀。$callback_param = array('callbackUrl' => $callbackUrl,'callbackBody' => 'filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}','callbackBodyType' => "application/x-www-form-urlencoded");$callback_string = json_encode($callback_param);$base64_callback_body = base64_encode($callback_string);$now = time();$expire = 30;  //设置该policy超时时间是10s. 即这个policy过了这个有效时间,将不能访问。$end = $now + $expire;$expiration = str_replace('+00:00', '.000Z', gmdate('c', $now));;//最大文件大小.用户可以自己设置$condition = array(0 => 'content-length-range', 1 => 0, 2 => 1048576000);$conditions[] = $condition;// 表示用户上传的数据,必须是以$dir开始,不然上传会失败,这一步不是必须项,只是为了安全起见,防止用户通过policy上传到别人的目录。$start = array(0 => 'starts-with', 1 => '$key', 2 => $dir);$conditions[] = $start;$arr = array('expiration' => $expiration, 'conditions' => $conditions);$policy = json_encode($arr);$base64_policy = base64_encode($policy);$string_to_sign = $base64_policy;$signature = base64_encode(hash_hmac('sha1', $string_to_sign, $key, true));$response = array();$response['accessid'] = $id;$response['host'] = $host;$response['policy'] = $base64_policy;$response['signature'] = $signature;$response['expire'] = $end;$response['callback'] = $base64_callback_body;$response['dir'] = $dir;  // 这个参数是设置用户上传文件时指定的前缀。return $response;
}

然后我们就可以在控制器中调用这个方法即可。


https://www.xjx100.cn/news/3090457.html

相关文章

从0开始学习JavaScript--JavaScript使用Promise

JavaScript中的异步编程一直是开发中的重要话题。传统的回调函数带来了回调地狱和代码可读性的问题。为了解决这些问题&#xff0c;ES6引入了Promise&#xff0c;一种更现代、更灵活的异步编程解决方案。本文将深入探讨JavaScript中如何使用Promise&#xff0c;通过丰富的示例代…

执行npm的时候报权限问题的解决方案

我们在执行npm操作的过程中&#xff0c;会出现以下权限问题&#xff0c;解决方案: 管理员身份 运行cmd 切换目录到要执行命令的文件下 再进行npm操作即可

openssl C++研发之pem格式处理详解

一、PEM_writeXXX和EM_write_bio_XXX 在OpenSSL的crypto/pem.h头文件中&#xff0c;PEM_write_XXXX和PEM_write_bio_XXXX系列函数用于将特定类型的数据写入文件或BIO&#xff08;内存缓冲区&#xff09;中&#xff0c;其中XXXX代表不同的数据类型。 这些函数的使用方式相似&a…

如何进行数据结构的设计和实现?

数据结构的设计和实现 数据结构是计算机科学中至关重要的概念之一&#xff0c;它涉及如何组织和存储数据以便有效地进行操作。在软件开发中&#xff0c;数据结构的选择和设计直接影响了程序的性能、可维护性和可扩展性。在这篇文章中&#xff0c;我们将深入探讨如何进行数据结…

Oracle 11g 多数据库环境下的TDE设置

19c的TDE wallet的设置是在数据库中设置的&#xff0c;也就是粒度为数据库&#xff0c;因此不会有冲突。 而11g的设置是在sqlnet.ora中&#xff0c;因此有可能产生冲突。 这里先将一个重要概念&#xff0c;按照文档的说法&#xff0c;wallet是不能被数据库共享的。 If there …

DES加密前端入参

js中使用DES加解密解决方案总结_js des加密-CSDN博客 1.需求背景 最近开发vue项目中&#xff0c;对于用户手机号码需要进行DES加解密操作。 简介&#xff1a;DES加密&#xff0c;是一种比较传统的加密方式&#xff0c;其加密运算、解密运算使用的是同样的密钥&#xff0c;信息…

全志H616开发版

开发板介绍&#xff1a; 二、开发板刷机 SDFormatter TF卡的格式化工具、Win32Diskimager 刷机工具 刷机镜像为&#xff1a;Orangepizero2_2.2.0_ubuntu_bionic_desktop_linux4.9.170.img 使用MobaXterm_Personal_20.3连接使用 网络配置&#xff1a;nmcli dev wifi 命令接入网…

8.5 Windows驱动开发:内核注册表增删改查

注册表是Windows中的一个重要的数据库&#xff0c;用于存储系统和应用程序的设置信息&#xff0c;注册表是一个巨大的树形结构&#xff0c;无论在应用层还是内核层操作注册表都有独立的API函数可以使用&#xff0c;而在内核中读写注册表则需要使用内核装用API函数&#xff0c;如…