码迷,mamicode.com
首页 > Web开发 > 详细

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

时间:2016-08-04 19:29:47      阅读:275      评论:0      收藏: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);
    }
}
View Code

 

下面是封装了一个图片上传的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("非法上传文件类型");
        }
    }
}   
View Code

 

 

相信图片上传对于一个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的方式来进行验证的。

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

标签:

原文地址:http://www.cnblogs.com/water0729/p/5737841.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!