master
parent
d5d98df533
commit
a2bb9f0007
@ -0,0 +1,113 @@
|
|||||||
|
<?php
|
||||||
|
namespace Base\Tool;
|
||||||
|
|
||||||
|
use Base\Tool\StorageClient;
|
||||||
|
use Obs\ObsClient as BaseObsClient;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 华为云OBS
|
||||||
|
*/
|
||||||
|
class ObsClient implements StorageClient
|
||||||
|
{
|
||||||
|
const MAX_PART_SIZE = 5368709120;
|
||||||
|
const MID_PART_SIZE = 10485760;
|
||||||
|
const MIN_PART_SIZE = 102400;
|
||||||
|
|
||||||
|
private $accessKey;
|
||||||
|
private $secretKey;
|
||||||
|
private $endpoint;
|
||||||
|
private $bucket;
|
||||||
|
private $domain;
|
||||||
|
private $client;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->accessKey = C('OBS_ACCESS_KEY');
|
||||||
|
$this->secretKey = C('OBS_SECRET_KEY');
|
||||||
|
$this->endpoint = C('OBS_ENDPOINT');
|
||||||
|
$this->domain = C('OBS_DOMAIN');
|
||||||
|
$this->bucket = C('OBS_BUCKET');
|
||||||
|
$this->client = new BaseObsClient([
|
||||||
|
'key' => $this->accessKey,
|
||||||
|
'secret' => $this->secretKey,
|
||||||
|
'endpoint' => $this->endpoint
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function upload($localFilePath, $saveFileName)
|
||||||
|
{
|
||||||
|
/* $resp = $this->client->putObject([
|
||||||
|
'Bucket' => $this->bucket,
|
||||||
|
'Key' => $saveFileName,
|
||||||
|
'SourceFile' => $localFilePath,
|
||||||
|
]); */
|
||||||
|
try {
|
||||||
|
$this->multiuploadFile($localFilePath, $saveFileName);
|
||||||
|
return [
|
||||||
|
'status' => true,
|
||||||
|
'message' => '上传OSS成功',
|
||||||
|
'data' => [
|
||||||
|
'url' => $this->getUrl($saveFileName)
|
||||||
|
]
|
||||||
|
];
|
||||||
|
} catch (\Obs\ObsException $e) {
|
||||||
|
return [
|
||||||
|
'status' => false,
|
||||||
|
'message' => $e->getExceptionMessage()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function multiuploadFile($file, $saveFileName)
|
||||||
|
{
|
||||||
|
$resp = $this->client->initiateMultipartUpload([
|
||||||
|
'Bucket' => $this->bucket,
|
||||||
|
'Key' => $saveFileName,
|
||||||
|
'ContentType' => 'text/plain'
|
||||||
|
]);
|
||||||
|
$uploadId = $resp['UploadId'];
|
||||||
|
|
||||||
|
$packetSize = 1048576;
|
||||||
|
$byteTotal = filesize($file);
|
||||||
|
$packetTotal = ceil($byteTotal / $packetSize);
|
||||||
|
$fileContent = fopen($file, 'r');
|
||||||
|
$parts = [];
|
||||||
|
for ($i=0; $i<$packetTotal; $i++) {
|
||||||
|
$packetFileContent = fread($fileContent, $packetSize);
|
||||||
|
$resp = $this->client->uploadPart([
|
||||||
|
'Bucket' => $this->bucket,
|
||||||
|
'Key' => $saveFileName,
|
||||||
|
'UploadId' => $uploadId,
|
||||||
|
'PartNumber' => $i+1,
|
||||||
|
'Body' => $packetFileContent
|
||||||
|
]);
|
||||||
|
$parts[] = ['PartNumber' => $i+1, 'ETag' => $resp['ETag']];
|
||||||
|
}
|
||||||
|
fclose($fileContent);
|
||||||
|
|
||||||
|
$resp = $this->client->completeMultipartUpload([
|
||||||
|
'Bucket' => $this->bucket,
|
||||||
|
'Key' => $saveFileName,
|
||||||
|
'UploadId' => $uploadId,
|
||||||
|
'Parts' => $parts
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete($deleteFile)
|
||||||
|
{
|
||||||
|
$resp = $this->client->deleteObject([
|
||||||
|
'Bucket' => $this->bucket,
|
||||||
|
'Key' => $deleteFile,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUrl($saveFileName)
|
||||||
|
{
|
||||||
|
return $this->domain . '/' . $saveFileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __destruct()
|
||||||
|
{
|
||||||
|
$this->client->close();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,127 @@
|
|||||||
|
<?php
|
||||||
|
namespace Base\Tool;
|
||||||
|
|
||||||
|
use OSS\Core\OssUtil;
|
||||||
|
use OSS\OssClient as BaseOssClient;
|
||||||
|
use OSS\Core\OSsException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阿里云OSS
|
||||||
|
*/
|
||||||
|
class OssClient implements StorageClient {
|
||||||
|
|
||||||
|
private $accessKeyId = '';
|
||||||
|
private $accessKeySecret = '';
|
||||||
|
private $endpoint = '';
|
||||||
|
private $isCName = false;
|
||||||
|
private $bucket = '';
|
||||||
|
private $domain = '';
|
||||||
|
private $client;
|
||||||
|
private $errorMessage = '';
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
Vendor('OSS.autoload');
|
||||||
|
$this->accessKeyId = C('OSS_ACCESS_KEY_ID');
|
||||||
|
$this->accessKeySecret = C('OSS_ACCESS_KEY_SECRET');
|
||||||
|
$this->endpoint = C('OSS_ENDPOINT');
|
||||||
|
$this->domain = C('OSS_DOMAIN');
|
||||||
|
$this->isCName = C('OSS_IS_CNAME');
|
||||||
|
$this->bucket = C('OSS_BUCKET');
|
||||||
|
$this->client = new BaseOssClient($this->accessKeyId, $this->accessKeySecret, $this->endpoint, $this->isCName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function upload($localFilePath, $saveFileName)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$this->multiuploadFile($localFilePath, $saveFileName);
|
||||||
|
return [
|
||||||
|
'status' => true,
|
||||||
|
'message' => '上传OSS成功',
|
||||||
|
'data' => [
|
||||||
|
'url' => $this->getUrl($saveFileName)
|
||||||
|
]
|
||||||
|
];
|
||||||
|
} catch (OssException $e) {
|
||||||
|
return [
|
||||||
|
'status' => false,
|
||||||
|
'message' => $e->getMessage()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function multiuploadFile($file, $saveFileName)
|
||||||
|
{
|
||||||
|
$uploadId = $this->client->initiateMultipartUpload($this->bucket, $saveFileName);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* step 2. 上传分片
|
||||||
|
*/
|
||||||
|
$partSize = 5 * 1000 * 1024;
|
||||||
|
$uploadFile = $file;
|
||||||
|
$uploadFileSize = filesize($uploadFile);
|
||||||
|
$pieces = $this->client->generateMultiuploadParts($uploadFileSize, $partSize);
|
||||||
|
$responseUploadPart = [];
|
||||||
|
$uploadPosition = 0;
|
||||||
|
$isCheckMd5 = true;
|
||||||
|
foreach ($pieces as $i => $piece) {
|
||||||
|
$fromPos = $uploadPosition + (integer) $piece[BaseOssClient::OSS_SEEK_TO];
|
||||||
|
$toPos = (integer) $piece[BaseOssClient::OSS_LENGTH] + $fromPos - 1;
|
||||||
|
$upOptions = [
|
||||||
|
BaseOssClient::OSS_FILE_UPLOAD => $uploadFile,
|
||||||
|
BaseOssClient::OSS_PART_NUM => ($i + 1),
|
||||||
|
BaseOssClient::OSS_SEEK_TO => $fromPos,
|
||||||
|
BaseOssClient::OSS_LENGTH => $toPos - $fromPos + 1,
|
||||||
|
BaseOssClient::OSS_CHECK_MD5 => $isCheckMd5,
|
||||||
|
];
|
||||||
|
if ($isCheckMd5) {
|
||||||
|
$contentMd5 = OssUtil::getMd5SumForFile($uploadFile, $fromPos, $toPos);
|
||||||
|
$upOptions[BaseOssClient::OSS_CONTENT_MD5] = $contentMd5;
|
||||||
|
}
|
||||||
|
// 2. 将每一分片上传到OSS
|
||||||
|
$responseUploadPart[] = $this->client->uploadPart($this->bucket, $saveFileName, $uploadId, $upOptions);
|
||||||
|
}
|
||||||
|
$uploadParts = [];
|
||||||
|
foreach ($responseUploadPart as $i => $eTag) {
|
||||||
|
$uploadParts[] = [
|
||||||
|
'PartNumber' => ($i + 1),
|
||||||
|
'ETag' => $eTag,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* step 3. 完成上传
|
||||||
|
*/
|
||||||
|
$this->client->completeMultipartUpload($this->bucket, $saveFileName, $uploadId, $uploadParts);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*删除文件
|
||||||
|
*/
|
||||||
|
public function delete($deleteFile)
|
||||||
|
{
|
||||||
|
$this->client->deleteObject($this->bucket, $deleteFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUrl($saveFileName)
|
||||||
|
{
|
||||||
|
$url = '';
|
||||||
|
/* if ($this->isCName) {
|
||||||
|
$url = 'http://' . $this->endpoint . '/' . $saveFileName;
|
||||||
|
} else {
|
||||||
|
$url = 'https://' . $this->bucket . '.' . $this->endpoint . '/' . $saveFileName;
|
||||||
|
$url = str_replace('-internal', '', $url);
|
||||||
|
} */
|
||||||
|
$url = $this->domain . '/' . $saveFileName;
|
||||||
|
return $url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除文件
|
||||||
|
*/
|
||||||
|
public function listObjects($deleteFile)
|
||||||
|
{
|
||||||
|
$listObject = $this->client->listObjects($this->bucket);
|
||||||
|
var_dump($listObject);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Base\Tool;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
class Storage {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var StorageClient
|
||||||
|
*/
|
||||||
|
private static $client;
|
||||||
|
|
||||||
|
private static function getClient(): StorageClient {
|
||||||
|
if (empty(self::$client)) {
|
||||||
|
if (C('STORAGE_TYPE') == 'oss') {
|
||||||
|
self::$client = new OssClient();
|
||||||
|
} elseif (C('STORAGE_TYPE') == 'obs') {
|
||||||
|
self::$client = new ObsClient();
|
||||||
|
} elseif (C('STORAGE_TYPE') == 'cos') {
|
||||||
|
self::$client = new CosClient();
|
||||||
|
} else {
|
||||||
|
throw new Exception("Storage type undefined!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return self::$client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function upload($localFilePath, $saveFileName) {
|
||||||
|
return self::getClient()->upload($localFilePath, $saveFileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function delete($deleteFile)
|
||||||
|
{
|
||||||
|
return self::getClient()->delete($deleteFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getUrl($saveFileName)
|
||||||
|
{
|
||||||
|
return self::getClient()->getUrl($saveFileName);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Base\Tool;
|
||||||
|
|
||||||
|
interface StorageClient {
|
||||||
|
|
||||||
|
public function upload($localFilePath, $saveFileName);
|
||||||
|
|
||||||
|
public function delete($deleteFile);
|
||||||
|
|
||||||
|
public function getUrl($saveFileName);
|
||||||
|
}
|
Loading…
Reference in New Issue