图片上传及管理

图片管理

作为基础功能,图片上传是必不可少的一个,文章发布的图片,banner图片,文章logo图等。接下来的教程就是教大家如何开发一个图片管理的功能。

需求剖析

图片管理主要有两块功能:

  • 图片资源上传:把本地的图片文件上传到图片服务器,返回图片访问链接
  • 图片链接存储:把图片链接存储到数据库

数据模型

确定好图片管理数据模型,定义如下字段:

CREATE TABLE `image` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `name` varchar(255) NOT NULL DEFAULT '' COMMENT '图片名称',
  `desc` varchar(255) DEFAULT NULL COMMENT '图片描述',
  `image_type` varchar(50) DEFAULT NULL COMMENT '图片类型',
  `size` decimal(11,2) DEFAULT NULL COMMENT '图片大小',
  `created_at` datetime DEFAULT NULL COMMENT '创建时间',
  `updated_at` datetime DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='图片管理表';

通过 Gii 生产模型:Image 与 CRUD 功能代码,这里就不再演示 Gii 的功能了,还不熟悉gii操作的同学可以参考分类管理章节的内容。

继续在 站点 添加子菜单:站点》文件管理》图片管理

七牛云存储

图片上传课程用的是七牛云存储服务,所以功能开发之前先去免费注册一个七牛的账号。

申请七牛云账号。 新用户享有10GB永久免费存储空间、每月 10GB 下载流量、每月 10万次PUT请求、每月 100万 次GET请求。足够我们开发测试用了

账号申请完成后进入管理后台,获取密钥配置及新建bucket,写入到项目的 common/config/params-local.php

创建七牛 bucket

登陆七牛后打开 https://portal.qiniu.com/bucket/create 创建一个 bucket 名称为:test,创建成功后会七牛会自动分配一个测试域名(例:pa4z382fz.bkt.clouddn.com)可以在开发期间使用,在正式环境替换成自己的图片域名即可(例:http://image.itdocs.org)

获取七牛密钥

打开 https://portal.qiniu.com/user/key 复制 AK 和 SK,写入到项目的本地配置 common/config/params-local.php 中。如下:

'qiniu' =>[
        'domain' => 'http://pa4z382fz.bkt.clouddn.com',  //七牛自动生成的测试域名
        'bucket' => 'test',                              //Bucket
        'ak' => 'sTPe7Isyjjjw83********HUDfQSGTzkQpMum',
        'sk' => 'ZioAt9iNGKbI3J********p7YC90TTi5dmRN-a'
    ]

加载图片上传扩展

通过 composer 加载 七牛图片上传的扩展,在根目录的 composer.jsonrequire 里面添加如下代码:

"yii-china/yii2-qiniu-upload":"~1.2.0"

然后执行

composer update

安装包下好之后可以在 vendor 看到有一个包 yii-china/yii-qiniu-upload 说明加载成功了!

打开 backend/themes/hyii2/views/_form.php 在 form 表单终添加 ['options' => ['enctype' => 'multipart/form-data']] 如下:

<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]); ?>

引入刚才我们下载的图片上传包,引入的包本身就是提供给yii2的扩展,所以可以直接用widget的形式:

<?= $form->field($model, 'name')->widget(\Ycn\Qiniu\UploadWidget::className(),['options'=>[
    'domain' => Yii::$app->params['qiniu']['domain'].'/'
]]) ?>

如上,我们的 界面调整加载图片上传扩展 已经完成如下图所示:

图片 CRUD

添加图片

打开控制器 backend/controller/ImageController 找到 actionCreate 的方法,调整如下:

头部引入类

use yii\web\UploadedFile;
use Ycn\Qiniu\UploadService;

修改控制器代码:

/**
 * 添加图片
 *
 * @return mixed
 * @throws \Exception
 */
public function actionCreate()
{
    $model = new Image();

    if ($model->load(Yii::$app->request->post()) ) {
        //获取文件内容
        $file = UploadedFile::getInstance($model, 'name');

        if($file){
            //实例化上传对象
            $up = UploadService::getInstance(Yii::$app->params['qiniu']['ak'], Yii::$app->params['qiniu']['sk'],Yii::$app->params['qiniu']['bucket']);

            //图片上传临时路径
            $filePath= $file->tempName;

            //调用upload上传图片到七牛
            $response = $up->upload($filePath);

            $model->name = $response['filename'];
            $model->image_type = $file->type;
            $model->size = round($file->size/1024, 2);

        }

        if($model->save(true))
            return null;
    }

    return $this->renderAjax('create', [
        'model' => $model,
    ]);
}

更新图片

打开控制器 backend/controller/ImageController 找到 actionUpdate 的方法,调整如下:

/**
 * 更新图片
 *
 * @param integer $id
 * @return mixed
 * @throws NotFoundHttpException
 * @throws \Exception
 */
public function actionUpdate($id)
{
    $model = $this->findModel($id);

    if ($model->load(Yii::$app->request->post())) {

        //获取文件内容
        $file = UploadedFile::getInstance($model, 'name');

        if($file){

            //原图名称
            $filename = $model->name;

            //删除原图
            $up = UploadService::getInstance(Yii::$app->params['qiniu']['ak'], Yii::$app->params['qiniu']['sk'],Yii::$app->params['qiniu']['bucket']);
            $up->delete(Yii::$app->params['qiniu']['bucket'], $model->name);

            //调用上传接口
            $response = $up->upload($file->tempName);

            $model->name = $response['filename'];

        }

        if($model->save(true))
            return null;
    }

    return $this->renderAjax('update', [
        'model' => $model,
    ]);
}

删除图片

打开控制器 backend/controller/ImageController 找到 actionDelete 的方法,调整如下:

/**
 * 删除图片
 * 
 * @param integer $id
 * @return mixed
 * @throws \Exception
 * @throws \Throwable
 */
public function actionDelete($id)
{
    try{
        $image = Image::findOne($id);
        $image->delete();

        //删除七牛图片资源
        $up = UploadService::getInstance(Yii::$app->params['qiniu']['ak'], Yii::$app->params['qiniu']['sk'],Yii::$app->params['qiniu']['bucket']);
        $up->delete(Yii::$app->params['qiniu']['bucket'], $image->name);

        return $this->redirect(['index']);

    }catch (\Exception $e){

        throw $e;
    }
}

如此我们便可以试一下,图片管理的功能,验证以下几点:

1.图片上传到七牛

2.图片数据存储到数据库。

3.编辑和删除的功能

上一篇 下一篇
yii2 入门教程 - 博客系统搭建
第1章. 基本信息
第2章. 开发环境部署