19. Yii2使用七牛云存储

初学yii2时,不怎么理解前后台分离的思路,有一阵子还纠结怎么处理图片上传的问题。毕竟在已做过的项目中,图片都是直接上传到项目中的一个类似Public/images/*的目录中。发觉这些做法在这里行不通了,在网上也搜查过一些,比较多的答案是配置一台图片
服务器,就可以前后台访问了。后来都觉得麻烦,幸好目前在做的项目中,使用了七牛。觉得还方便一些,提供了很多通用的接口,解决了例如断点续传这样的问题。

PHP开发者地址,基本的使用文档不仅在官网提供,在源代码中也有很多有用的实例。七牛的SDK也在不断更新,要随时看最新的文档。

话不多说,直接上代码。

namespace common\extend\qiniu;

require __DIR__ . '/autoload.php';

use Qiniu\Auth;
use Qiniu\Storage\BucketManager;
use Qiniu\Storage\UploadManager;

class Upload
{
    private $accessKey;
    private $secretKey;
    private $bucket;
    private $auth;
    private $token;
    public static $instance;

    public static function getInstance()
    {
        if (empty(self::$instance)) {
            self::$instance = new self();
        }

        return self::$instance;
    }

    public function __construct()
    {
        $this->accessKey = \Yii::$app->params['qiniu']['ak'];
        $this->secretKey = \Yii::$app->params['qiniu']['sk'];
        $this->auth = new Auth($this->accessKey, $this->secretKey);
        $this->bucket = \Yii::$app->params['qiniu']['bucket'];
        $this->token = $this->auth->uploadToken($this->bucket);
    }

    /**
     * 上传一段文本内容
     * @param string $content 需要上传的文本内容
     * @return mixed ['hash' => '', 'key' => ''] 成功后的文件名保存在key=>value中
     */
    public function uploadText($content)
    {
        list($ret, $error) = (new UploadManager())->put($this->token, null, $content);
        if ($error !== null) {
            return $error;
        } else {
            return $ret;
        }
    }

    /**
     * 上传图片
     * @param string $fileName 图片名
     * @param string $filePath 图片存放路径
     * @return mixed ['hash' => '', 'key' => ''] 成功后的文件名保存在key=>value中
     * @throws \Exception
     */
    public function uploadFile($fileName, $filePath = './')
    {
        list($ret, $error) = (new UploadManager())->putFile($this->token, $fileName, $filePath);
        if ($error !== null) {
            return $error;
        } else {
            return $ret;
        }
    }

    /**
     * 删除文件
     * @param string $fileName 文件名
     * @return mixed
     */
    public function delete($fileName)
    {
        return (new BucketManager($this->auth))->delete($this->bucket, $fileName);
    }
}

具体使用方法如下:
class SiteController extends Controller
{
    /**
     * 上传图片到七牛云存储
     * @return mixed|string
     */
    public function actionUpload()
    {
        // 是否有文件上传
        if (!isset($_FILES['imgFile']) || $_FILES['imgFile']['error'] || !$_FILES['imgFile']['name']) {
            return json_encode(['error' => 1, 'message' => '没有文件被上传']);
        }
        // 扩展名检测
        if (!in_array($_FILES['imgFile']['type'], ['image/jpeg', 'image/png', 'image/gif'])) {
            return json_encode(['error' => 1, 'message' => '扩展名不允许']);
        }
        $filePath = $_FILES['imgFile']['tmp_name']; // 图片上传后保存的临时路径
        $fileName = '/zoulu/article/' . date('ymdHis', time()) . $_FILES['imgFile']['name'];
        if (!file_exists($filePath)) {
            return json_encode(['error' => 1, 'message' => '临时文件不存在']);
        }
        $url = \common\extend\qiniu\Upload::getInstance()->uploadFile($fileName, $filePath);
        if (isset($url['key']) && $url['key']) {
            return json_encode(['error' => 0, 'url' => Yii::$app->params['qiniu']['baseurl'] . $url['key']]);
        } else {
            \common\base\TaskLog::getInstance()->writeLog(\yii\helpers\Json::encode($url));
        }
        unlink($filePath);
        return json_encode(['error' => 1, 'message' => '图片上传到七牛云存储失败']);
    }
}