前提
華為的obs
上傳sdk
寫的有點一言難盡,而且包的版本全部指定了,無法在hyperf框架中使用。所以自己寫了一個。
直接上程式碼:
<?php
/**
* Created by EzrealRao MacBook
* User: Ezreal Rao
* Date: 2019/12/8
* Time: 20:49
*/
namespace App\Services;
use GuzzleHttp\Client;
use Hyperf\HttpMessage\Upload\UploadedFile;
class HuaWeiService
{
/**
* @var array
*/
private $config;
/**
* 物件策略
* @var string
*/
private $obsAcl = 'public-read';
/**
* @var UploadedFile
*/
private $file;
/**
* 過期時間
* @var int
*/
private $expires = 3600;
/**
* @var int
*/
private $boundary = 9431149156168;
/**
* @var string
*/
protected $logName = 'ObsUpload';
/**
* HuaWeiService constructor.
*/
public function __construct()
{
$this->config = config('hw');
}
/**
* @param UploadedFile $file
* @param $filePath string 檔案路徑
* @return array
*/
public function post(UploadedFile $file, $filePath = 'images')
{
$this->file = $file;
//獲取字尾
$fileExtension = $file->getExtension();
//生成檔名
$fileName = trim($filePath, '/') . '/' . date('YmdHis') . '_' . uniqid() . '.' . $fileExtension;
$buffers = $this->getBuffers($fileName);
$buffer = $buffers['buffers'];
$contentLength = $buffers['contentLength'];
$requestBody = [
'headers' => [
'Content-Type' => 'multipart/form-data; boundary=' . $this->boundary,
'Content-Length' =>strval($contentLength) ,
],
'body' => implode('', $buffer),
];
$scheme = $this->config['obs_scheme'];
$port = $scheme == 'https' ? '443' : '80';
$host = $scheme . '://' . $this->config['bucket'] . '.' . $this->config['endpoint'] . ':' . $port;
logger($this->logName)->info('begin request', [
'requestBody' => $requestBody,
'host' => $host
]);
$client = new Client([
'verify' => false
]);
try {
$request = $client->request('POST', $host, $requestBody);
$response = $request->getBody()->getContents();
logger($this->logName)->info('result success', [$response]);
return [
'status' => true,
'file_path' => $fileName,
'msg' => null
];
} catch (\Exception $e) {
$message = $e->getResponse()->getBody()->getContents();
$message = json_decode(json_encode(simplexml_load_string($message, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
logger($this->logName)->error('result failed', ['message' => $message]);
return [
'status' => false,
'file_path' => null,
'msg' => $message
];
}
}
/**
* 獲取策略
* @param $fileName
* @return false|string
*/
private function getPolicy($fileName)
{
//頭部過期時間
$expires = gmdate('Y-m-d\TH:i:s\Z', time() + $this->expires);
$policy = [
'expiration' => $expires,
'conditions' => [
['bucket' => $this->config['bucket']],
['key' => $fileName],
['x-obs-acl' => $this->obsAcl],
['content-type' => $this->file->getClientMediaType()],
]
];
logger($this->logName)->info('policy', $policy);
return json_encode($policy);
}
/**
* 獲取簽名
* @param $originPolicy
* @return string
*/
private function getSign($originPolicy)
{
$policy = base64_encode($originPolicy);
$sign = base64_encode(hash_hmac('sha1', $policy, $this->config['secret'], true));
logger($this->logName)->info('sign', [$sign]);
return $sign;
}
/**
* 返回表單引數
* @param $fileName
* @return array
*/
private function getFormParams($fileName)
{
$policy = $this->getPolicy($fileName);
$sign = $this->getSign($policy);
$formParams = [
'x-obs-acl' => $this->obsAcl,
'content-type' => $this->file->getClientMediaType(),
'key' => $fileName,
'policy' => base64_encode($policy),
'Accesskeyid' => $this->config['key'],
'signature' => $sign
];
logger($this->logName)->info('formParams', $formParams);
return $formParams;
}
/**
* 獲取buffers
* @param $fileName
* @return array
*/
private function getBuffers($fileName)
{
$formParams = $this->getFormParams($fileName);
$buffers = [];
$contentLength = 0;
/**
* 從formParams 構造
*/
$buffer = [];
$first = true;
foreach ($formParams as $key => $val){
if(!$first){
$buffer[] = "\r\n";
}else{
$first = false;
}
$buffer[] = "--";
$buffer[] = $this->boundary;
$buffer[] = "\r\n";
$buffer[] = "Content-Disposition: form-data; name=\"";
$buffer[] = strval($key);
$buffer[] = "\"\r\n\r\n";
$buffer[] = strval($val);
}
$buffer = implode('', $buffer);
$contentLength += strlen($buffer);
$buffers[] = $buffer;
/**
* 構造描述
*/
$buffer = [];
$buffer[] = "\r\n";
$buffer[] = "--";
$buffer[] = $this->boundary;
$buffer[] = "\r\n";
$buffer[] = "Content-Disposition: form-data; name=\"file\"; filename=\"";
$buffer[] = $fileName;
$buffer[] = "\"\r\n";
$buffer[] = "Content-Type: " . $this->file->getClientMediaType();
$buffer[] = "\r\n\r\n";
$buffer = implode('', $buffer);
$contentLength += strlen($buffer);
$buffers[] = $buffer;
/**
* 構造檔案資料
*/
$buffer = [];
$fp = fopen($this->file->getRealPath(), 'r');
if($fp){
while(!feof($fp)){
$buffer[] = fgetc($fp);
}
fclose($fp);
}
$buffer = implode('', $buffer);
$contentLength += strlen($buffer);
$buffers[] = $buffer;
/**
* 結束構造
*/
$buffer = [];
$buffer[] = "\r\n--";
$buffer[] = $this->boundary;
$buffer[] = "--\r\n";
$buffer = implode('', $buffer);
$contentLength += strlen($buffer);
$buffers[] = $buffer;
$data = [
'buffers' => $buffers,
'contentLength' => $contentLength
];
return $data;
}
}
新增配置檔案config/autoload/hw.php
return [
'key' => env('OBS_ACCESS_KEY', ''),
'secret' => env('OBS_ACCESS_SECRET', ''),
'endpoint' => env('OBS_ENDPOINT', ''),
'bucket' => env('OBS_BUCKET', ''),
'obs_cdn_endpoint' => env('OBS_CDN_ENDPOINT', ''),
'obs_scheme' => env('OBS_SCHEME', 'https')
];
完成!
本作品採用《CC 協議》,轉載必須註明作者和本文連結