3

前言

将图片上传到阿里云OSS是一种趋势,一个必然。当你的项目图片过多,需要频繁上传和替换的时候,用阿里云OSS可以很方便的管理你的图片,节省服务器空间,大大提高了效率。阿里云OSS是阿里云提供的海量、安全、低成本、高可靠的云存储服务。你可以通过调用API,在任何应用、任何时间、任何地点上传和下载数据,也可以通过Web控制台对数据进行简单的管理。阿里云OSS适合存放任意类型的文件,适合各种网站、开发企业及开发者使用。

如果直接把图片上传到阿里云OSS是比较简单的,应该很多人都懂,但是用百度UEditor上传图片到阿里云OSS,就没那么简单了,所以我感觉还是有必要写这篇文章分享出来,给有需要的人。

效果图

图片描述

修改百度UEditor的文件

1、修改这几个文件:图片描述

1.1、修改Uploader.class.php文件

注意:修改的部分我有加注释,注意看。

<?php


/**
 * Created by JetBrains PhpStorm.
 * User: taoqili
 * Date: 12-7-18
 * Time: 上午11: 32
 * UEditor编辑器通用上传类
 */
class Uploader
{

    private $fileField; //文件域名
    private $file; //文件上传对象
    private $base64; //文件上传对象
    private $config; //配置信息
    private $oriName; //原始文件名
    private $fileName; //新文件名
    private $fullName; //完整文件名,即从当前配置目录开始的URL
    private $filePath; //完整文件名,即从当前配置目录开始的URL
    private $fileSize; //文件大小
    private $fileType; //文件类型
    private $stateInfo; //上传状态信息,
    private $stateMap = array( //上传状态映射表,国际化用户需考虑此处数据的国际化
        "SUCCESS", //上传成功标记,在UEditor中内不可改变,否则flash判断会出错
        "文件大小超出 upload_max_filesize 限制",
        "文件大小超出 MAX_FILE_SIZE 限制",
        "文件未被完整上传",
        "没有文件被上传",
        "上传文件为空",
        "ERROR_TMP_FILE" => "临时文件错误",
        "ERROR_TMP_FILE_NOT_FOUND" => "找不到临时文件",
        "ERROR_SIZE_EXCEED" => "文件大小超出网站限制",
        "ERROR_TYPE_NOT_ALLOWED" => "文件类型不允许",
        "ERROR_CREATE_DIR" => "目录创建失败",
        "ERROR_DIR_NOT_WRITEABLE" => "目录没有写权限",
        "ERROR_FILE_MOVE" => "文件保存时出错",
        "ERROR_FILE_NOT_FOUND" => "找不到上传文件",
        "ERROR_WRITE_CONTENT" => "写入文件内容错误",
        "ERROR_UNKNOWN" => "未知错误",
        "ERROR_DEAD_LINK" => "链接不可用",
        "ERROR_HTTP_LINK" => "链接不是http链接",
        "ERROR_HTTP_CONTENTTYPE" => "链接contentType不正确"
    );

    /**
     * 构造函数
     * @param string $fileField 表单名称
     * @param array $config 配置项
     * @param bool $base64 是否解析base64编码,可省略。若开启,则$fileField代表的是base64编码的字符串表单名
     */
    public function __construct($fileField, $config, $type = "upload")
    {
        $this->fileField = $fileField;
        $this->config = $config;
        $this->type = $type;
        if ($type == "remote") {
            $this->saveRemote();
        } else if($type == "base64") {
            $this->upBase64();
        } else {
            $this->upFile();
        }

        $this->stateMap['ERROR_TYPE_NOT_ALLOWED'] = iconv('unicode', 'utf-8', $this->stateMap['ERROR_TYPE_NOT_ALLOWED']);
    }

    /**
     * 上传文件的主处理方法
     * @return mixed
     */
    private function upFile()
    {  
        $file = $this->file = $_FILES[$this->fileField];  
        if (!$file) {
            $this->stateInfo = $this->getStateInfo("ERROR_FILE_NOT_FOUND");
            return;
        }
        if ($this->file['error']) {
            $this->stateInfo = $this->getStateInfo($file['error']);
            return;
        } else if (!file_exists($file['tmp_name'])) {
            $this->stateInfo = $this->getStateInfo("ERROR_TMP_FILE_NOT_FOUND");
            return;
        } else if (!is_uploaded_file($file['tmp_name'])) {
            $this->stateInfo = $this->getStateInfo("ERROR_TMPFILE");
            return;
        }
        
        //修改:上传阿里云OSS
        $upload=new \source\core\widgets\upload\FileUpload();
        
        $Pictureinfo=$upload->UploadUeditorPicture($file);

        $this->oriName = $file['name'];
        $this->fileSize = $file['size'];
        $this->fileType = $this->getFileExt();
        $this->fullName = '/'.$Pictureinfo['path'];
        $this->filePath = $Pictureinfo['path'];
        $this->fileName = $this->getFileName();
        $dirname = dirname($this->filePath);

        //检查文件大小是否超出限制
        if (!$this->checkSize()) {
            $this->stateInfo = $this->getStateInfo("ERROR_SIZE_EXCEED");
            return;
        }

        //检查是否不允许的文件格式
        if (!$this->checkType()) {
            $this->stateInfo = $this->getStateInfo("ERROR_TYPE_NOT_ALLOWED");
            return;
        }

        //创建目录失败
        // if (!file_exists($dirname) && !mkdir($dirname, 0777, true)) {
        //     $this->stateInfo = $this->getStateInfo("ERROR_CREATE_DIR");
        //     return;
        // } else if (!is_writeable($dirname)) {
        //     $this->stateInfo = $this->getStateInfo("ERROR_DIR_NOT_WRITEABLE");
        //     return;
        // }

        $this->stateInfo = $this->stateMap[0];
        //移动文件
        // if (!(move_uploaded_file($file["tmp_name"], $this->filePath) && file_exists($this->filePath))) { //移动失败

        //     $this->stateInfo = $this->getStateInfo("ERROR_FILE_MOVE");
        // } else { //移动成功
        //     $this->stateInfo = $this->stateMap[0];
        // }

    }

    /**
     * 处理base64编码的图片上传
     * @return mixed
     */
    private function upBase64()
    {
        $base64Data = $_POST[$this->fileField];
        $img = base64_decode($base64Data);

        $this->oriName = $this->config['oriName'];
        $this->fileSize = strlen($img);
        $this->fileType = $this->getFileExt();
        $this->fullName = $this->getFullName();
        $this->filePath = $this->getFilePath();
        $this->fileName = $this->getFileName();
        $dirname = dirname($this->filePath);

        //检查文件大小是否超出限制
        if (!$this->checkSize()) {
            $this->stateInfo = $this->getStateInfo("ERROR_SIZE_EXCEED");
            return;
        }

        //创建目录失败
        if (!file_exists($dirname) && !mkdir($dirname, 0777, true)) {
            $this->stateInfo = $this->getStateInfo("ERROR_CREATE_DIR");
            return;
        } else if (!is_writeable($dirname)) {
            $this->stateInfo = $this->getStateInfo("ERROR_DIR_NOT_WRITEABLE");
            return;
        }

        //移动文件
        if (!(file_put_contents($this->filePath, $img) && file_exists($this->filePath))) { //移动失败
            $this->stateInfo = $this->getStateInfo("ERROR_WRITE_CONTENT");
        } else { //移动成功
            $this->stateInfo = $this->stateMap[0];
        }

    }

    /**
     * 拉取远程图片
     * @return mixed
     */
    private function saveRemote()
    {
        $imgUrl = htmlspecialchars($this->fileField);
        $imgUrl = str_replace("&amp;", "&", $imgUrl);

        //http开头验证
        if (strpos($imgUrl, "http") !== 0) {
            $this->stateInfo = $this->getStateInfo("ERROR_HTTP_LINK");
            return;
        }
        //获取请求头并检测死链
        $heads = get_headers($imgUrl);
        if (!(stristr($heads[0], "200") && stristr($heads[0], "OK"))) {
            $this->stateInfo = $this->getStateInfo("ERROR_DEAD_LINK");
            return;
        }
        //格式验证(扩展名验证和Content-Type验证)
        $fileType = strtolower(strrchr($imgUrl, '.'));
        if (!in_array($fileType, $this->config['allowFiles']) || stristr($heads['Content-Type'], "image")) {
            $this->stateInfo = $this->getStateInfo("ERROR_HTTP_CONTENTTYPE");
            return;
        }

        //打开输出缓冲区并获取远程图片
        ob_start();
        $context = stream_context_create(
            array('http' => array(
                'follow_location' => false // don't follow redirects
            ))
        );
        readfile($imgUrl, false, $context);

        $img = ob_get_contents();
        ob_end_clean();
        preg_match("/[\/]([^\/]*)[\.]?[^\.\/]*$/", $imgUrl, $m);

        $this->oriName = $m ? $m[1]:"";
        $this->fileSize = strlen($img);
        $this->fileType = $this->getFileExt();
        $this->fullName = $this->getFullName();
        $this->filePath = $this->getFilePath();
        $this->fileName = $this->getFileName();
        $dirname = dirname($this->filePath);

        //检查文件大小是否超出限制
        if (!$this->checkSize()) {
            $this->stateInfo = $this->getStateInfo("ERROR_SIZE_EXCEED");
            return;
        }

        //创建目录失败
        if (!file_exists($dirname) && !mkdir($dirname, 0777, true)) {
            $this->stateInfo = $this->getStateInfo("ERROR_CREATE_DIR");
            return;
        } else if (!is_writeable($dirname)) {
            $this->stateInfo = $this->getStateInfo("ERROR_DIR_NOT_WRITEABLE");
            return;
        }

        //移动文件
        if (!(file_put_contents($this->filePath, $img) && file_exists($this->filePath))) { //移动失败
            $this->stateInfo = $this->getStateInfo("ERROR_WRITE_CONTENT");
        } else { //移动成功
            $this->stateInfo = $this->stateMap[0];
        }

    }

    /**
     * 上传错误检查
     * @param $errCode
     * @return string
     */
    private function getStateInfo($errCode)
    {
        return !$this->stateMap[$errCode] ? $this->stateMap["ERROR_UNKNOWN"] : $this->stateMap[$errCode];
    }

    /**
     * 获取文件扩展名
     * @return string
     */
    private function getFileExt()
    {
        return strtolower(strrchr($this->oriName, '.'));
    }

    /**
     * 重命名文件
     * @return string
     */
    private function getFullName()
    {
        //替换日期事件
        $t = time();
        $d = explode('-', date("Y-y-m-d-H-i-s"));
        $format = $this->config["pathFormat"];
        $format = str_replace("{yyyy}", $d[0], $format);
        $format = str_replace("{yy}", $d[1], $format);
        $format = str_replace("{mm}", $d[2], $format);
        $format = str_replace("{dd}", $d[3], $format);
        $format = str_replace("{hh}", $d[4], $format);
        $format = str_replace("{ii}", $d[5], $format);
        $format = str_replace("{ss}", $d[6], $format);
        $format = str_replace("{time}", $t, $format);

        //过滤文件名的非法自负,并替换文件名
        $oriName = substr($this->oriName, 0, strrpos($this->oriName, '.'));
        $oriName = preg_replace("/[\|\?\"\<\>\/\*\\\\]+/", '', $oriName);
        $format = str_replace("{filename}", $oriName, $format);

        //替换随机字符串
        $randNum = rand(1, 10000000000) . rand(1, 10000000000);
        if (preg_match("/\{rand\:([\d]*)\}/i", $format, $matches)) {
            $format = preg_replace("/\{rand\:[\d]*\}/i", substr($randNum, 0, $matches[1]), $format);
        }

        $ext = $this->getFileExt();
        return $format . $ext;
    }

    /**
     * 获取文件名
     * @return string
     */
    private function getFileName () {
        return substr($this->filePath, strrpos($this->filePath, '/') + 1);
    }

    /**
     * 获取文件完整路径
     * @return string
     */
    private function getFilePath()
    {
        $fullname = $this->fullName;
        
        // $rootPath = $_SERVER['DOCUMENT_ROOT'];

        // if (substr($fullname, 0, 1) != '/') {
        //     $fullname = '/' . $fullname;
        // }

        //修改:替换路径
        return  $fullname;
    }

    /**
     * 文件类型检测
     * @return bool
     */
    private function checkType()
    {
        return in_array($this->getFileExt(), $this->config["allowFiles"]);
    }

    /**
     * 文件大小检测
     * @return bool
     */
    private function  checkSize()
    {
        return $this->fileSize <= ($this->config["maxSize"]);
    }

    /**
     * 获取当前上传成功文件的各项信息
     * @return array
     */
    public function getFileInfo()
    { 
        return array(
            "state" => $this->stateInfo,
            "url" => $this->fullName,
            "title" => $this->fileName,
            "original" => $this->oriName,
            "type" => $this->fileType,
            "size" => $this->fileSize
        );
    }

}

1.2、修改config.json文件,这个文件主要是修改图片路径,改为你的阿里云OSS的路径

/* 前后端通信相关的配置,注释只允许使用多行方式 */
{
    /* 上传图片配置项 */
    "imageActionName": "uploadimage", /* 执行上传图片的action名称 */
    "imageFieldName": "upfile", /* 提交的图片表单名称 */
    "imageMaxSize": 2048000, /* 上传大小限制,单位B */
    "imageAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 上传图片格式显示 */
    "imageCompressEnable": true, /* 是否压缩图片,默认是true */
    "imageCompressBorder": 1600, /* 图片压缩最长边限制 */
    "imageInsertAlign": "none", /* 插入的图片浮动方式 */
    "imageUrlPrefix": "http://test.oss-cn-hangzhou.aliyuncs.com", /* 图片访问路径前缀 */
    "imagePathFormat": "data/attachment/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
                                /* {filename} 会替换成原文件名,配置这项需要注意中文乱码问题 */
                                /* {rand:6} 会替换成随机数,后面的数字是随机数的位数 */
                                /* {time} 会替换成时间戳 */
                                /* {yyyy} 会替换成四位年份 */
                                /* {yy} 会替换成两位年份 */
                                /* {mm} 会替换成两位月份 */
                                /* {dd} 会替换成两位日期 */
                                /* {hh} 会替换成两位小时 */
                                /* {ii} 会替换成两位分钟 */
                                /* {ss} 会替换成两位秒 */
                                /* 非法字符 \ : * ? " < > | */
                                /* 具请体看线上文档: fex.baidu.com/ueditor/#use-format_upload_filename */

    /* 涂鸦图片上传配置项 */
    "scrawlActionName": "uploadscrawl", /* 执行上传涂鸦的action名称 */
    "scrawlFieldName": "upfile", /* 提交的图片表单名称 */
    "scrawlPathFormat": "data/attachment/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
    "scrawlMaxSize": 2048000, /* 上传大小限制,单位B */
    "scrawlUrlPrefix": "http://test.oss-cn-hangzhou.aliyuncs.com", /* 图片访问路径前缀 */
    "scrawlInsertAlign": "none",

    /* 截图工具上传 */
    "snapscreenActionName": "uploadimage", /* 执行上传截图的action名称 */
    "snapscreenPathFormat": "/data/attachment/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
    "snapscreenUrlPrefix": "http://test.oss-cn-hangzhou.aliyuncs.com", /* 图片访问路径前缀 */
    "snapscreenInsertAlign": "none", /* 插入的图片浮动方式 */

    /* 抓取远程图片配置 */
    "catcherLocalDomain": ["127.0.0.1", "localhost", "img.baidu.com"],
    "catcherActionName": "catchimage", /* 执行抓取远程图片的action名称 */
    "catcherFieldName": "source", /* 提交的图片列表表单名称 */
    "catcherPathFormat": "/data/attachment/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
    "catcherUrlPrefix": "http://test.oss-cn-hangzhou.aliyuncs.com", /* 图片访问路径前缀 */
    "catcherMaxSize": 2048000, /* 上传大小限制,单位B */
    "catcherAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 抓取图片格式显示 */

    /* 上传视频配置 */
    "videoActionName": "uploadvideo", /* 执行上传视频的action名称 */
    "videoFieldName": "upfile", /* 提交的视频表单名称 */
    "videoPathFormat": "/data/attachment/video/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
    "videoUrlPrefix": "http://test.oss-cn-hangzhou.aliyuncs.com", /* 视频访问路径前缀 */
    "videoMaxSize": 102400000, /* 上传大小限制,单位B,默认100MB */
    "videoAllowFiles": [
        ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
        ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid"], /* 上传视频格式显示 */

    /* 上传文件配置 */
    "fileActionName": "uploadfile", /* controller里,执行上传视频的action名称 */
    "fileFieldName": "upfile", /* 提交的文件表单名称 */
    "filePathFormat": "/data/attachment/file/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
    "fileUrlPrefix": "http://test.oss-cn-hangzhou.aliyuncs.com", /* 文件访问路径前缀 */
    "fileMaxSize": 51200000, /* 上传大小限制,单位B,默认50MB */
    "fileAllowFiles": [
        ".png", ".jpg", ".jpeg", ".gif", ".bmp",
        ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
        ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
        ".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
        ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
    ], /* 上传文件格式显示 */

    /* 列出指定目录下的图片 */
    "imageManagerActionName": "listimage", /* 执行图片管理的action名称 */
    "imageManagerListPath": "/data/attachment/image/", /* 指定要列出图片的目录 */
    "imageManagerListSize": 20, /* 每次列出文件数量 */
    "imageManagerUrlPrefix": "http://test.oss-cn-hangzhou.aliyuncs.com", /* 图片访问路径前缀 */
    "imageManagerInsertAlign": "none", /* 插入的图片浮动方式 */
    "imageManagerAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 列出的文件类型 */

    /* 列出指定目录下的文件 */
    "fileManagerActionName": "listfile", /* 执行文件管理的action名称 */
    "fileManagerListPath": "/data/attachment/file/", /* 指定要列出文件的目录 */
    "fileManagerUrlPrefix": "http://test.oss-cn-hangzhou.aliyuncs.com", /* 文件访问路径前缀 */
    "fileManagerListSize": 20, /* 每次列出文件数量 */
    "fileManagerAllowFiles": [
        ".png", ".jpg", ".jpeg", ".gif", ".bmp",
        ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
        ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
        ".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
        ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
    ] /* 列出的文件类型 */

}

1.3、action_upload.php、action_list.php、action_crawler.php这三个文件主要是引用上传到阿里云OSS的文件FileUpload.php,都加入如下代码即可

include (__DIR__."/../../../../../../source/core/widgets/upload/FileUpload.php");

FileUpload.php文件上传到阿里云OSS的代码

<?php
namespace source\core\widgets\upload;

use Yii;
use yii\base\Action;
use yii\base\ActionFilter;
use source\models\Upload;
use OSS\OssClient;
use OSS\Core\OssException;
use OSS\Http\RequestCore;
use OSS\Http\ResponseCore;
use source\core\widgets\encrypt\AesMask;
use source\models\User;

class FileUpload 
{
    const endpoint = "填写你的endpoint";
    const accessKeyId = "填写你的accessKeyId";
    const accessKeySecret = "填写你的accessKeyId";


  //百度编辑器图片上传
  public static function UploadUeditorPicture($file)
  {  
        include (__DIR__."/../../../../vendor/aliyuncs/oss-sdk-php/src/OSS/OssClient.php");  
        include (__DIR__."/../../../../vendor/aliyuncs/oss-sdk-php/src/OSS/Core/OssException.php");      
        include (__DIR__."/../../../../vendor/aliyuncs/oss-sdk-php/src/OSS/Core/OssUtil.php");
        include (__DIR__."/../../../../vendor/aliyuncs/oss-sdk-php/src/OSS/Core/MimeTypes.php");
        include (__DIR__."/../../../../vendor/aliyuncs/oss-sdk-php/src/OSS/Http/RequestCore.php");
        include (__DIR__."/../../../../vendor/aliyuncs/oss-sdk-php/src/OSS/Http/ResponseCore.php");
        include (__DIR__."/../../../../vendor/aliyuncs/oss-sdk-php/src/OSS/Result/Result.php");
        include (__DIR__."/../../../../vendor/aliyuncs/oss-sdk-php/src/OSS/Result/PutSetDeleteResult.php");

        include ("/../encrypt/StrMask.php");
        include ("/../encrypt/AesMask.php");

        $ossClient = new \OSS\OssClient(self::accessKeyId, self::accessKeySecret, self::endpoint);

        $data = ['id'=>1,'modules_name'=>'ueditor','user_id'=>1];
        $model = array();
        $bucket = 'test';
        if(empty($data['id'])){
             $model['status']="ID不能为空";
             return $model; 
        }
        if(!isset($data['modules_name'])){
             $model['status']="模块名称不能为空";
             return $model; 
        }
        if(!isset($data['user_id'])){
             $model['status']="用户id不能为空";
             return $model; 
        }
        $path = self::Encrypt($data['modules_name'],$data['id'],$data['user_id']);//对上传的路径加密

        if(!empty($file)){

            $randName = time() . rand(1000, 9999) . strtolower(strrchr($file['name'], '.'));
            $name = $path.$randName;
            $tempName=!empty($file['tmp_name'])?$file['tmp_name']:"";

            $ossClient->uploadFile($bucket,$name,$tempName);

            return  ['path'=>$name,'randName'=>$randName];
        } 

        return ['path'=>'','randName'=>''];   
       
  }
  
  
    /**
   * 删除附件
   *
   * @param  path      string  y upload表返回的附件上传路径path 字段\n
   * @return status   string    结果信息
   */
 static public function DownloadDelete($path)
 {
       $ossClient = new OssClient(self::accessKeyId, self::accessKeySecret, self::endpoint);
       $bucket = "test";
       if(!isset($path)){
            $model['status']="附件路径不能为空";
            return $model;
       }
       $ossClient->deleteObject($bucket, $path);
       $model['status']="删除成功";
       return $model;
      
  }
  
  
   /**
   * 批量删除附件
   *
   * @param  path      string  y upload表返回的附件上传路径path 字段\n
   * @return status   string    结果信息
   */
 static public function DownloadDeletes($data)
 {
       $ossClient = new OssClient(self::accessKeyId, self::accessKeySecret, self::endpoint);
       $bucket = "test";
       if(!isset($data)){
            $model['status']="删除数组不能为空";
            return $model;
       }
       $ossClient->deleteObjects($bucket, $data); 
       $model['status']="删除成功";
       return $model;
      
  }

  function getObject($object)
  {
        $ossClient = new OssClient(self::accessKeyId, self::accessKeySecret, self::endpoint);
        $options = array();
        $bucket = "test";
        
        $timeout = 3600;
        $options = NULL;
        try {
            $signedUrl = $ossClient->signUrl($bucket, $object, $timeout, "PUT");
        } catch (OssException $e) {
            printf(__FUNCTION__ . ": FAILED\n");
            printf($e->getMessage() . "\n");
            return;
        }
        print(__FUNCTION__ . ": signedUrl: " . $signedUrl . "\n");
        $content = file_get_contents(__FILE__);

        $request = new RequestCore($signedUrl);
        $request->set_method('PUT');
        $request->add_header('Content-Type', '');
        $request->add_header('Content-Length', strlen($content));
        $request->set_body($content);
        $request->send_request();
        $res = new ResponseCore($request->get_response_header(),
            $request->get_response_body(), $request->get_response_code());
        if ($res->isOK()) {
            print(__FUNCTION__ . ": OK" . "\n");
        } else {
            print(__FUNCTION__ . ": FAILED" . "\n");
        };
    }
  
  
   /**
   * 加密路径
   *
   * @param array $data       Y 参数数组(array('modules_name'=>$modules_name,'bucket'=>'test','path'=>'upload/accessory/14585506176746.jpg'))\n
   * --modules_name   string  Y 模块名称\n
   * --id             string  Y id\n
   * @return status   string    结果信息
   */
 static public function Encrypt($modules_name,$id,$user_id='')
 {

       if(empty($user_id)){
          $user_id =  Yii::$app->user->id;
       }
       
       $modules_path = AesMask::encrypt($modules_name,'test');
       
       $id_path = AesMask::encrypt($id,'test');
       
       return "test/".$modules_path."/".$id_path."/";
  }
  
}
?>

新增图片Controller的代码

 public function actionCreate()
{  
        $username=!empty(Yii::$app->user->identity->attributes['username'])?Yii::$app->user->identity->attributes['username']:"";
        $model = new Product();  
        $model->user_id=Yii::$app->user->id;
        $model->user_name = $username;
        $model->product_type=$this->product_type;
        $model->loadDefaultValues();
        
        $bodyModel = $this->getBodyModel();
        $bodyModel->loadDefaultValues();
        
        if(($r = $this->saveProduct($model, $bodyModel))!==false)
        {
            return $r;
        }
        
        //产品属性
        $product_items=[];

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

 public function saveProduct($model, $bodyModel)
 { 
        $postDatas = Yii::$app->request->post();

        if ($model->load($postDatas) && $bodyModel->load($postDatas) && $model->validate() && $bodyModel->validate()) {
            
            if($model->summary===null|| $model->summary ==='')
            {
                if($bodyModel->hasAttribute('body'))
                {
                    $product = strip_tags($bodyModel->body);
                    $pattern = '/\s/';//去除空白
                    $product = preg_replace($pattern, '', $product);
                     
                    $model->summary=StringHelper::subStr($product,250);
                }
            }

            if($model->save())
            {  
                $bodyModel->product_id = $model->id; 
                $bodyModel->save();
                //保存百度编辑器的图片
                $this->saveUpload($bodyModel->body,$model->id);
                //属性
                if(!empty($postDatas['ProductItems'])){
                    ProductItems::deleteAll(['product_id'=>$model->id]);
                    foreach ($postDatas['ProductItems']['type'] as $key => $val) {
                        $modelItems = new ProductItems();
                        $modelItems->product_id = $model->id;
                        $modelItems->type = !empty($postDatas['ProductItems']['type'][$key])?$postDatas['ProductItems']['type'][$key]:"";
                        $modelItems->source = !empty($postDatas['ProductItems']['source'][$key])?$postDatas['ProductItems']['source'][$key]:"";
                        $modelItems->ticket_pat = !empty($postDatas['ProductItems']['ticket_pat'][$key])?$postDatas['ProductItems']['ticket_pat'][$key]:"";
                        $modelItems->ticket_pats = !empty($postDatas['ProductItems']['ticket_pats'][$key])?$postDatas['ProductItems']['ticket_pats'][$key]:"";
                        $modelItems->save();
                    }
                }

                return $this->redirect(['index']);
            }
        }
        return false;
}
 //保存图片
public function saveUpload($body,$task_id)
{   
        $error['status']="内容为空";
        if(!empty($body) && $task_id){ 
            $preg = '/<img.*?src=[\"|\']?(.*?)[\"|\']?\s.*?>/i'; //获取百度编辑器里提交的图片路径
            preg_match_all($preg, $body, $imgArr);
        
            if(!empty($imgArr[1])){
                foreach ($imgArr[1] as $key => $val) { 
                    $_imgArr = explode('/wpzx/', $val);  
                    $path='wpzx/'.$_imgArr[1];
                    $suffix = pathinfo($_imgArr[1]);  
                    $img_info = getimagesize($val);

                    $model= new Upload();
                    if($suffix['extension'] == 'jpg' || $suffix['extension'] == 'JPG'|| $suffix['extension'] == 'png'|| $suffix['extension'] == 'PNG'|| $suffix['extension'] == 'jpeg'){
                        $model->thumb        = $path;
                    }

                    $model->task_id          = $task_id;
                    $model->name             = $suffix['basename'];
                    $model->path             = $path;
                    $model->status           = 1;
                    $model->user_id          = Yii::$app->user->id;
                    $model->size             = $img_info[0]*$img_info[1];
                    $model->type             = $img_info['mime'];
                    $model->upload_time      = time();
                    $model->module_id        = 3;
                    $model->modules_name     = 'product';
                    $model->target           = 1;
                    
                    if (!$model->save()) {
                        $error['status']="失败"; 
                    }
                }
                if($error['status']!="失败"){
                    return true;
                }
                return $error;
            }
        }
        //删除upload与阿里云的图片  
        $upload=Upload::getUploadsAll($task_id,'product'); 
        if(!empty($upload)){
            FileUpload::DownloadDeletes(ArrayHelper::getColumn($upload, 'path'));
            Upload::deleteAll(['task_id'=>$task_id,'modules_name'=>'product']);  
        }   
}

//根据指定条件获取所有上传图片
 public static function getUploadsAll($task_id,$modules_name)
 {
        $data=[];
        $query=Upload::find()->where(['modules_name'=>$modules_name]);
        if(!empty($task_id)){
            $data=$query->andWhere(['task_id'=>$task_id])->all();
        }else{
            $data=$query->all();
        }
        
        return $data;
 }

//upload表的字段如下,仅供参考
 public function attributeLabels()
 {
        return [
            'id' => 'ID',
            'name' => '上传文件名',
            'path' => '文件路径',
            'status' => '上传状态',
            'task_id' => '所属任务',
            'user_id' => '所属用户',
            'size' => '文件大小',
            'type' => '文件类型',
            'upload_time' => '上传时间',
            'module_id' => '所属系统',
            'thumb' => '缩略图',
        ];
}

新增图片Views的代码

<?php
use yii\helpers\Html;
use yii\bootstrap\ActiveForm;
use source\models\Product;
use source\models\Takonomy;
use source\libs\Common;
use source\core\widgets\ueditor\Ueditor;

/* @var $this yii\web\View */
/* @var $model app\models\Product */
/* @var $form yii\widgets\ActiveForm */

$filedOptions = [
    'template' => "{label}{input}\n{error}", 
    'labelOptions' => [
        'class' => 'control-label'
    ]
]
;

$takonomies = Takonomy::getArrayTree('product');

$options = Common::buildTreeOptions($takonomies, $model->takonomy_id);

?>

<div class="product-form ">


    <?php
                
$form = ActiveForm::begin([
                    'options'=>[
                        'enctype'=>'multipart/form-data',
                        
                        ],
                    'fieldConfig' => [
                        'template' => "{label}<div class=\"col-md-8\">{input}</div>\n{error}", 
                        'labelOptions' => [
                            'class' => 'col-md-4 control-label no-padding-left no-padding-right align-left'
                        ]
                    ], 
                    
                ]);
                ?>
    
<div class="row">
        <div class="col-md-9">
            <?= $form->field($model, 'title',$filedOptions)->textInput(['maxlength' => 256,'placeholder'=>'请输入标题'])?>

            <?= $form->field($model, 'url_alias',$filedOptions)->textInput(['maxlength' => 128,'placeholder'=>'Url 地址'])?>

            <hr class="hr">

            
            <?=$form->field($bodyModel, 'body',$filedOptions)->widget(Ueditor::className(),[
                'options'=>[
                    'focus'=>true,
                    'toolbars'=> [
                         ['fullscreen', 'source', '|', 'undo', 'redo', '|', 'bold', 'italic', 'underline','removeformat','autotypeset', '|', 'forecolor', 'backcolor', 'selectall', 'cleardoc','|','fontfamily', 'fontsize', '|', 'justifyleft', 'justifycenter', '|', 'link', 'unlink','|', 'insertimage', 'emotion','attachment','|', 'preview', 'searchreplace']  
                    ],
                ],
                'attributes'=>[
                    'style'=>'height:80px'
                ]
            ])?>
            
            
        </div>

        <div class="col-md-3 form-horizontal" >
    
            
             <div  class="form-group">
                <?= Html::submitButton($model->isNewRecord ? '新建' : '编辑', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary'])?>
            </div>

    </div>

</div>
<?php ActiveForm::end(); ?>

</div>

总结分析

1、要修改的地方还是挺多的,百度UEditor上传后获取图片路径保存到数据库处理起来也有点繁琐,如果你们有更好的方法,可以给我留言,咱们一块讨论。

2、以上我只是处理了图片上传到阿里云OSS,如果大家需要把视频,Mp3等等附件上传到阿里云OSS也是同样的方法,唯一的区别就是在提交表单的时候要获取到对应的视频,Mp3等等附件路径保存到数据库得处理一下。

相关资料

PHP-SDK 下载安装地址
ueditor 下载地址


zacklee
704 声望56 粉丝