oss文件上傳與簽名
相信大家日常開發中,經常使用到云文件的上傳與下載等功能,而國內常用的阿里云和華為云,laravel 自帶的 Storage 默認并未進行友好支持。
剛好最近云遷移過程中的各種惡心,主要涉及上傳與簽名接口。特地記錄下 OSS 云環境文件上傳與簽名的重點代碼,以供參考。
相關包安裝命令:
需注意包版本,是否與 php 版本適用。
.env 配置項:
#?OSS相關配置 OSS_DRIVER=HW_OBS #華為OBS OSS_HW_ENDPOINT=https://obs.cn-east-3.myhuaweicloud.com OSS_HW_KEY=ME0AVBTNJTSJB2LH0EGI OSS_HW_SECRET=eCGffrwdx3Rt5QEmKbtEvruvGgg1mCUjMsnHfjWo OSS_HW_BUCKET=pub-obs-test-1 #阿里云 OSS_ENDPOINT=https://oss-cn-hangzhou.aliyuncs.com OSS_KEYID=LTAI4Ftno9DsfiVHADX73osa OSS_KEYSECRET=vo9KuqgaDN727eOOz1tDg77Egeg7wE OSS_BUCKET=xgimi-ipr
代碼:
1. 接口聲明
<?php namespace AppServiceOSS; interface IOSS { /** * 上傳 * * @param $fullFileName * @param $filePath * @return mixed */ public function publicUpload($fullFileName, $filePath); /** * url驗簽、下載 * * @param $fullFileName | 含前綴的完整url文件名 * @param $expires | 過期時效 * @return mixed */ public function getUrl($fullFileName, $expires); /** * 可替換url域名 * * @param $url * @return mixed */ public function replaceUrl($url); }
2. 阿里 OSS 實現
<?php namespace AppServiceOSS; use OSSOssClient; class AliOSS implements IOSS { private $endPoint; private $keyId; private $secret; private $bucket; private $ossClient; private $expires = 3 * 24 * 3600; private $aliHost = ''; private $myHost = ''; public function __construct() { $this->endPoint?=?env("OSS_ENDPOINT"); ????????$this->keyId?=?env("OSS_KEYID"); ????????$this->secret?=?env("OSS_KEYSECRET"); ????????$this->bucket?=?env("OSS_BUCKET"); ????????try?{ ????????????$this->ossClient?=?new?OssClient($this->keyId,?$this->secret,?$this->endPoint); ????????}?catch?(Exception?$e)?{ ????????} ????} ????/** ?????*?上傳 ?????* ?????*?@param?$fullFileName ?????*?@param?$filePath ?????*?@return?mixed ?????*?@throws?Exception ?????*/ ????public?function?publicUpload($fullFileName,?$filePath) ????{ ????????return?$this->ossClient->uploadFile($this->bucket,?$fullFileName,?$filePath); ????} ????/** ?????*?url驗簽、下載 ?????* ?????*?@param?$fullFileName ?????*?@param?$expires?|???過期時效 ?????*?@return?mixed ?????*?@throws?Exception ?????*/ ????public?function?getUrl($fullFileName,?$expires) ????{ ????????$expires?=?$expires???$expires?:?$this->expires; ????????$signUrl?=?$this->ossClient->signUrl($this->bucket,?$fullFileName,?$expires); ????????return?$signUrl; ????} ????/** ?????*?替換url域名 ?????* ?????*?@param?$url ?????*?@return?mixed ?????*/ ????public?function?replaceUrl($url) ????{ ????????return?str_replace($this->aliHost,?$this->myHost,?$url); ????} }
3. 華為 OBS 實現
<?php namespace AppServiceOSS; use ObsObsClient; class HuaweiOBS implements IOSS { private $endPoint; private $key; private $secret; private $bucket; private $obsClient; private $expires = 3 * 24 * 3600; private $hwHost = ''; private $myHost = ''; public function __construct() { $this->endPoint?=?env("OSS_HW_ENDPOINT"); ????????$this->key?=?env("OSS_HW_KEY"); ????????$this->secret?=?env("OSS_HW_SECRET"); ????????$this->bucket?=?env("OSS_HW_BUCKET"); ????????try?{ ????????????$this->obsClient?=?new?ObsClient(['key'?=>?$this->key,?'secret'?=>?$this->secret,?'endpoint'?=>?$this->endPoint]); ????????}?catch?(Exception?$e)?{ ????????} ????} ????/** ?????*?上傳 ?????* ?????*?@param?$fullFileName ?????*?@param?$filePath ?????*?@return?mixed ?????*/ ????public?function?publicUpload($fullFileName,?$filePath) ????{ ????????$res?=?$this->obsClient->putObject([ ????????????'Bucket'?=>?$this->bucket, ????????????'Key'?=>?$fullFileName, ????????????'SourceFile'?=>?$filePath ????????]); ????????return?$res; ????} ????/** ?????*?url驗簽、下載 ?????* ?????*?@param?$fullFileName ?????*?@param?$expires?|???過期時效 ?????*?@return?mixed ?????*?@throws?Exception ?????*/ ????public?function?getUrl($fullFileName,?$expires) ????{ ????????$expires?=?$expires???$expires?:?$this->expires; ????????//?生成下載對象的帶授權信息的URL ????????$res?=?$this->obsClient->createSignedUrl([ ????????????'Method'?=>?'GET', ????????????'Bucket'?=>?$this->bucket, ????????????'Key'?=>?$fullFileName, ????????????'Expires'?=>?$expires ????????]); ????????return?$res['SignedUrl']; ????} ????/** ?????*?替換url域名 ?????* ?????*?@param?$url ?????*?@return?mixed ?????*/ ????public?function?replaceUrl($url) ????{ ????????return?str_replace($this->hwHost,?$this->myHost,?$url); ????} }
Demo: 業務邏輯 + OSS 類
<?php namespace AppService; class UploadFile { /** * 文件上傳 帶簽名訪問 * * @param $files * @param string $prefix * @return array * @throws Exception */ public static function upload($files, $prefix = '') { if (empty($files)) { return ['ok' =>?false,?'message'?=>?'請上傳文件!']; ????????} ????????if?(is_array($files))?{ ????????????$pics?=?[]; ????????????foreach?($files?as?$key?=>?$file)?{ ????????????????if?($file->isValid())?{ ????????????????????$name?=?$file->getClientOriginalName(); ????????????????????$fullName?=?OSS::getFullFileName($name,?$prefix); ????????????????????$ret?=?OSS::publicUpload($fullName,?$file,?$prefix); ????????????????????if?($ret)?{ ????????????????????????$url?=?OSS::getUrl($fullName); ????????????????????????$url?=?OSS::replaceUrl($url); ????????????????????????$pics[]?=?['name'?=>?$name,?'url'?=>?$url,?'file_name'?=>?$fullName]; ????????????????????} ????????????????}?else?{ ????????????????????return?['ok'?=>?false,?'message'?=>?'無效文件!']; ????????????????} ????????????} ????????????if?(count($pics)?>?0)?{ ????????????????return?['ok'?=>?true,?'data'?=>?$pics]; ????????????} ????????}?else?{ ????????????$name?=?$files->getClientOriginalName(); ????????????$fullName?=?OSS::getFullFileName($name,?$prefix); ????????????$ret?=?OSS::publicUpload($fullName,?$files,?$prefix); ????????????if?($ret)?{ ????????????????$url?=?OSS::getUrl($fullName); ????????????????$url?=?OSS::replaceUrl($url); ????????????????return?['ok'?=>?true,?'data'?=>?['name'?=>?$name,?'url'?=>?$url,?'file_name'?=>?$fullName]]; ????????????}?else?{ ????????????????return?['ok'?=>?false,?'message'?=>?'無效文件!']; ????????????} ????????} ????} }
<?php namespace AppService; use AppServiceOSSAliOSS; use AppServiceOSSHuaweiOBS; use Exception; class OSS { const DEFAULT_DRIVER = 'HW_OBS'; const OSS_PREFIX = 'oss/'; public $OSSService; /** * 初始化 service */ public function __construct() { if (env('OSS_DRIVER') === self::DEFAULT_DRIVER) { $this->OSSService?=?new?HuaweiOBS(); ????????}?else?{ ????????????$this->OSSService?=?new?AliOSS(); ????????} ????} ????public?static?function?getInstance() ????{ ????????return?new?self(); ????} ????/** ?????*?使用外網上傳文件 ?????* ?????*?@param?$fullName ?????*?@param?$filePath ?????*?@param?$prefix ?????*?@return?mixed ?????*?@throws?Exception ?????*/ ????public?static?function?publicUpload($fullName,?$filePath,?$prefix) ????{ ????????return?self::getInstance()->OSSService->publicUpload($fullName,?$filePath); ????} ????/** ?????*?獲取oss圖片url ?????* ?????*?@param?$fullName ?????*?@param?$expires?|????過期時效 ?????*?@return?string ?????*?@throws?Exception ?????*/ ????public?static?function?getUrl($fullName,?$expires?=?'') ????{ ????????return?self::getInstance()->OSSService->getUrl($fullName,?$expires); ????} ????/** ?????*?替換url域名 ?????* ?????*?@param?$url ?????*?@return?mixed ?????*/ ????public?static?function?replaceUrl($url) ????{ ????????return?self::getInstance()->OSSService->replaceUrl($url); ????} ????/** ?????*?獲取完整的文件名含路徑 ?????* ?????*?@param?$fileName ?????*?@param?$prefix ?????*?@return?string ?????*/ ????public?static?function?getFullFileName($fileName,?$prefix) ????{ ????????return?self::OSS_PREFIX?.?$prefix?.?self::setFileName($fileName); ????} ????/** ?????*?設置新的文件名(重命名規則) ?????* ?????*?@param?$fileName ?????*?@return?string ?????*/ ????public?static?function?setFileName($fileName) ????{ ????????$nameArray?=?explode('.',?$fileName); ????????$extension?=?$nameArray[count($nameArray)?-?1]; ????????$newName?=?date('Ymd')?.?'/'?.?date('YmdHis')?.?rand(10000,?99999)?.?'.'?.?$extension; ????????return?$newName; ????} }
有時間可以對其進行功能接口補充,豐富更多云接口能力。
附:
composer 包:https://packagist.org/packages/league/flysystem
composer?require?league/flysystem
spring mvn 包:https://spring-file-storage.xuyanwu.cn/#/ | https://spring-file-storage.xuyanwu.cn/#/
推薦學習:《laravel視頻教程》
? 版權聲明
文章版權歸作者所有,未經允許請勿轉載。
THE END