yii2.0下,单图片上传到搜狐云台以及图片上传到本机。

图片服务器接的是搜狐云台。在搜狐云台上有代码包,下载下来,放到yii框架的vendor下。

yii2.0导入第三方库,很简单,写个autoload的文件,然后在入口脚本index.php中包含那个autoload文件就好了。具体到这个云台的库,只要包含代码中的autoload文件就好了。

简单介绍下搜狐云台的实现,用户会有一个对应的域名,然后选择建一些bucket,文件的上传下载都是在这个bucket中执行。函数调用在云台提供的文档中介绍的很清楚。这里就不再介绍了。同时我只从php的部分来介绍,不考虑前端部分。

控制器部分

class SiteController extends Controller
{
    public function actionUpload()
{
    //return ImgUpdate::uploadToScs($_FILES);
    return ImgUpdate::uploadToLocal($_FILES);
    }
}

下面是封装了一个图片上传的service。


<?php
/**
 * Created by PhpStorm.
 * User: changshuiwang
 * Date: 2016/8/2
 * Time: 17:51
 */

namespace common\service;
use yii;
use SohuCS\Scs\ScsClient;
use yii\base\Exception;
use yii\web\UploadedFile;

class ImgUpdate
{
    const SCS_ACCESS_KEY=‘xxxxxxx‘;
    const SCS_SECRET_KEY=‘xxxxxxx‘;
    const HOST=‘xxxxxx‘;

    public static $type=array(
        ‘image/jpeg‘,‘image/png‘,‘image/jpg‘
    );

    public static $ext=array(
        ‘jpeg‘,‘png‘,‘jpg‘
    );

    /**
     * @param $file
     * @return string 返回一个json响应
     */
    public static function uploadToScs($file,$bucket=‘focus-img‘)
    {
        try{

            $filename=$file[‘file‘][‘name‘];
            $tmp_name=$file[‘file‘][‘tmp_name‘];

            //检查文件合法
            self::checkImgExt($filename,$tmp_name);

            if($file[‘file‘]){
                $ext=self::getExtension($filename);
                $client = ScsClient::factory(array(
                    ‘key‘ => self::SCS_ACCESS_KEY,
                    ‘secret‘ => self::SCS_SECRET_KEY,
                    ‘region‘ => "bjcnc"
                ));

                //判断bucket是否存在
                if(!$client->doesBucketExist($bucket)){
                    $result = $client->createBucket(array(
                        ‘Bucket‘ => $bucket,
                        ‘LocationConstraint‘ => self::HOST
                    ));
                    $client->waitUntilBucketExists(array(‘Bucket‘ => $bucket));
                }

                $randName=uniqid().‘.‘.$ext;
                $filename="dianping/photos/".date(‘Ym‘,time())."/".$randName;//上传之后的文件名
                $pathToFile=$tmp_name;//图片上传之后php生成的临时文件名

                $result = $client->putObject(array(
                    ‘Bucket‘ => $bucket,
                    ‘Key‘ => $filename,
                    ‘Body‘ => fopen($pathToFile,‘r+‘),
                ));

                return json_encode(array(
                    ‘status‘=>‘success‘,
                    ‘msg‘=>self::HOST.‘/‘.$bucket.‘/‘.$filename,
                ));
            }else{
                throw new Exception("图片不能为空");
            }
        }catch(Exception $e){
            return json_encode(array(
                ‘status‘=>‘error‘,
                ‘msg‘=>$e->getMessage(),
            ));
        }
    }

    /**
     * @param $file 上传的图片 $_FILES
     * @return string 返回json串
     */
    public static function uploadToLocal($file)
    {
        try{
            $image=UploadedFile::usrLoadFiles();//获取到图片上传类
            if($image){
                //检查文件合法
                $filename=$file[‘file‘][‘name‘];
                $tmp_name=$file[‘file‘][‘tmp_name‘];
                self::checkImgExt($filename,$tmp_name);
                //将图片移动到指定目录下
                $image=$image[‘file‘];
                $ext = $image->getExtension();
                $randName = uniqid() . "." . $ext;
                $path = date(‘y-m-d‘,time());
                $rootPath = ‘uploads/‘ . $path . "/";
                //文件上传路径,使用的是相对路径,如果以/开头,linux上会从系统根目录而不是web根目录
                if (!file_exists($rootPath)) {
                    mkdir($rootPath,0777);
                }
                $image->saveAs($rootPath . $randName);
                $photo = ‘/‘.$rootPath.$randName;//图片存放到数据库的路径
                return json_encode(array(
                    ‘status‘=>‘success‘,
                    ‘msg‘=>$photo,//返回给前台显示
                ));
            }else{
                throw new Exception("图片不能为空");
            }

        }catch (Exception $e){
            return json_encode(array(
                ‘status‘ => ‘error‘,
                ‘msg‘ => $e->getMessage(),
            ));
        }
    }
    /**
     * @param $filename 上传的文件名
     * @return mixed 返回文件后缀
     */
    private static function getExtension($filename)
    {
        $info = pathinfo($filename);
        return $info[‘extension‘];
    }

    /**
     * @param $filesrcname源文件名
     * @param $filename临时文件名
     * @throws Exception
     */
    private static function checkImgExt($filesrcname,$filename)
    {
        $ext=self::getExtension($filesrcname);
        //对源文件类型判断
        if(!in_array($ext, self::$ext)) {
            throw new Exception("上传只能为图片");
        }

        $size=filesize($filename);
        if($size>=1024*1024){
            throw new Exception("上传图片太大,不超过1MB");
        }

        //判断文件名是否恶意更改
        $magicFile = null;
        $info = finfo_open(FILEINFO_MIME_TYPE, $magicFile);
        //3、图片类型限制,
        if ($info) {
            $result = finfo_file($info, $filename);
            finfo_close($info);
        }
        if(!in_array($result, self::$type)){
            throw new Exception("非法上传文件类型");
        }
    }
}   

相信图片上传对于一个web开发的程序员来说并不陌生,我自己之前也做了很多次图片,但是好像一直都没怎么做过图片验证

private static function checkImgExt($filesrcname,$filename)是对上传的图片进行了一些验证,PHP对于上传的图片,会根据php.ini中的配置,移动到$_FILES[‘file‘][‘tmp_name‘],
$_FILES[‘file‘][‘name‘]则是上传的图片原本的名字。

对于一些恶意程序,可能会选择修改文件的后缀名,这样可以逃过对$_FILES的验证,在checkImgExt()中通过finfo_open可以获取文件MIME类型,这样就可以检查文件后缀名是不是有恶意更改。
yii对于继承model的子类,都继承了rules()方法,rules()方法也可以对文件类型进行判断,yii底层也是通过finfo_open的方式来进行验证的。

时间: 2024-10-10 01:37:16

yii2.0下,单图片上传到搜狐云台以及图片上传到本机。的相关文章

Openresty+YII2.0下开发高性能RestfulAPI系列2:api + wap的配置

1. openresty的安装 参考:<openresty最佳实践> https://moonbingbing.gitbooks.io/openresty-best-practices/content/index.html 2. centos服务器上的目录结构 ⑴ Openresty的nginx配置文件nginx.conf 文件放/etc/conf下 ⑵ api的目录 ① 目录总体结构: ② YII2.0框架的整个目录放php目录: ⑶ wap的目录 ① ② 静态html代码放wap/html

Yii2.0 下的 load() 方法的使用

一 问题 最近在使用 Yii2.0,遇到一个 bug:在 /models/OrderDetail.php add() 方法中调用 load() 方法加载数据,却加载不了. public function add($data) { if ($this->load($data) && $this->save()) { return true; } return false; } 二 排错 2.1 将 add() 方法修改成如下(添加 $this->getErrors()):

Openresty+YII2.0下开发高性能RestfulAPI系列3:开发基于php的restfulAPI

1. nginx.conf中配置访问url 访问 api1.yingtrader.com/boquote,就会执行boquote.php代码. 2. Nginx 实现AJAX跨域请求 要在nginx上启用跨域请求,需要添加add_header Access-Control*指令. 如下所示: location/{ add_header 'Access-Control-Allow-Origin' ' http://other.subdomain.com '; add_header 'Access-

Openresty+YII2.0下开发RestfulAPI系列4:vanilla香草框架简介

1. 安装 ⑴ 压缩包在https://github.com/idevz/vanilla下载. ⑵ 把解压后的文件 /vanilla-master 放到 /opt/目录.并修改整个文件夹的属性: chmod –R 755 vanilla-master ⑶ ./configure --prefix=/opt/vanilla --openresty-path=/opt/openresty make install 2. vanilla的使用 ⑴ 创建application框架 cd vanilla

从web编辑器 UEditor 中单独提取图片上传,包含多图片单图片上传以及在线涂鸦功能

UEditor是由百度web前端研发部开发所见即所得富文本web编辑器,具有轻量,可定制,注重用户体验等特点,开源基于MIT协议,允许自由使用和修改代码.(抄的...) UEditor是非常好用的富文本web编辑器,而且全中文API和注释,方便学习和使用.特别是图片上传查看及涂鸦功能极为喜欢,但是有很多情况我们并不需要Web编辑器,而只需要图片上传.那么问题来了,提取图片上传哪家强..... 网上有很多图片上传的控件.插件.但都不是那么的完美,有的只有一张图片上传不包含批量上传,有的没有图片查看

CKEditor图片上传实现详细步骤(使用Struts 2)

本人使用的CKEditor版本是3.6.3.CKEditor配置和部署我就不多说. CKEditor的编辑器工具栏中有一项"图片域",该工具可以贴上图片地址来在文本编辑器中加入图片,但是没有图片上传. "预览"中有一大堆鸟语,看得很不爽.可以打开ckeditor/plugins/image/dialogs/image.js文件,搜索"b.config.image_previewText"就能找到这段鸟语了,(b.config.image_prev

django之创建第10-1个项目-图片上传并记录上传时间

1.百度云盘:django之创建第10-1个项目-图片上传并记录上传时间 2.主要修改的配置文件有3个,forms.views和models3个文件以及html 3.forms.py文件修改 #coding:utf-8 #这里定义html页面中用到的表单,常和views和models文件配合使用 """ >>> help(django) Help on package django: PACKAGE CONTENTS conf (package) contr

UEditor之实现配置简单的图片上传示例

开心一笑 下班后,阿华到楼下小超市买毛巾,刚买完出来,就遇到同一办公楼里另一家公司的阿菲,之前与她远远的有过几次眼神交流,但从没说过话,"买毛巾啊",看着阿华手里的毛巾,阿菲先开口了. 阿华回到:"是啊,这里的老板眼神太好了,我不敢偷,就只有买了." 阿菲一下就哈哈笑了,配合到:"哇,原来你是小偷." 阿华:"嘘,小声点,其实主要原因是--"阿华指着自己的脑袋接着说到:"你看,我是个有头有脸的人,所以还是要用用毛巾的

UEditor之实现配置简单的图片上传示例 (转)

http://blog.csdn.net/huangwenyi1010/article/details/51637427#comments 1.首先你可以到官网Ueditor,查看很详细的文档,包括如何安装到Eclipse,相关jar包和如何使用Ueditor,本文主要介绍如何实现单图片上传和利用自己的接口: 运行tomcat上,在google浏览器运行(Test是我的项目名称): http://localhost:8081/Test/jsp/config.json 出现一串长长的json的字符