七牛上传报文件已存在

薄洪涛6年前PHP1469

之前做了一个大文件的分片上传,做好之后就没管了,让客户端一直自己用着,然后期间偶尔会有浏览器不兼容的现象我也懒得改,然后十一回来,客户端就给我说,有文件上传不上去,然后正好手头没活,就用改了下

先看下思路,这里做了分片上传,就是文件按照一小块一小块分片上传到服务器后,然后拼接,拉到七牛

拉到七牛的代码如下

/*
 * 上传到七牛
 */
public static function saveQiniuByUrl($file_url){
    $data = file_get_contents($file_url);
    //七牛的密钥、域名和空间
    $access_key = Yii::$app->params['access_key'];
    $secret_key = Yii::$app->params['secret_key'];
    $bucket = Yii::$app->params['bucket'];
    //上传7牛的文件的名字及路径
    $file_name =  basename($file_url);
    //授权
    $auth = new Auth($access_key,$secret_key);
    //生成token
    $token = $auth->uploadToken($bucket);
    $uploadManager = new UploadManager();
    list($ret,$err) = $uploadManager->put($token,$file_name,$data);
    if($err !== null){
        return false;
    }
    return Yii::$app->params['domain'].'/'.$file_name;
}

我只需要提供本地的组装好的文件的位置就可以

然后我打印了下七牛的返回

array (size=2)
  0 => null
  1 => 
    object(Qiniu\Http\Error)[89]      
    private 'url' => string 'http://up.qiniup.com' (length=20)
      private 'response' => 
        object(Qiniu\Http\Response)[88]          
        public 'statusCode' => int 614
          public 'headers' => 
            array (size=16)
              ...          
          public 'body' => string '{"error":"file exists"}' (length=23)
          public 'error' => string 'file exists' (length=11)
          private 'jsonData' => 
            array (size=1)
              ...          
              public 'duration' => float 12.178

关键的一句话,file exists

查了七牛的文档,我知道了原因,七牛判断文件是否相同是根据文件的key,即文件的名字,我上传文件到服务器后,保留了上传之前的名称,所以会出现这个问题,那我们如何避免用户上传相同key的文件呢?

七牛已经提供好了相应的算法,见 https://github.com/qiniu/qetag

算法大体如下:

  • 如果你能够确认文件 <= 4M,那么 hash = UrlsafeBase64([0x16, sha1(FileContent)])

  • 如果文件 > 4M,则 hash = UrlsafeBase64([0x96, sha1([sha1(Block1), sha1(Block2), ...])])

  • 其中 Block 是把文件内容切分为 4M 为单位的一个个块,也就是 BlockI = FileContent[I*4M:(I+1)*4M]

上传到七牛云存储的时候,key 是可选的。如果你不指定 key,则自动以 hash 值作为 key,此时自动带了消重能力。两个用户上传相同的文件,最终的 key 是一样的。

另外需要指出,当上传相同的文件时,七牛不会覆盖,只能你手动删除某个文件然后才能上传相同文件(如果你想覆盖的话)

我这里的解决就比较简单了,直接生成唯一的key拼接下就可以了

相关文章

谷歌浏览器加载前端资源status=canceled

谷歌浏览器加载前端资源status=canceled

如图,今天在做弹出框(modal中用了iframe)的时候,发现模态框弹出的时候,会有一些前端资源加载被取消,但是也会有加载时间,影响页面的加载速度;然后我尝试用火狐,发现没有这个问题经过一顿goog...

Laravel中灵活使用Trait

这次我们来学的是Trait,说到Trait ,大家的印象可能就是复用一直以来,我对复用的理解就是写一个公共类/文件,通过继承/require 来实现复用,那里需要就哪里继承/ 引用,目的就是少写代码我...

YII2独立开发遇到的坑

    之前开发的时候,遇到图片上传什么的都是直接用前辈们配好的插件等等,换了家公司以后,要自己独立开发项目,顿时遇到了问题,开始是项目的配置,然后在添加的时候遇到了图片上传的问题...

Yii2.0搭建接口模块教程

Yii2.0搭建接口模块教程

最近我需要做一个大项目中的一个模块,考虑用前后端分离,所以想自己搭建一套基于Yii2.0的restful接口出来,本来的时候老大想让我用spring boot,无奈我太菜只会php.....教程开始:...

Elasticsearch为什么搜索那么快?

Elasticsearch为什么搜索那么快?

介绍Elasticsearch 是一个分布式可扩展的实时搜索和分析引擎,一个建立在全文搜索引擎 Apache Lucene(TM) 基础上的搜索引擎.当然 Elasticsearch 并不仅仅是 Lu...

Elasticsearch第三篇之全文搜索及在Yii2.0中的使用

Elasticsearch第三篇之全文搜索及在Yii2.0中的使用

前几天做了一个模块,大数据的搜索,其实也不是特别大,组合起来差不多800万左右,用的是mysql数据库,需求有这么变态的两点;需要按照地址去搜索按照起止时间去搜索别的不说,就这两条,mysql也就只能...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。