为了账号安全,请及时绑定邮箱和手机立即绑定

yii2.0使用ueditior完成上传单张,多张图片,上传视频等操作

标签:
PHP

一、前言

      由于工作需求需要集成富文本编辑器,本来是想要选用之前用过的WangEditor的,但是考虑到WangEditor还是比较小众,所以最终选择了没用过的Uedtor,这篇文章主要讲述了Yii2.0集成Ueditor的基本配置,以及上传单张,多张图片,上传视频的问题。

二、集成Yii2-ueditor-widget以及基本的配置

1、选用kucha/ueditor

      在开始之前,肯定是要先搜索一下有没有第三方插件的Ueditor的,直接引入的话,会比较麻烦,用的时候需要改命名空间等,所以这边直接选用了裤衩大神写的插件。

2、相关配置

      博主在通过composer引入之后,然后按照裤衩大神的配置大致配置了一下。但是由于文档有限,好多地方还是似懂非懂的,走了不少弯路,这边详细记录一下配置的过程

(1)假定你按照github上面的配置了一遍,一定是似懂非懂的状态

首先,假如说你是要在NewsController下使用富文本编辑器,那么首先操作是:

//这个东西是必须要配置的,位置的话没什么特别的要求,直接加到控制器里面就行了,具体的
//配置参照注释
 public function actions()
    {
        return [
            'upload' => [
                'class' => 'kucha\ueditor\UEditorAction',
                'config' => [
                    "imageUrlPrefix"  => "",//图片访问路径前缀
                    "imagePathFormat" => "/img/{time}{rand:6}", //上传保存路径
                    "imageFieldName"          => "xxx",  //这个我怀疑是随便写都行
                    "imageActionName"         => "uploadimage",  //这里uploadimage一定要用小写,请求的时候,会自动拼接action 上去,类似于:
 //http://xxxxxx.com/index.php?r=xxxx/upload&action=uploadimage    具体参考UEditorAction的48行
                ],
            ]
        ];
    }

(2)其次是使用activeForm引入编辑器

 			 echo $form->field($model,'content')->widget('kucha\ueditor\UEditor',['id'=>'content','name'=>'content','clientOptions' => [
            'serverUrl'=>$url,  //这个是上传图片用到的方法的路由
            'lang' =>'en', //中文为 zh-cn
            'initialFrameHeight' => '400', //编辑器显示高度
            'autoHeightEnabled'=>false, //出现滚动条
            //定制菜单  //'insertvideo',  这个是上传视频tab
            'toolbars' => [
                [
                    'fullscreen', 'source', 'undo', 'redo', '|',
                    'fontsize',
                    'bold', 'italic', 'underline', 'fontborder', 'strikethrough', 'removeformat',
                    'formatmatch', 'autotypeset', 'blockquote', 'pasteplain', '|',
                    'forecolor', 'backcolor', '|',
                    'lineheight', '|',
                    'indent', '|','simpleupload','insertimage','justifyleft', 'justifyright', 'justifycenter', 'justifyjustify', //两端对齐
                ],
            ]]]);

      上面是编辑器的一些配置,可以直接引用的。相关的菜单博主去掉了不少,只保留需要用到的,主要是上传图片等。那个出现滚动条的配置是防止编辑器里面内容过多,把页面撑变形。

(3)刷新页面,控制套报错:Server config format error.

      很明显是咱们的配置出现了问题。这里困扰了博主挺久的,主要是不知道该从哪里进行排错,既然是服务器配置问题,那是有八九是config引入的问题。具体的请参考上面actions的配置,主要是imageActionName这项,一定要是小写的uploadimage ,因为在上传方法中,使用的就是这个方法。

其次就是我们配置actions的时候,是return了一个upload数组,所以控制器要新增:

public functon upload(){
}

OK,刷新页面,错误消失,终于看到了传说中的Ueditor

三、上传单张图片

1、上传图片的配置

      点击上传图片,经过的步骤都有哪些呢?基本上点击上传之后都会报错,因为我们的配置还没有结束,大家可以参考下上传类的源码,根据源码一步步调试:

(1) 源码部分参考:UEditorAction.phphandleAction()方法,可以根据源码一步步查看,也就那些上传的步骤,大家一看就懂

(2) 上传使用的是Uploader.php类,进入里面先初始化,上传图片执行:upFile() 方法

(3) serverUrl一定要配置一下,不然上传图片会报错,访问不到指定的控制器方法
这里的$url就是自己定义的路径,大概是:?r=你的控制器名字/upload

      大家按照上面的方法一步步调试,基本上传图片就走通了,在执行完upFile() 方法之后,会返回指定格式的数组,数组中的url就是我们图片的地址,大家可以打印着看一下。

2、上传成功之后,编辑器内不显示图片,只是显示一串字符串的问题

      如果是把图片直接上传到根项目内,是不会出现这个问题的,直接就能访问到。我这边是把图片上传到了项目外,所以访问才出现了问题,虽然返回了url,但是根本无法访问项目外的文件。

(1) 打印返回的数据

		original: "14683807384225690.jpg"
				size: 10618
				state: "SUCCESS"
				title: "news"
				type: ".jpg"
				url: "电脑上图片的绝对路径"

(2) 点击编辑器左上角的html,我们可以看到,img标签的src引入的就是这个url的地址。因为图片是在项目外,所以并不能通过file:///文件协议直接访问到
(3) 通过替换返回的url值,返回一个接口地址,通过接口去读取图片流,返回给img的src即可

替换的地方:Uploader.php的upFile()方法:

	//$this->filePath = $this->getFilePath();
 $this->filePath = \Yii::getAlias('@out_news');   这一步先替换路径为自己的路径
	//移动文件部分,拼接成自己的路径即可
Uploader.php的getFileInfo()方法:
	$name = substr($this->imgName,5);
    // 这里本来返回的是全路径的图片地址,例如:C:\phpStudy\PHPTutorial\WWW/xxx/1562124088174261.jpg
    //因为我把图片上传到了非项目目录,所以直接通过这个路径访问不到后续的图片。为了防止麻烦,索性拼接php接口地址
    //访问php接口,返回图片资源,然后ueditor再把图片资源赋值给img的src即可正常显示
    
    $http_url = "?r=xxxx/xxxxx&&imageName=".$name;
    return array(
        "state"    => $this->stateInfo,
       // "url"      => $this->fullName,
        "url"      => $http_url,
        "title"    => $this->fileName,
        "original" => $this->oriName,
        "type"     => $this->fileType,
        "size"     => $this->fileSize
    );

关于接口读取图片,返回图片流的部分,需要的话可以参考:
网页上的base64码太长?科普base64到底是啥

      如此单图片上传就算是完成了,能在编辑器中直接看到上传的图片。

四、上传多张图片

      单张图片完成上传之后,点击多图上传,本以为会老老实实的成功,结果却发现图片报错:http error !!!

1、查看network,发现路径为:
http://xxxx.com/assets/e96af72c/dialogs/image/image.html?r=xxxxx&action=uploadimage&encode=utf-8
      很明显并不是yii的路由路径,此处猜测应该是没有限定根目录造成的,也就是serverUrl不够严谨造成的。

2、修改serverUrl

			 $url = "/index.php/?r=xxxx/upload";  //把/index.php/拼上即可

原来我写的地址是直接/?r=xxxx/upload,没有加上前面的index.php

3、多图上传成功,编辑器内正常显示,图片正常存储。

五、上传视频

      上传视频的方法,我们可以去config里面看看,定义的有上传方法名称。博主本来还担心上传视频会很麻烦,实际上只要走上传图片部分的逻辑就好了,使用上传图片的方法也能够成功保存mp4文件。

(1) 上传视频不能正常播放问题,参考:
https://www.cnblogs.com/yuan951/p/7286242.html

这里就按照这个博主的配置,配置一下就可以。

(2) php读取mp4文件,返回流给video标签的src,视频播放,此处应该有代码

      还是老问题,我这边访问不到项目外的文件,因此使用php解析mp4文件,返回流给video标签展示

public function actionUploadVideo()
{
    header("Content-type: video/mp4");
    header("Accept-Ranges: bytes");
    Yii::$app->response->format = Response::FORMAT_JSON;
    $objStr = new StringUtil();
    $g_data = $objStr->strStripslashes($_GET);
    $db_g_data = $objStr->strAddslashes($g_data);
    $video = isset($db_g_data ['videoName']) ? $db_g_data ['videoName'] : "";
    $path = \Yii::getAlias('@out_news');
    $file = $path . "/video/".$video;
    $size = filesize($file);
    if(isset($_SERVER['HTTP_RANGE'])){
        header("HTTP/1.1 206 Partial Content");
        list($name, $range) = explode("=", $_SERVER['HTTP_RANGE']);
        list($begin, $end) =explode("-", $range);
        if($end == 0) $end = $size - 1;
    }
    else {
        $begin = 0; $end = $size - 1;
    }
    header("Content-Length: " . ($end - $begin + 1));
    header("Content-Disposition: filename=".basename($file));
    header("Content-Range: bytes ".$begin."-".$end."/".$size);
    $fp = fopen($file, 'rb');
    fseek($fp, $begin);
    while(!feof($fp)) {
        $p = min(1024, $end - $begin + 1);
        $begin += $p;
        echo fread($fp, $p);
    }
    fclose($fp);
}

(3) src会自动清空问题,以及切换html标签之后,视频变成图片的问题

      在视频能正常显示之后,我们会发现点击切换html标签,再切换回来的时候,视频消失了,变成了图片。这个问题貌似ueditor也发现了,具体的参考下面的链接吧,改一改源码即可。
参考: https://blog.csdn.net/yingjia11/article/details/78472261

(4) 上述问题是解决了,但是视频无法删除?

暂时没什么好方案,点击html删除视频吧

六、获取数据

以上完成之后,基本上就没什么难点了,剩下的就是获取数据的操作,这边简单列出一下:
1、获取编辑器中的内容

var content = UE.getEditor("activeForm中的id").getContent();

关于jquery怎么获取ueditor中的内容,可以参考:https://blog.csdn.net/qq_37138818/article/details/83653881

2、如果报错:Cannot read property ‘offsetWidth’ of null

可以参考:https://q.cnblogs.com/q/111336/ (不过考虑到是composer安装,自动初始化的,遇到这个问题的可能性小)

3、获取之后,剩下的就是业务逻辑了。如果要给编辑框赋值,采用函数:

				UE.getEditor("activeForm中的id").setContent("你要赋值的内容");

七、使用ueditor的感受

      通过近一天的配置,博主终于可以正常使用ueditor的相关功能,只是感觉麻烦,非常之麻烦。遇到问题总是要动源码部分,每次给源码动刀都心惊肉跳的,生怕影响到了其他功能。个人感觉上还是WangEditor更好用一些,最起码轻量级,够简单。

============ 2019年7月8日补充 ==========================

1、修改默认上传图片的/upload

这个路由看起来不够明显,并不能一眼知道它到底是哪部分的上传,所以最好是按照自己的业务逻辑修改下,比如改成/news-upload

(1)只是修改actions里面的upload为news-upload的话,会报错,server config错误。
	  return [
        'news-upload' => [
            'class' => 'kucha\ueditor\UEditorAction',
(2)console控制台发现有个请求http://xxx.com/index.php/?r=gm/upload&action=config&&noCache=1562556059012‘
	这个链接的意思是请求ueditor的配置文件,但是很明显,这里的请求是错误的,路由并不是最新的路由
(3)在ueditor_all_js的8246行,打印url,发现url还是旧的方法。
(4)实在找不到这个在哪配置了,肯定是serverUrl的锅,参考:https://www.oschina.net/question/274219_240962?sort=time
	本来以为会是Ueditor.php的init()方法中重写serverUrl,不过既然我们初始化的时候配置过serverUrl了,那么应该是以初始化的
	配置为基准的。
(4)修改初始化编辑器里面的serverUrl,改为news-image这个新的方法
(5)刷新页面,请求成功,编辑器没再出错,上传图片功能可以正常使用

2、再次理解serverUrl是干嘛的

	关于serverUrl,如果还有些疑惑的话,可以在ueditor.all.js中搜索:me.getOpt('serverUrl')  ,大概是在24506行,会发现
拼接了一个form表单的action,用我们设置的serverUrl当做表单的action。然后去页面上搜索“edui_form_”,查看元素就会发现,
这个id对应的就是上传图片的小图标。

end

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消