Compare commits
9 Commits
Author | SHA1 | Date |
---|---|---|
ljl | 2349f1104b | 7 months ago |
ljl | 0fc827d5e1 | 7 months ago |
elf | ae05762cc0 | 7 months ago |
elf | e8214180a0 | 7 months ago |
elf | 80f6a9fae9 | 7 months ago |
elf | 6f3faa33dd | 7 months ago |
elf | 640f333830 | 7 months ago |
elf | c96d4a2375 | 7 months ago |
elf | f6241f961a | 7 months ago |
@ -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,118 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
@ -1,12 +1,8 @@
|
||||
{
|
||||
"require": {
|
||||
"rodneyrehm/plist": "^2.0",
|
||||
"guzzlehttp/guzzle": "~6.0"
|
||||
},
|
||||
"repositories": {
|
||||
"packagist": {
|
||||
"type": "composer",
|
||||
"url": "https://packagist.phpcomposer.com"
|
||||
}
|
||||
"guzzlehttp/guzzle": "~6.0",
|
||||
"obs/esdk-obs-php": "3.22.6",
|
||||
"qcloud/cos-sdk-v5": ">=2.0"
|
||||
}
|
||||
}
|
||||
|
@ -1,40 +0,0 @@
|
||||
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
|
||||
|
||||
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
|
||||
- using env: export GIN_MODE=release
|
||||
- using code: gin.SetMode(gin.ReleaseMode)
|
||||
|
||||
[GIN-debug] POST /upload --> main.setupRouter.func1 (3 handlers)
|
||||
[GIN-debug] Listening and serving HTTP on :8080
|
||||
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
|
||||
|
||||
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
|
||||
- using env: export GIN_MODE=release
|
||||
- using code: gin.SetMode(gin.ReleaseMode)
|
||||
|
||||
[GIN-debug] POST /upload --> main.setupRouter.func1 (3 handlers)
|
||||
[GIN-debug] Listening and serving HTTP on :8080
|
||||
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
|
||||
|
||||
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
|
||||
- using env: export GIN_MODE=release
|
||||
- using code: gin.SetMode(gin.ReleaseMode)
|
||||
|
||||
[GIN-debug] POST /upload --> main.setupRouter.func1 (3 handlers)
|
||||
[GIN-debug] Listening and serving HTTP on :8080
|
||||
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
|
||||
|
||||
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
|
||||
- using env: export GIN_MODE=release
|
||||
- using code: gin.SetMode(gin.ReleaseMode)
|
||||
|
||||
[GIN-debug] POST /upload --> main.setupRouter.func1 (3 handlers)
|
||||
[GIN-debug] Listening and serving HTTP on :8080
|
||||
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
|
||||
|
||||
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
|
||||
- using env: export GIN_MODE=release
|
||||
- using code: gin.SetMode(gin.ReleaseMode)
|
||||
|
||||
[GIN-debug] POST /upload --> main.setupRouter.func1 (3 handlers)
|
||||
[GIN-debug] Listening and serving HTTP on :8080
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Loading…
Reference in New Issue