上傳文件至阿里雲OSS,整體邏輯是,文件先臨時上傳到本地,然后在上傳到OSS,最后刪除本地的臨時文件(也可以不刪,具體看自己的業務需求),具體實現流程如下:
1、下載阿里雲OSS對象上傳SDK(PHP版) 通過Github下載
2、解壓后,可自行修改目錄名稱,以下為本人項目實例(aliyun_oss改過之后的名稱)
項目目錄結構如下:

3、Index.php 為文件上傳靜態表單頁
4、do_upload.php 為文件處理控制頁,封裝的代碼如下:上傳文件相關的輔助函數可以自行封裝,本文是為了便於展示,全部放在一個文件中
1 <?php 2 /** 3 * @Class: do_upload.php 4 * @Description: 控制器 5 * @Date: 2019/10/16 6 */ 7 header("Content-Type:text/html;charset=utf-8"); 8 set_time_limit(0); 9 // error_reporting(E_ALL); 10 require __DIR__.'/AliyunOss.php'; 11 if(!empty($_FILES['oss_file']) && !empty($_POST['type'])){ 12 $file_arr = getFiles(); 13 $AliyunOss = new AliyunOss(); 14 foreach ($file_arr as $file){ 15 $res = upload_File($file,$type_name.'/'.$user_info['contact'],$user_info); 16 if(isset($res['fname']) && isset($res['dest']) && isset($res['file_name'])){ 17 $result = $AliyunOss->upload_file($res['dest'],$res['fname']); 18 if($result){ 19 //1、存入數據庫 此處部分變量及入庫代碼補全 知道邏輯即可 20 $insert_time = date('Y-m-d H:i:s',time()); 21 $fileData = array( 22 'phone' => "'{$phone}'", 23 'company_name' => "'{$oss_db->escape($user_info['contact'])}'", 24 'insert_time' => "'{$insert_time}'", 25 'file_name' => "'{$res['file_name']}'", 26 'file_url' => "'{$result['oss_file']}'" 27 ); 28 $sql = "insert into `oss_file` (".implode(',', array_keys($fileData)).") values (".implode(',', array_values($fileData)).")"; 29 $oss_db->query($sql); 30 if($oss_db->insert_id()){ 31 //2、刪除臨時文件 32 unlink($res['dest']); 33 } 34 } 35 } 36 } 37 echo '上傳成功'; 38 header('Location:list.php'); 39 die; 40 }else{ 41 echo '上傳失敗'; 42 } 43 44 /** 45 * 文件上傳 46 * @description 47 * @param $file 48 * @param string $path 49 * @param $max_size 50 * @param $allowExt 51 * @return mixed 52 */ 53 function upload_File($file,$oss_dir = '',$user_info,$path = __DIR__.'/temp'){ 54 $filename=$file['name']; 55 $temp_name=$file['tmp_name']; 56 $error=$file['error']; 57 $res = []; 58 if ($error==UPLOAD_ERR_OK) { 59 // if ($size>$max_size) { 60 // $res['mes']=$filename."文件超過規定上傳大小"; 61 // } 62 $ext = getExt($filename); 63 if (in_array($ext, array('exe'))) { 64 $res['mes']=$filename.'非法的文件'; 65 } 66 if (!is_uploaded_file($temp_name)) { 67 $res['mes']=$filename."文件不是通過HTTP POST 方法上傳上傳過來的"; 68 } 69 70 if ($res) { 71 return $res; 72 } 73 74 if (!file_exists($path)) { 75 mkdir($path,0777,true); 76 chmod($path, 0777); 77 } 78 $fname = getUniName($filename,$user_info); 79 $destination = $path.'/'.$fname.'.'.$ext; 80 if (move_uploaded_file($temp_name, $destination)) { 81 $res['mes'] = $filename.'上傳成功'; 82 $res['dest'] = $destination; 83 $res['fname'] = $oss_dir.'/'.$fname.'.'.$ext; 84 $res['file_name'] = $fname.'.'.$ext; 85 }else{ 86 $res['mes']=$filename."文件上傳失敗"; 87 } 88 }else{ 89 switch ($error) { 90 case '1': 91 $res['mes']="超過了配置文件上傳文件的大小"; 92 break; 93 case '2': 94 $res['mes']="超過表單設置上傳文件文件的大小"; 95 break; 96 case '3': 97 $res['mes']="文件部分被上傳"; 98 break; 99 case '4': 100 $res['mes']="沒有文件被上傳"; 101 102 break; 103 case '6': 104 $res['mes']="沒有找到臨時目錄"; 105 break; 106 case '7': 107 $res['mes']="文件不可寫"; 108 109 break; 110 default: 111 $res['mes']="上傳文件失敗"; 112 break; 113 } 114 } 115 116 return $res; 117 118 } 119 /** 120 * 獲得文件擴展名 121 * @param string $filename 上傳文件名 122 * @return string 返回擴展名 123 */ 124 function getExt($filename){ 125 $arr=explode('.', basename($filename)); 126 127 return end($arr); 128 } 129 /** 130 * 獲得文件唯一擴展名 131 * @return string 經過md5后生成32位唯一的上傳文件名 132 */ 133 function getUniName($fileName, $user_info) 134 { 135 $new_fileName = substr($fileName,0,strrpos($fileName,'.')); 136 $oss_db = new data_base('10.1.51.64', 'root', 'abc@123456', 'dahua_oss'); 137 $has_file = $oss_db->getRow("select * from `oss_file` where `phone` = '{$user_info['phone']}' and locate('{$fileName}',`file_url`)>0 "); 138 if ($has_file) { 139 $new_fileName .= '-1'; 140 } 141 return $new_fileName; 142 } 143 144 /** 145 * 整理多個文件 146 * @description 147 * @return mixed 148 */ 149 function getFiles(){ 150 $files = array(); 151 foreach($_FILES as $file){ 152 $fileNum=count($file['name']); 153 for ($i=0; $i < $fileNum; $i++) { 154 $files[$i]['name']=$file['name'][$i]; 155 $files[$i]['type']=$file['type'][$i]; 156 $files[$i]['tmp_name']=$file['tmp_name'][$i]; 157 $files[$i]['error']=$file['error'][$i]; 158 $files[$i]['size']=$file['size'][$i]; 159 } 160 } 161 return $files; 162 } 163 164 ?>
5、AliyunOss.php OSS文件上傳接口類
1 <?php 2 /** 3 * @Class: AliyunOss.php 4 * @Description: 控制器 5 * @Date: 2019/10/16 6 */ 7 header("Content-Type:text/html;charset=utf-8"); 8 // error_reporting(E_ALL); 9 10 if (is_file(__DIR__ . '/aliyun_oss/autoload.php')) { 11 require_once __DIR__ . '/aliyun_oss/autoload.php'; 12 } 13 14 use OSS\OssClient; 15 use OSS\Core\OssException; 16 17 // 阿里雲主賬號AccessKey擁有所有API的訪問權限,風險很高。強烈建議您創建並使用RAM賬號進行API訪問或日常運維,請登錄 https://ram.console.aliyun.com 創建RAM賬號。 18 19 class AliyunOss 20 { 21 private $accessKeyId; 22 private $accessKeySecret; 23 private $endpoint; 24 private $bucket; 25 26 public function __construct() 27 28 { 29 require_once __DIR__ . '/aliyun_oss/config.php'; 30 $this->accessKeyId = $oss_config['accessKeyId']; 31 $this->accessKeySecret = $oss_config['accessKeySecret']; 32 // Endpoint以杭州為例,其它Region請按實際情況填寫。 $endpoint="http://oss-cn-hangzhou.aliyuncs.com"; 33 $this->endpoint = $oss_config['endpoint']; 34 // 存儲空間名稱 35 $this->bucket = $oss_config['bucket']; 36 } 37 //$file_path oss文件名稱 (支持中文如:商務/科技/項目計划.doc)會自動創建目錄
//$file_name 由本地文件絕對路徑加文件名包括后綴組成,例如/users/local/myfile.txt 38 public function upload_file($file_path, $file_name) 39 { 40 try { 41 $ossClient = new OssClient($this->accessKeyId, $this->accessKeySecret, $this->endpoint); 42 $result = $ossClient->uploadFile($this->bucket, $file_name, $file_path);//$result['info']['url'] 返回上傳成功的oss文件地址 43 $arr = array( 44 'oss_file' =>$result['info']['url'], 45 'local_path' => $file_name 46 ); 47 return $arr; 48 } catch (OssException $e) { 49 // printf(__FUNCTION__ . ": FAILED\n"); 50 // printf($e->getMessage() . "\n"); 51 log_msg('文件上傳失敗',$e->getMessage()); 52 log_msg('文件上傳失敗',$file_path.'---'.$file_name); 53 return false; 54 } 55 } 56 }
至此,OSS文件上傳就完成了,具體使用過程中有什么問題,可隨時反饋,同時也歡迎提出各種建議,謝謝!
