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