• ThinkPHP5+七牛云文件操作 方法梳理


    • 背景
      近期在项目的优化过程中,注意到对七牛云存储的使用频率提高了
      同时为了减轻对项目资源服务器的流量压力
      选择将常用的图片、word 文件转储到七牛云服务器
      在此根据自己的使用经验,梳理一下核心方法的处理,方便大家的参考使用 …

    官方文档 - 【七牛云 php-SDK】


    前期处理

    • composer 安装
      php composer.phar require qiniu/php-sdk
    
    • 1

    实现方法

    根据项目需求,在此整理几个核心的操作方法

    1. 抓取 web上的图片,上传七牛云服务器

    • 示例:
      $save_path = 'uploads/'.date('Ymd',time()).'/'.microtime(true).'.png';
    	/**
         * 抓取 web上的图片,上传七牛云服务器
         * @param $imgUrl web 图片地址
         * @param string $saveImgPath 保存到七牛云的地址
         * @return string
         */
        public function uploadWebImgToQiniu($imgUrl,$saveImgPath = '')
        {
            #读取网上图片内容
            $imageData = self::getSslPage($imgUrl);
            $auth  = new Auth($this->accessKey, $this->secretKey);
            $token = $auth->uploadToken($this->bucket);
            $key   = $saveImgPath;
    
            $up    = new UploadManager();
            $mime  = 'image/jpeg';
            list($rest, $err) = $up->put($token, $key, $imageData, null, $mime);
            if ($err) {
                return '';
            } else {
                $host = config('cdn.Host');
                return $host.'/'.$rest['key'];
            }
        }
        
        /**
         * 抓取网上图片 web image
         * @param $url
         * @return bool|string
         */
        public function getSslPage($url) {
            if(!empty($slika)){
                file_put_contents('vest1.webp', $slika);
            }
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_HEADER, false);
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_REFERER, $url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            $result = curl_exec($ch);
            curl_close($ch);
            return $result;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    2. 将服务器上的文件 上传到七牛云服务器

    • 场景:以我们的实际项目为例,对用户的订单审核通过后,会生成一份 word文件
      然后上传的七牛云,数据表中会记录下文件地址
      方便后期,直接下载查看
        /**
         * 将服务器上的文件 上传到七牛云服务器
         * @param string $file_name
         * @param string $file_from_path
         * @param string $file_to_path
         * @param string $ext_name
         * @return mixed|string
         * @throws Exception
         */
        private function uploadServerFileToQiniu($file_name = '',$file_from_path = '',$file_to_path = '',$ext_name = 'txt')
        {
            $auth = $this->getQiniuAuth();
            // 生成上传Token
            $token = $auth->uploadToken($this->bucket);
            // 构建 UploadManager 对象
            $uploadMgr = new UploadManager();
            // 上传文件到七牛
            if (empty($file_name)){
                $file_name = md5(uniqid(microtime(true),true));
            }
    
            if (empty($file_to_path)){}
    
            $key = $file_to_path.'/'.$file_name.'.'.$ext_name;
    
    
            list($ret, $err) = $uploadMgr->putFile($token, $key, $file_from_path);
            if ($err !== null) {
                //上传失败
                return '';
            } else {
                //删除临时服务器 文件
                unlink($file_from_path);
                return $ret['key'];
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    3. 删除七牛云上的文件

    • 应用场景:比如存储了用户上传的头像信息,那么前期被替换的头像,就没必要保存了
      可以将原先的头像地址记录到数据表
      编写计划任务,每天删除一下无效的文件
    /**
         * 删除文件
         * @param string $file_key
         * @return int 1:删除成功 ,0:删除失败
         */
        public function deleteQiniuFile($file_key = ''){
            $auth = new Auth($this->accessKey, $this->secretKey);
            $config = new \Qiniu\Config();
            $bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
            $err = $bucketManager->delete($this->bucket, $file_key);
            if ($err) {
                return 0;
            }else{
                return 1;
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    4. 将七牛云中的多个文件,压缩包存储

    • 场景:七牛云服务器中已存储了多个 word 稿件文本
      此时需要将这些文本压缩为一个 .rar 文件,方便运营人员一次性下载
      调用该方法, 记录生成的 压缩文件链接
        /**
         * 生成word稿件压缩包
         * @param string $task_idstr
         * @param int $index
         * @param array $picture_arr
         * @return array
         */
        public function createWordFileRar($task_idstr = '',$index = 1,$picture_arr = []){
    
            $zipKey = "task_words/{$task_idstr}_{$index}.zip";
    
            //组装七牛云请求参数
            $fops = 'mkzip/2';
            //每十个文件,作为一个压缩包
    
            foreach ($picture_arr as $key_ => $val) {
                //添加图片重命名
                $fops .= '/url/'.\Qiniu\base64_urlSafeEncode($val);
            }
            $key = $this->fileKey;  //mode = 2时,仅仅为符合pfop操作的接口规格而存在,并没有实际的意义,但需要是操作空间中存在的资源的 key
    
            $fops .= '|saveas/' . \Qiniu\base64_urlSafeEncode("$this->bucket:$zipKey");
            $result = $this->picMkzip($key, $fops);
            $result['qiniu_url'] = $zipKey;
    
            return $result;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    附录

    根据业务开发过程中遇到的问题,在此做下梳理,方便大家避雷

    问题1 . 七牛云文件上传延时

    • 当调用七牛云上传文件接口时,可能会出现一种情况:
    场景描述:
    	我指定要存储的压缩文件名为 'hello-1122337.rar';
    	当数据发生变动后,我先删除这个文件,然后再重新生成一份,如此一来压缩文件的名称就没必要变动了
    	但是我发现,执行逻辑后的压缩文件并不是最新的!
    
    	另一种情况,我要生成的压缩文件较大(500M左右)
    	测试生成时间要6~10秒
    	我想每两秒去检查下是否生成完毕
    	结果参考使用了网上很多的 判断web文件是否存在的方法
    	即便实际情况6秒生成(七牛云后台都能看到文件了,甚至可以下载),但是检测方法直到20秒后才判断生成了
    	这显然不能满足我的业务需求
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    问题分析:

    1. 七牛云服务器对同名文件有缓存,实际上并不会真实删除,当检测到文件同名时对已删除文件有复原的处理(猜测)
    2. 或者网上的判断文件是否存在的方法存在bug (排除,毕竟不可能都错吧)
    3. 本地设计的 while 循环判断时,同一个方法的调用存在缓存情况 (极有可能)
    • 解决方案
      回想以前的开发经验,在读取 html 页面时,后面添加个随机字符串就会避免缓存
      所以,在检查文件是否存在时,
      每次对文件路径加一个随机数,避免与前面的链接相同
      发现,顺利的解决的判断需求

      代码截图如下:

    • 补充一下 curl 检测图片资源方法
    /**
     * php使用 curl 判断404
     * @param string $url
     * @return bool
     */
    function check_url($url = ''){
        stream_context_set_default(
            array(
                'http' => array(
                    'timeout' => 5,
                )
            )
        );
        $header = get_headers($url,1);
        if(strpos($header[0],'200')){
            return true;
        }
        if(strpos($header[0],'404')){
            return false;
        }
        if (strpos($header[0],'301') || strpos($header[0],'302')) {
            if(is_array($header['Location'])) {
                $redirectUrl = $header['Location'][count($header['Location'])-1];
            }else{
                $redirectUrl = $header['Location'];
            }
            return check_url($redirectUrl);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
  • 相关阅读:
    OpenCV(三十四):轮廓外接最大、最小矩形和多边形拟合
    php服务端 和 python 爬虫 结合 user-agent
    PGL图学习之图神经网络ERNIESage、UniMP进阶模型[系列八]
    C++中的static和extern关键字
    Self-Attention:初步理解
    HTML5播放 M3U8的hls流地址
    支持向量机 (SVM) 算法详解
    DXF笔记:根据法向量,求出位置矩阵或坐标系
    关于汽车维修类中译英的英语翻译
    线性表的线性表示;初始化,输出,插入,删除,查找;
  • 原文地址:https://blog.csdn.net/u011415782/article/details/126730084