PHP与Javascript上传图片到七牛

qiniu.png

PHP后端上传

用composer安装SDK

composer require teg1c/thinkphp-qiniu-sdk

如果不行的话就在目录下的composer.json的require中添加

"teg1c/thinkphp-qiniu-sdk": "dev-master"

然后执行

composer update

在config文件夹里新建一个qiniu.php配置文件

<?php
return [
    'accesskey'=>'',//你的accesskey
    'secretkey'=>'',//你的secretkey
    'bucket'=>'',//你的上传空间名称
    'url'=>''//你的空间绑定的域名
];

修改vendor/teg1c/thinkphp-qiniu-sdk文件夹下Qiniu.php文件像这样

<?php

namespace tegic\qiniu;

use Qiniu\Auth;
use Qiniu\Storage\UploadManager;
use think\Exception;

require 'qiniu_php_driver/autoload.php';

class Qiniu
{
    private $_accessKey;
    private $_secretKey;
    private $_bucket;

    private $_error;

    /**
     * Qiniu constructor.
     * @param string $accessKey
     * @param string $secretKey
     * @param string $bucketName
     * 初始化参数
     */
    public function __construct($accessKey = "", $secretKey = "", $bucketName = "")
    {
        if (empty($accessKey) || empty($secretKey) || empty($bucketName)) {
            if (empty(config('qiniu.accesskey')) || empty(config('qiniu.secretkey')) || empty(config('qiniu.bucket'))) {
                $this->_error = '配置信息不完整';
                return false;
            }
            $this->_accessKey = config('qiniu.accesskey');
            $this->_secretKey = config('qiniu.secretkey');
            $this->_bucket    = config('qiniu.bucket');
        } else {
            $this->_accessKey = $accessKey;
            $this->_secretKey = $secretKey;
            $this->_bucket    = $bucketName;
        }
    }

    /**
     * @return bool|string
     * 获取bucket
     */
    private function _getBucket()
    {
        return $this->_bucket;
    }

    /**
     * @param string $saveName
     * @param string $bucket
     * @return mixed
     * @throws Exception
     * @throws \Exception
     * 单文件上传,如果添加多个文件则只上传第一个
     */
    public function upload($saveName = '', $bucket = '')
    {
        $token = $this->_getUploadToken($bucket);

        $files = $_FILES;
        if (empty($files)) {
            throw new Exception('没有文件被上传', 10002);
        }
        $values = array_values($files);

        $uploadManager = new UploadManager();
        if (empty($saveName)) {
            $saveName = hash_file('sha1', $values[0]['tmp_name']) . time();
        }
        $infoArr         = explode('.', $values[0]['name']);
        $extension       = array_pop($infoArr);
        $fileInfo        = $saveName . '.' . $extension;
        list($ret, $err) = $uploadManager->putFile($token, $saveName, $values[0]['tmp_name']);
        if ($err !== null) {
            throw new Exception('上传出错' . serialize($err));
        }
        return $ret['key'];
    }

    public function getUploadToken()
    {
        $auth   = new Auth($this->_accessKey, $this->_secretKey);
        $upToken = $auth->uploadToken($this->_getBucket());
        return $upToken;
    }

}

引入SDK TP5.1框架vendor会自动加载

use tegic\qiniu\Qiniu;

上传

public function UpFile($file){
      $qiniu = new Qiniu();
      $key = $qiniu-> upload('要保存的图片名称','空间名');
      return json([
        "code"=>200,
        "msg"=>"上传完成",
        "data"=>"您的七牛云域名/".$key
      ]);
    }

Base64上传

public function Base64($base64){
      $base64 = trim($base64);
      $base64 = str_replace('data:image/jpeg;base64,', '', $base64); //只要逗号后面的
      $qiniu = new Qiniu();
      $token = $qiniu->getUploadToken();

      $ret = $this->request_by_curl('https://up.qiniup.com/putb64/-1', $base64, $token);
      $key = json_decode($ret, true)['key'];
      return json([
        "code"=>200,
        "msg"=>"上传完成",
        "data"=>"您的七牛云域名/".$key
      ]);
    }

public function request_by_curl($remote_server, $post_string, $upToken){
      $headers = array();
      $headers[] = 'Content-Type:image/png';
      $headers[] = 'Authorization:UpToken ' . $upToken;
      $ch = curl_init();
      curl_setopt($ch, CURLOPT_URL, $remote_server);
      //curl_setopt($ch, CURLOPT_HEADER, 0);
      curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
      //curl_setopt($ch, CURLOPT_POST, 1);
      curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string);
      curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
      curl_setopt($ch, CURLOPT_TIMEOUT, 30);
      $data = curl_exec($ch);
      curl_close($ch);

      return $data;
    }

Javascript前端上传

首先引入七牛的js

<script href="https://unpkg.com/qiniu-js@2.5.3/dist/qiniu.min.js"></script>

选择图片使用ajax上传

//上传图片
$('#upimg').on("change",
function() {
    var file = this.files[0];
    //获取上传凭证
    $.ajax({
        type: "POST",
        url: "getToken",//获取上传凭证的接口
        dataType: "json",
        data: {
            name: file.name
        },
        success: function(result) {
            var key = result.key;
            var token = result.token;
            var config = {
                region: qiniu.region.z1
            };
            var putExtra = {
                mimeType: ["image/jpg", "image/png", "image/jpeg"]
            };
            var observable = qiniu.upload(file, key, token, putExtra, config);
            observable.subscribe({
                next: (res) = >{
                    // 主要用来展示进度
                    let total = res.total;
                    console.log("进度:" + parseInt(total.percent) + "%");
                },
                error: (err) = >{
                    // 失败报错信息
                    console.log(err)
                },
                complete: (res) = >{
                    // 接收成功后返回的信息
                    console.log(res)
                }
            });
        }
    });
});

上传Base64图片

  //dataURL 是base64数据
  var pic = dataURL.replace('data:image/jpeg;base64,' ,'') //base64后的字符串
  var url = "https://upload-z1.qiniup.com/putb64/-1"; //非华东空间需要根据注意事项
  var xhr = new XMLHttpRequest();
  xhr.onreadystatechange=()=>{
    if (xhr.readyState==4){
      var dataInfo = JSON.parse(xhr.response) //将返回的字符串转化为JSON对象
      console.log(dataInfo);
    }
  }
  xhr.open("POST", url, true);
  xhr.setRequestHeader("Content-Type", "application/octet-stream");
  xhr.setRequestHeader("Authorization", 'UpToken {$token}');//替换上传token
  xhr.send(pic);

后端的凭证接口

    //返回图片上传所需要的参数
    public function getToken()
    {
        if(Request::isAjax()){
            $qiniu = new Qiniu();
            return [
                'key' => createImgName() . '-' . input('post.name'),
                'token' => $qiniu->getUploadToken()
            ];
        }
    }

推荐阅读更多精彩内容