上传文件至阿里云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文件上传就完成了,具体使用过程中有什么问题,可随时反馈,同时也欢迎提出各种建议,谢谢!