生活随笔
收集整理的這篇文章主要介紹了
php阿里云oss文件上传
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
php的文件上傳
文件上傳
php的文件上傳放在了$_FILES數組里,單文件和多文件上傳的區別在于$_FILES['userfile']['name']是否為數組,
不熟悉的可以讀一下官方文檔 單文件上傳、 多文件上傳
阿里云oss web直傳實踐
這里采用的是服務端簽名后上傳,沒有使用回調。
阿里云提供了一個php和前端的示例,不過有點坑人,前端采用的是plupload插件,這種demo應該使用原生js更合適啊,畢竟上傳的js插件各不相同。
使用jquery的ajax上傳時,始終上傳失敗,于是用fiddler抓包demo,才知道了上傳給oss的詳細參數格式。
吐槽完畢,下面才是正式上菜。
- 服務端生成policy,這里使用php
下面的代碼是從官方demo修改而來,可以通過Facade模式增加靜態方法,方便調用。
注意dir目錄不能使用"/"開始。下面的簽名算法來自阿里云的demo。
<?php
class OssPolicy
{private $oss_bucket ;private $oss_host;private $oss_appid;private $oss_appsecret;private $oss_expire ;//過期時間/*** OssPolicy constructor.* @param $bucket 阿里云oss的bucket* @param $host 對應bucket的host* @param $appId app_id* @param $appSecret app_secret* @param int $expire 過期時間*/public function __construct($bucket,$host,$appId,$appSecret,$expire=900) {$this->oss_expire = $expire;$this->oss_bucket = $bucket;$this->oss_host = $host;$this->oss_appid = $appId;$this->oss_appsecret = $appSecret;}private function gmt_iso8601($time) {$dtStr = date("c", $time); //格式為2016-12-27T09:10:11+08:00$mydatetime = new DateTime($dtStr);$expiration = $mydatetime->format(DateTime::ISO8601); //格式為2016-12-27T09:12:32+0800$pos = strpos($expiration, '+');$expiration = substr($expiration, 0, $pos);//格式為2016-12-27T09:12:32return $expiration."Z";}/*** @function getPolicy 獲取policy* @author * @version 1.0* @date* @param $dir 上傳目錄* @param $maxSize 最大文件大小 單位M* @param int $expireTime 過期時間* @return $array policy*/public function getPolicy($dir,$maxSize=100,$expireTime=null){$expireTime = isset($expireTime) ? $expireTime : $this->oss_expire;$end = time() + $expireTime;$expiration = $this->gmt_iso8601($end);$conditions = [];$conditions[] = array(0=>'content-length-range', 1=>0, 2=>1024*1024*$maxSize); // 最大文件大小.用戶可以自己設置 100M$start = array(0=>'starts-with', 1=>'$key', 2=>$dir); //表示用戶上傳的數據,必須是以$dir開始, 不然上傳會失敗,這一步不是必須項,只是為了安全起見,防止用戶通過policy上傳到別人的目錄$conditions[] = $start;$arr = array('expiration'=>$expiration,'conditions'=>$conditions);$policy = json_encode($arr);$base64_policy = base64_encode($policy);$string_to_sign = $base64_policy;$signature = base64_encode(hash_hmac('sha1', $string_to_sign, $this->oss_appsecret, true));$response = array();$response['accessid'] = $this->oss_appid;$response['host'] = $this->oss_host;$response['policy'] = $base64_policy;$response['signature'] = $signature;$response['expire'] = $end;$response['bucket'] = $this->oss_bucket;$response['dir'] = $dir; //這個參數是設置用戶上傳指定的前綴return $response;}
}
- 前端
過程 想后端請求policy,上傳到阿里云,成功后通知后端
不要問我代碼為啥這么亂,我不生產代碼,我只是代碼的搬運工(從阿里云demo里搬出來,稍加修改)
在用表單提交時,注冊一下提交處理的函數,取出文件,然后OssUpload()即可。
oss_accessid = ''
oss_accessoss_key = ''
oss_host = ''
oss_policyBase64 = ''
oss_signature = ''
oss_callbackbody = ''
oss_filename = ''
oss_key = ''
oss_expire = 0
g_object_name = ''
g_object_name_type = 'local_name'
OSS_FILE_NAME_TYPE_LOCAL = "local_name"
OSS_FILE_NAME_TYPE_RANDOM = "random_name"oss_now = oss_timestamp = Date.parse(new Date()) / 1000;//向服務端請求policy
function send_request() {}
//生成簽名
function get_oss_signature() {//可以判斷當前oss_expire是否超過了當前時間,如果超過了當前時間,就重新取一下.3s 做為緩沖oss_now = oss_timestamp = Date.parse(new Date()) / 1000;if (oss_expire < oss_now + 3) {body = send_request()var obj = eval("(" + body + ")");oss_host = obj['host']oss_policyBase64 = obj['policy']oss_accessid = obj['accessid']oss_signature = obj['signature']oss_expire = parseInt(obj['expire'])oss_callbackbody = obj['callback']oss_key = obj['dir']}}//隨機字符串
function random_string(len) {len = len || 32;var chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';var maxPos = chars.length;var str = '';for (i = 0; i < len; i++) {str += chars.charAt(Math.floor(Math.random() * maxPos));}return str;
}
//獲取文件名后綴
function get_suffix(filename) {pos = filename.lastIndexOf('.')suffix = ''if (pos != -1) {suffix = filename.substring(pos)}return suffix;
}
//根據文件名類型 臨時文件還是原始文件名,返回文件名
function calculate_object_name(filename) {if (g_object_name_type == 'local_name') {g_object_name = oss_key + "${filename}"}else if (g_object_name_type == 'random_name') {suffix = get_suffix(filename)g_object_name = oss_key + random_string(10) + suffix}return ''
}//把policy填充到Formdata里
function set_upload_param(file) {get_oss_signature()if (file) {calculate_object_name(file.name);var res = {'key': g_object_name,'policy': oss_policyBase64,'OSSAccessKeyId': oss_accessid,'success_action_status': '200', //讓服務端返回200,不然,默認會返回204
// 'callback': oss_callbackbody,'signature': oss_signature,};var form_data = new FormData();for ( var key in res ) {form_data.append(key, res[key]);}form_data.append("file",file);return res;}return false;}//上傳到阿里云 callBack 是用來在上傳成功后通知服務端
function OssUpload( file,fileNameType,callBack) {g_object_name_type = fileNameType;var form_data = set_upload_param(file.name);if(!form_data){alert("form_data error")return}var fileFullName = oss_host+form_data.get("key");$.ajax({url: oss_host,data: form_data,processData: false,cache: false,async: false,type:'POST',contentType: false,//這個就是了success: function (data, textStatus, request) {//textStatus === "success" 表示成功if(typeof callBack === "function") {callBack(fileFullName,form_data.get("policy"),textStatus);}},error : function(responseStr) {if(typeof callBack === "function") {callBack(fileFullName,form_data.get("policy"),responseStr.responseText);}}});
}
總結
以上是生活随笔為你收集整理的php阿里云oss文件上传的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。