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:32
return $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文件上传的更多相关文章

  1. 构建基于阿里云OSS文件上传服务

    转载请注明来源:http://blog.csdn.net/loongshawn/article/details/50710132 <构建基于阿里云OSS文件上传服务> <构建基于OS ...

  2. 记一次阿里云oss文件上传服务假死

    引言 记得以前刚开始学习web项目的时候,经常涉及到需要上传图片啥的,那时候都是把图片上传到当前项目文件夹下面,每次项目一重启图片就丢了.虽然可以通过修改/tomcat/conf/server.xml ...

  3. PHP实现阿里云OSS文件上传(支持批量)

    上传文件至阿里云OSS,整体逻辑是,文件先临时上传到本地,然后在上传到OSS,最后删除本地的临时文件(也可以不删,具体看自己的业务需求),具体实现流程如下:   1.下载阿里云OSS对象上传SDK(P ...

  4. SpringBoot整合阿里云OSS文件上传、下载、查看、删除

    1. 开发前准备 1.1 前置知识 java基础以及SpringBoot简单基础知识即可. 1.2 环境参数 开发工具:IDEA 基础环境:Maven+JDK8 所用技术:SpringBoot.lom ...

  5. 阿里云OSS文件上传封装

    1.先用composer安装阿里云OSS的PHPSDK 2.配置文件里定义阿里云OSS的秘钥 3.在index控制器里的代码封装 <?php namespace app\index\contro ...

  6. 记录-阿里云Oss文件上传

    public class OssUtil { /** * 上传图片 * @param file * @param request * @return */ public static Map<S ...

  7. Thinkphp整合阿里云OSS图片上传实例

    Thinkphp3.2整合阿里云OSS图片上传实例,图片上传至OSS可减少服务器压力,节省宽带,安全又稳定,阿里云OSS对于做负载均衡非常方便,不用传到各个服务器了 首先引入阿里云OSS类库 < ...

  8. SpringBoot完美配置阿里云的文件上传

    新建一个config类 AliyunOSS.java @Configuration @Data public class AliyunOSS { private OSSClient ossClient ...

  9. 阿里云OSS图片上传类

    1.阿里云基本函数 /** * 把本地变量的内容到文件 * 简单上传,上传指定变量的内存值作为object的内容 */ public function putObject($imgPath,$obje ...

随机推荐

  1. 【C语言】练习3-3

     题目来源:<The C programming language>中的习题P49  练习2-9: 编写函数expand(s1, s2),将字符串s1中类似于a-z一类的速记符号在字符串s ...

  2. C# 编写Windows Service(windows服务程序)

    C# 编写Windows Service(windows服务程序)   Windows Service简介: 一个Windows服务程序是在Windows操作系统下能完成特定功能的可执行的应用程序.W ...

  3. Inondb中的checkpoint

    checkpoint主要是为了解决一下问题: 1.缩短数据库的恢复时间 2.缓冲池不够用时,将脏页刷新到磁盘 3.重做日志不可用时,刷新脏页 Innodb引擎使用LSN(log sequence nu ...

  4. 嵌入式Linux下MP4视频录制库MP4V2移植和简单介绍

    **************************************************************************************************** ...

  5. SQL Server 2008 R2占用内存越来越大两种解决方法

    SQL Server 2008 R2运行越久,占用内存会越来越大. 第一种:有了上边的分析结果,解决方法就简单了,定期重启下SQL Server 2008 R2数据库服务即可,使用任务计划定期执行下边 ...

  6. 10.翻译:EF基础系列---EF中的持久性

    原文链接:http://www.entityframeworktutorial.net/EntityFramework4.3/persistence-in-entity-framework.aspx ...

  7. matlab入门笔记(六):编程基础之M文件

    摘自<matlab从入门到精通>胡晓东 在Matlab中,用户可以在命令行中直接输入命令,从而以一种交互式的方式来编写程序.这种方式适用于命令行比较简单,输入比较方便,同时处理的问题较少的 ...

  8. echarts legend 的单选模式以及轮播技巧

    1.设置 legend 属性: selectedMode: 'single' 2.使用 myCharts.dispatchAction 来设置legend的聚焦 broadcast (v) { // ...

  9. MySQL设置从库只读模式

    常见现象 运维工作中会经常维护MySQL主从服务器,当然Slave我们只是用于读操作. 一般权限开通也只授权只读账号,但是有时候维护工作可能不是一个人在做,你不能保证其他同事都按照这个标准操作. 有同 ...

  10. ext: gridpanel中的点击事件的参数是什么意思?

    listeners: {      // 当用户单击列表项时激发该函数      itemclick: function(view, record, item, index, evt)  //①    ...