阿里oss儲存API介面封裝呼叫(PHP)
阿新 • • 發佈:2019-02-08
這篇是php後臺封裝的OSS物件儲存API介面類
<?php /** * OSS 阿里雲平臺上傳刪除介面 * 使用前請進行一些必須的設定 在bucket屬性裡 設定該讀寫許可權(ACL)為 公共讀 要不然上傳的圖片無法顯示 * Cors設定 一般是 post方法,自己根據情況而設定,要不然上傳不了圖片或檔案,我設定為 GET POST 來源使用* * @author jorsh 20160127 * **/ class Ossupload{ public $ossconfig = array( 'id'=>'LTA******X5h', //Access Key ID 'key'=>'6dLVH###########bIdxf6nh', //Access Key Secret 'bucketname'=>'yix####ng', //bucket名稱 刪除時需要填坑 'host'=>'http://filename.yixiansheng.com', //上傳提交地址 格式:bucketname+區別+阿里的域名 列如:http://d****a-t.img-cn-beijing.aliyuncs.com/ 'expire' => 30, //過期時間 'callback_body' => array( 'callbackUrl'=>'', //回撥地址全地址含有引數 'callbackHost'=>'', //回撥域名 'callbackBody'=>'filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}', //阿里返回的圖片資訊 'callbackBodyType'=>'application/x-www-form-urlencoded', //設定阿里返回的資料格式 ), 'maxfilesize'=>10485760, //限制上傳檔案大小 這裡是10M 'imghost' =>'http://d****a-t.img-cn-beijing.aliyuncs.com/', //前臺顯示圖片的地址 格式不多說 ); public function _initialize() { $this->ossconfig['callback_body']['callbackUrl']='http://'.$_SERVER['HTTP_HOST'].'/s****n.php/ossupload/cupload/'; //初始化回撥地址 $this->ossconfig['callback_body']['callbackHost']=$_SERVER['HTTP_HOST']; //初始化回撥域名 } //獲取policy和回撥地址 一般使用jajx或是在載入頁面的時候會用到policy和回撥地址,還有傳限制大小等 public function getpolicy(){ //過期時間 不得不說那個T和Z這個得注意(阿里demo的那個函式不知道就是使用不了,我這樣是可以使用的) $expire = $this->ossconfig['expire']+time(); $expire = date('Y-m-d').'T'.date('H:i:s').'Z'; //$expiration = $this->gmt_iso8601($expire); //獲取上傳的路徑 $dir = $this->uploadpath(I('path')); //這裡要獲得上傳的路徑有一個引數path 具體看uploadpath這個方法,根據專案自己設定 //這個就是policy $policy = array( 'expiration' =>$expire, //過期時間 'conditions' =>array( 0=>array(0=>'content-length-range', 1=>0, 2=>$this->ossconfig['maxfilesize']), //限制上傳檔案的大小 1=>array(0=>'starts-with', 1=>'$key', 2=>$dir), //這裡的'$key' 一定要注意 ), ); //上面的'$key' 自定義使用哪個引數來做上傳檔案的名稱. //而這個'$key'並不是一個值,只是告訴OSS伺服器使用哪個引數來作為上傳檔案的名稱 //注意是全路徑,比如前端上傳圖片的使用提交的地址中&key=upload/images/20160127${filename} //那麼在上傳圖片的時候就要拼接出key的路徑然後和圖片一起提交給oss伺服器 //你上傳的圖片的名子是5566.png ,那麼儲存在oss的圖片路徑 就是upload/images/201601275566.png; //而後面的$dir 就是upload/images/ $policy = base64_encode(json_encode($policy)); $signature = base64_encode(hash_hmac('sha1', $policy, $this->ossconfig['key'], true)); //簽名演算法 $res = array( 'accessid'=>$this->ossconfig['id'], 'host' =>$this->ossconfig['host'], 'policy' => $policy, 'signature'=>$signature, 'expire' =>$expire, 'callback' =>base64_encode(json_encode($this->ossconfig['callback_body'])), 'dir' =>$dir, 'filename' =>md5(date('YmdHis').rand(1000,9999)), //我這裡使用時間和隨時資料作為上傳檔案的名子 'maximgfilesize'=>307200, //前端JS判斷 可以上傳的圖片的大小 這裡是300K ); $this->ajaxReturn(array('status'=>0, 'msg'=>'', 'config'=>$res),'json'); } //回撥處理方法 這裡使用OSS demo裡的東西,但demo裡有個坑就是一定要告訴其內容長度 content-lenght的值具體看 _msg()方法 //這裡面還有一些設定可以檢視OSS介面說明的地方,我這裡沒有設定,可以獲到頭部的資訊 public function cupload(){ $authorizationBase64 = ''; $pubKeyUrlBase64 = ''; if(isset($_SERVER['HTTP_AUTHORIZATION'])){ $authorizationBase64 = $_SERVER['HTTP_AUTHORIZATION']; } if (isset($_SERVER['HTTP_X_OSS_PUB_KEY_URL'])){ $pubKeyUrlBase64 = $_SERVER['HTTP_X_OSS_PUB_KEY_URL']; } if ($authorizationBase64 == '' || $pubKeyUrlBase64 == ''){ //header("http/1.1 403 Forbidden"); $this->_msg(array("Status"=>"error",'msg'=>'上傳失敗,請重新上傳')); } //獲取OSS的簽名 $authorization = base64_decode($authorizationBase64); //獲取公鑰 $pubKeyUrl = base64_decode($pubKeyUrlBase64); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $pubKeyUrl); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); $pubKey = curl_exec($ch); curl_close($ch); if ($pubKey == ""){ //header("http/1.1 403 Forbidden"); $this->_msg(array("Status"=>"error",'msg'=>'上傳失敗,請重新上傳')); } //獲取回撥body $body = file_get_contents('php://input'); //拼接待簽名字串 $authStr = ''; $path = $_SERVER['REQUEST_URI']; $pos = strpos($path, '?'); if ($pos === false){ $authStr = urldecode($path)."\n".$body; }else{ $authStr = urldecode(substr($path, 0, $pos)).substr($path, $pos, strlen($path) - $pos)."\n".$body; } //驗證簽名 $ok = openssl_verify($authStr, $authorization, $pubKey, OPENSSL_ALGO_MD5); if ($ok == 1){ //增加對上圖片的型別的判斷 if(!in_array(I('mimeType'), array('image/png', 'image/gif', 'image/jpeg'))){ $this->_msg(array("Status"=>"error",'msg'=>'不支援的檔案型別')); } //if(I('size')>$this->ossconfig['maxfilesize']){ if(I('size')>512000){ $this->_msg(array("Status"=>"error",'msg'=>'上傳圖片過大,無法上傳')); } $this->_msg(array("Status"=>"Ok",'msg'=>'','pic'=>$this->ossconfig['imghost'].I('filename'))); }else{ //header("http/1.1 403 Forbidden"); $this->_msg(array("Status"=>"error",'msg'=>'上傳失敗,請重新上傳')); } } //返回要上傳的路徑 注意這裡的路徑 最前最不要有/符號,否則會出錯 public function uploadpath($type){ switch ($type) { case '1': $patch = 'Upload/images/'; break; default: # code... break; } return $patch; } public function gmt_iso8601($time) { $dtStr = date("c", $time); $mydatetime = new DateTime($dtStr); $expiration = $mydatetime->format(DateTime::ISO8601); $pos = strpos($expiration, '+'); $expiration = substr($expiration, 0, $pos); return $expiration."Z"; } public function _msg($arr){ $data = json_encode($arr); header("Content-Type: application/json"); header("Content-Length: ".strlen($data)); exit($data); } //刪除圖片或檔案資訊 這裡有個坑就簽名演算法這塊 //這個刪除是單一檔案刪除,估計批量刪除可以就沒有問題了 //單一圖片刪除使用delete 所以傳遞的內容為空,就不要使用md5加密 //然後刪除成功了,OSS服務不返回任務內容 坑 //還有就是地址這塊在算簽名的時候一定要加個bucketname這點最坑 public function delosspic($picurl){ if(empty($picurl)){ return array('status'=>1, 'msg'=>'要刪除的圖片不能為空'); } if(strpos($picurl, $this->ossconfig['host'])===false){ $picurl = trim($picurl,'/'); $url = $this->ossconfig['host'].'/'.$picurl; $picurl = '/'.$this->ossconfig['bucketname'].'/'.$picurl; //一定要加上 bucketname 坑啊,官方沒有說明 }else{ $url = $picurl; $picurl = str_replace($this->ossconfig['host'], '', $picurl); $picurl = trim($picurl, '/'); $picurl = '/'.$this->ossconfig['bucketname'].'/'.$picurl; } $gtime = gmdate("D, d M Y H:i:s").' GMT'; //一定要使用 http 1.1 標準時間格式 //簽名演算法不多說官網的例子也只能無語,沒有PHP版的。本人這個可以使用驗證通過,可以正常刪除檔案 $signature = base64_encode(hash_hmac('sha1',"DELETE\n\ntext/html\n".$gtime."\n".$picurl, $this->ossconfig['key'], true)); //傳遞頭這裡也是坑 上面使用了 text/html靠,在協議頭裡還得加上,要不然會提示出錯。 $headers = array( 'Authorization: OSS '.$this->ossconfig['id'].':'.$signature, 'Date:'.$gtime, //靠時間也得帶上 'Content-Type: text/html', //傳遞型別要與上面簽名演算法一直 ); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); //curl_setopt($ch, CURLOPT_HEADER, 1); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); $ret = curl_exec($ch); curl_close($ch); return $ret; //靠,OSS刪除檔案不返回結果,沒有返回結果就表示刪除成功,反之會有刪除出錯資訊 } }
下一篇是前端直傳OSS