|
|
|
<?php
|
|
|
|
namespace Base\Service;
|
|
|
|
|
|
|
|
use OSS\Core\OssUtil;
|
|
|
|
use OSS\OssClient;
|
|
|
|
use OSS\Core\OSsException;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 目前仅支持阿里云OSS
|
|
|
|
*/
|
|
|
|
class OssService {
|
|
|
|
|
|
|
|
private $accessKeyId = '';
|
|
|
|
private $accessKeySecret = '';
|
|
|
|
private $domain = '';
|
|
|
|
private $isCName = false;
|
|
|
|
private $bucket = '';
|
|
|
|
private $bdDomain = '';
|
|
|
|
private $client;
|
|
|
|
private $errorMessage = '';
|
|
|
|
|
|
|
|
public function __construct()
|
|
|
|
{
|
|
|
|
Vendor('OSS.autoload');
|
|
|
|
$this->accessKeyId = C('oss_storage.accesskeyid');
|
|
|
|
$this->accessKeySecret = C('oss_storage.accesskeysecr');
|
|
|
|
$this->domain = C('oss_storage.domain');
|
|
|
|
$this->isCName = C('oss_storage.is_cname');
|
|
|
|
$this->bdDomain = C('oss_storage.bd_domain');
|
|
|
|
$this->bucket = C('oss_storage.bucket');
|
|
|
|
$this->client = new OssClient($this->accessKeyId, $this->accessKeySecret, $this->domain, $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[OssClient::OSS_SEEK_TO];
|
|
|
|
$toPos = (integer) $piece[OssClient::OSS_LENGTH] + $fromPos - 1;
|
|
|
|
$upOptions = [
|
|
|
|
OssClient::OSS_FILE_UPLOAD => $uploadFile,
|
|
|
|
OssClient::OSS_PART_NUM => ($i + 1),
|
|
|
|
OssClient::OSS_SEEK_TO => $fromPos,
|
|
|
|
OssClient::OSS_LENGTH => $toPos - $fromPos + 1,
|
|
|
|
OssClient::OSS_CHECK_MD5 => $isCheckMd5,
|
|
|
|
];
|
|
|
|
if ($isCheckMd5) {
|
|
|
|
$contentMd5 = OssUtil::getMd5SumForFile($uploadFile, $fromPos, $toPos);
|
|
|
|
$upOptions[OssClient::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 deleteObject($deleteFile)
|
|
|
|
{
|
|
|
|
$this->client->deleteObject($this->bucket, $deleteFile);
|
|
|
|
}
|
|
|
|
|
|
|
|
private function getUrl($saveFileName)
|
|
|
|
{
|
|
|
|
$url = '';
|
|
|
|
if ($this->isCName) {
|
|
|
|
$url = 'http://' . $this->domain . '/' . $saveFileName;
|
|
|
|
} else {
|
|
|
|
$url = 'https://' . $this->bucket . '.' . $this->domain . '/' . $saveFileName;
|
|
|
|
$url = str_replace('-internal', '', $url);
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
* @todo unknown
|
|
|
|
*/
|
|
|
|
if (!empty($this->bdDomain) && strlen($this->bdDomain) > 5) {
|
|
|
|
$url = $this->bdDomain . $saveFileName;
|
|
|
|
}
|
|
|
|
return $url;
|
|
|
|
}
|
|
|
|
}
|