86 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			PHP
		
	
	
	
			
		
		
	
	
			86 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			PHP
		
	
	
	
| <?php
 | ||
| declare (strict_types=1);
 | ||
| 
 | ||
| namespace app\util;
 | ||
| 
 | ||
| use app\exception\BusinessException;
 | ||
| use OSS\Core\OssException;
 | ||
| use OSS\OssClient;
 | ||
| 
 | ||
| /**
 | ||
|  * @author canny
 | ||
|  * @date 2024/1/6 14:23
 | ||
|  **/
 | ||
| class AliOss
 | ||
| {
 | ||
|     private OssClient $ossClient;
 | ||
| 
 | ||
|     private string $accessKeyId;
 | ||
|     private string $accessKeySecret;
 | ||
|     private string $endpoint;
 | ||
|     private string $bucket;
 | ||
|     private string $dir;
 | ||
|     const HTTP_PROTOCOL = 'https://';
 | ||
|     const CONTENT_SIZE_LIMIT = 50 * 1024 * 1024; //文件上传限制 50m
 | ||
| 
 | ||
|     public function __construct()
 | ||
|     {
 | ||
|         $this->accessKeyId = env('ali-oss.accessKey');
 | ||
|         $this->accessKeySecret = env('ali-oss.accessKeySecret');
 | ||
|         $this->endpoint = env('ali-oss.endpoint');
 | ||
|         $this->bucket = env('ali-oss.bucket');
 | ||
|         $this->dir = env('ali-oss.dir', '/');
 | ||
|         try {
 | ||
|             $this->ossClient = new OssClient($this->accessKeyId, $this->accessKeySecret, $this->endpoint);
 | ||
|         } catch (OssException $e) {
 | ||
|             throw new BusinessException("oss参数错误");
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     public function getOssClient(): OssClient
 | ||
|     {
 | ||
|         return $this->ossClient;
 | ||
|     }
 | ||
| 
 | ||
|     public function upload($file): string
 | ||
|     {
 | ||
|         validate(['file' => ['fileExt:jpg,png,jpeg,bmp,xlsx,xls,webp|fileSize:20*1024*1024']])->check(['file' => $file]);
 | ||
|         $fileName = $this->dir . md5(uniqid()) . '.' . $file->getOriginalExtension();
 | ||
|         $this->ossClient->uploadFile($this->bucket, $fileName, $file);
 | ||
|         return self::HTTP_PROTOCOL . $this->bucket . '.' . $this->endpoint . '/' . $fileName;
 | ||
|     }
 | ||
| 
 | ||
|     public function getSignature(): array
 | ||
|     {
 | ||
|         $host = 'https://' . $this->bucket . '.' . $this->endpoint;
 | ||
|         $end = time() + 20;
 | ||
|         $dir = $this->dir . 'uploads/' . date('Ym', time()) . '/';//文件在oss中保存目录
 | ||
| 
 | ||
|         //设置该policy超时时间是20s. 即这个policy过了这个有效时间,将不能访问
 | ||
|         $arr = ['expiration' => $this->gmt_iso8601($end),
 | ||
|             'conditions' => [
 | ||
|                 ['content-length-range', 0, self::CONTENT_SIZE_LIMIT], //最大文件大小.用户可以自己设置
 | ||
|                 ['starts-with', '$key', $dir] //表示用户上传的数据,必须是以$dir开始, 不然上传会失败,这一步不是必须项,只是为了安全起见,防止用户通过policy上传到别人的目录
 | ||
|             ]];
 | ||
|         $base64_policy = base64_encode(json_encode($arr));
 | ||
|         $signature = base64_encode(hash_hmac('sha1', $base64_policy, $this->accessKeySecret, true));
 | ||
| 
 | ||
|         $response['accessid'] = $this->accessKeyId;
 | ||
|         $response['host'] = $host;
 | ||
|         $response['policy'] = $base64_policy;
 | ||
|         $response['signature'] = $signature;
 | ||
|         $response['expire'] = $end;
 | ||
|         $response['dir'] = $dir;
 | ||
|         return $response;
 | ||
|     }
 | ||
| 
 | ||
|     private function gmt_iso8601($time): string
 | ||
|     {
 | ||
|         $dtStr = date("c", $time);
 | ||
|         $dateTime = new \DateTime($dtStr);
 | ||
|         $expiration = $dateTime->format(\DateTime::ISO8601);
 | ||
|         $pos = strpos($expiration, '+');
 | ||
|         $expiration = substr($expiration, 0, $pos);
 | ||
|         return $expiration . "Z";
 | ||
|     }
 | ||
| } |