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";
|
||
}
|
||
} |