下载鸥 > 网站下载 > 开发教程 > 帝国CMS

帝国cms默认编辑器UEdito读取远程图片失效

868 2021-02-20 09:30:34

收藏
帝国cms默认编辑器UEdito读取远程图片失效

帝国cms默认编辑器UEdito读取远程图片失效,失败的原因有2个,1是文件类型,也就是文件的扩展名验证不通过。2是当图片的地址后面带问号“?”,也就是地址后面带参数的时候,拉取远程图片会失败。

另外,验证时的扩展名问题解决了,就出现另一个问题,就是上传保存的实际的文件名没有扩展名。
 

 

原有逻辑

获取扩展名是依赖原始文件名的:

$imgUrl="https://upload-images.jianshu.io/upload_images/13291551-ea2071894c84a625.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/544/format/webp";
preg_match("/[/]([^/]*)[.]?[^./]*$/",$imgUrl,$m);
$this->oriName=$m?$m[1]:"";


这导致获取到的原始文件名是:/webp,原始文件名没有扩展名,就导致实际的文件名没有扩展名。
 

修改后的完整代码

<?php
classUploader
{
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不正确",
"ERROR_HTTP_ALLOWFILES"=>"抓取图片格式扩展名不正确",
"INVALID_URL"=>"非法URL",
"INVALID_IP"=>"非法IP"
);
/**
*构造函数
*@paramstring$fileField表单名称
*@paramarray$config配置项
*@parambool$base64是否解析base64编码,可省略。若开启,则$fileField代表的是base64编码的字符串表单名
*/
publicfunction__construct($fileField,$config,$type="upload")
{
$this->fileField=$fileField;
$this->config=$config;
$this->type=$type;
if($type=="remote"){
$this->saveRemote();
}elseif($type=="base64"){
$this->upBase64();
}else{
$this->upFile();
}
$this->stateMap['ERROR_TYPE_NOT_ALLOWED']=iconv('unicode','utf-8',$this->stateMap['ERROR_TYPE_NOT_ALLOWED']);
}
/**
*上传文件的主处理方法
*@returnmixed
*/
privatefunctionupFile()
{
$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;
}elseif(!file_exists($file['tmp_name'])){
$this->stateInfo=$this->getStateInfo("ERROR_TMP_FILE_NOT_FOUND");
return;
}elseif(!is_uploaded_file($file['tmp_name'])){
$this->stateInfo=$this->getStateInfo("ERROR_TMPFILE");
return;
}
$this->oriName=$file['name'];
$this->fileSize=$file['size'];
$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(!$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;
}elseif(!is_writeable($dirname)){
$this->stateInfo=$this->getStateInfo("ERROR_DIR_NOT_WRITEABLE");
return;
}
//移动文件
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编码的图片上传
*@returnmixed
*/
privatefunctionupBase64()
{
$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;
}elseif(!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];
}
}
/**
*拉取远程图片
*@returnmixed
*/
privatefunctionsaveRemote()
{
$imgUrl=htmlspecialchars($this->fileField);
$imgUrl=str_replace("&amp;","&",$imgUrl);
//http开头验证
if(strpos($imgUrl,"http")!==0){
$this->stateInfo=$this->getStateInfo("ERROR_HTTP_LINK");
return;
}
preg_match('/(^https*://[^:/]+)/',$imgUrl,$matches);
$host_with_protocol=count($matches)>1?$matches[1]:'';
//判断是否是合法url
if(!filter_var($host_with_protocol,FILTER_VALIDATE_URL)){
$this->stateInfo=$this->getStateInfo("INVALID_URL");
return;
}
preg_match('/^https*://(.+)/',$host_with_protocol,$matches);
$host_without_protocol=count($matches)>1?$matches[1]:'';
//此时提取出来的可能是ip也有可能是域名,先获取ip
$ip=gethostbyname($host_without_protocol);
//判断是否是私有ip
if(!filter_var($ip,FILTER_VALIDATE_IP,FILTER_FLAG_NO_PRIV_RANGE)){
$this->stateInfo=$this->getStateInfo("INVALID_IP");
return;
}
//获取请求头并检测死链
$heads=get_headers($imgUrl,1);
if(!(stristr($heads[0],"200")&&stristr($heads[0],"OK"))){
$this->stateInfo=$this->getStateInfo("ERROR_DEAD_LINK");
return;
}
//格式验证(扩展名验证和Content-Type验证)
if(!isset($heads['Content-Type'])||!stristr($heads['Content-Type'],"image")){
$this->stateInfo=$this->getStateInfo("ERROR_HTTP_CONTENTTYPE");
return;
}else{
if(count($this->config['allowFiles'])>0){
$fileType=strtolower(strrchr($imgUrl,'.'));
if(strpos($fileType,"?")){
$fileType=strstr($fileType,"?",true);
}
if(!in_array($fileType,$this->config['allowFiles'])){
//$this->stateInfo=$this->getStateInfo("ERROR_HTTP_ALLOWFILES");
//return;
}
}
}
//打开输出缓冲区并获取远程图片
ob_start();
$context=stream_context_create(
array('http'=>array(
'follow_location'=>false//don'tfollowredirects
))
);
readfile($imgUrl,false,$context);
$img=ob_get_contents();
ob_end_clean();
$imgUrl2=$imgUrl;
if(strpos($imgUrl,"?")){
$imgUrl2=substr($imgUrl,0,strripos($imgUrl,"?"));
}
preg_match("/[/]([^/]*)[.]?[^./]*$/",$imgUrl2,$m);
$this->oriName=$m?$m[1]:"";
if(!strpos($this->oriName,".")){
if(strpos($heads['Content-Type'],'/')){
$this->oriName.=".".substr($heads['Content-Type'],strpos($heads['Content-Type'],'/')+1);
}else{
$this->oriName.=".png";
}
}
$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;
}elseif(!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
*@returnstring
*/
privatefunctiongetStateInfo($errCode)
{
return!$this->stateMap[$errCode]?$this->stateMap["ERROR_UNKNOWN"]:$this->stateMap[$errCode];
}
/**
*获取文件扩展名
*@returnstring
*/
privatefunctiongetFileExt()
{
returnstrtolower(strrchr($this->oriName,'.'));
}
/**
*重命名文件
*@returnstring
*/
privatefunctiongetFullName()
{
//替换日期事件
$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;
}
/**
*获取文件名
*@returnstring
*/
privatefunctiongetFileName(){
returnsubstr($this->filePath,strrpos($this->filePath,'/')+1);
}
/**
*获取文件完整路径
*@returnstring
*/
privatefunctiongetFilePath()
{
$fullname=$this->fullName;
$rootPath=$_SERVER['DOCUMENT_ROOT'];
if(substr($fullname,0,1)!='/'){
$fullname='/'.$fullname;
}
return$rootPath.$fullname;
}
/**
*文件类型检测
*@returnbool
*/
privatefunctioncheckType()
{
returnin_array($this->getFileExt(),$this->config["allowFiles"]);
}
/**
*文件大小检测
*@returnbool
*/
privatefunctioncheckSize()
{
return$this->fileSize<=($this->config["maxSize"]);
}
/**
*获取当前上传成功文件的各项信息
*@returnarray
*/
publicfunctiongetFileInfo()
{
returnarray(
"state"=>$this->stateInfo,
"url"=>$this->fullName,
"title"=>$this->fileName,
"original"=>$this->oriName,
"type"=>$this->fileType,
"size"=>$this->fileSize
);
}
}

 

解决的问题

1、地址后面带参数的问题,获取不到正确的扩展名。

2、地址中不包含扩展名的问题,使用 content-type 过滤,取消文件扩展名的过滤;

3、获取不到正确的扩展名的时候,从 content-type 中获取,content-type 中也没有的话,设置默认的扩展名为 .png

本文地址:https://xzo.com.cn/develop/empire/420.html

有帮助,很赞!

信息来源:精准像素
导出教程 下载word版教程
发表评论 共有条评论
关于帝国CMS


帝国cms是一款功能极为强大的cms程序,性能强悍、安全性高,可轻松支持10万数据,高级开发人员可制作出能容纳千万数据量的网站,是国内最出色的开源cms程序之一,推荐企业用户使用

当前最新版本为7.5,8.0版本即将上线,新版本的核心优化点在于多终端的适配。

推荐帝国CMS开发教程
帝国cms博客怎样将发布时间设置为秒/分钟/小时/天/个月前?
帝国cms博客怎样将发布时间设置为秒/分钟/小时/天/个月前?

最近发现想要用帝国CMS开发博客的客户越来越多,但帝国cms本身更多的是支持企...

7 916
帝国cms取消用户邮箱必填(注册/修改资料/管理员编辑资料)
帝国cms取消用户邮箱必填(注册/修改资料/管理员编辑资料)

网上关于取消会员邮箱必填的教程很多,但大都不完整。今天放出完整版本,确保全...

12 708
帝国cms怎样将信息来源befrom外链转内链?
帝国cms怎样将信息来源befrom外链转内链?

很多技术分享型站点转载了外站不少信息,部分有素质的站长会展示信息来源并链...

27 3923
有办法将多个帝国CMS网站会员系统数据库进行整合和同步吗?
有办法将多个帝国CMS网站会员系统数据库进行整合和同步吗?

如果能将手里的资源合并,会员渠道打通,则用起来更加舒服。而帝国CMS自带的会...

3 523
帝国CMS多值字段怎样增加上传图片的功能?
帝国CMS多值字段怎样增加上传图片的功能?

帝国CMS多值字段是一个字段包含N条内容的方法,通过合理运用多值字段,我们可以...

1 408
帝国cms后台DoTimeRepage.php一直刷新写满日志了怎么办?
帝国cms后台DoTimeRepage.php一直刷新写满日志了怎么办?

如果平时喜欢挂着帝国cms网站后台不关闭,又留心了网站日志的朋友就会发现DoT...

1 622
Wordpress转为帝国cms将会出现的问题
Wordpress转为帝国cms将会出现的问题

帝国cms和Wordpress是完全不同的程序,其设计理念有着天壤之别。转换肯定会存...

3 736
帝国cms怎样调用图集第一张图片?
帝国cms怎样调用图集第一张图片?

帝国cms图片集非常好用,通过合理配置图片集,我们可以实现网站图集的展示,让页...

0 462
推荐插件
帝国cms百度AI图像清晰度增强api接口对接插件
帝国cms百度AI图像清晰度增强api接口对接插件

通过本插件,可以实现帝国cms网站对接百度云api实现图像清晰度增强的功能。经...

0 498
帝国cms在线考试系统模板插件
帝国cms在线考试系统模板插件

一直没看到好用的帝国cms在线考试插件,所以自己开发了一款。在线考试插件用...

0 1258
帝国cms百度AI图像去雾api接口对接插件
帝国cms百度AI图像去雾api接口对接插件

通过本插件,可以实现帝国cms网站对接百度云api实现图像去雾的功能。经过实际...

0 449
帝国cms多栏目多数据表自动审核推送插件
帝国cms多栏目多数据表自动审核推送插件

本插件基于帝国cms帝国cms每日自动审核插件,在自动审核指定条数信息的基础上...

0 891
帝国cms批量添加后台用户插件
帝国cms批量添加后台用户插件

使用帝国cms的企业用户、新闻资讯类站点的用户很多,此类站点很多时候需要有...

0 675
帝国CMS内网用户静态站点文章访客统计插件
帝国CMS内网用户静态站点文章访客统计插件

本插件适用于内网用户,可查看单篇文章访问者ip地址。如果添加访问者ip组,可查...

0 536
帝国cms智能自动审核按星期几审核指定栏目带推送插件
帝国cms智能自动审核按星期几审核指定栏目带推送插件

采集站的必备资源是自动审核,要做到日收录也离不开定时发布。而本插件的自动...

0 1274
帝国cms自动生成文章新闻目录插件下载
帝国cms自动生成文章新闻目录插件下载

用户体验是我们的需求,百度蜘蛛的认可更是我们的需求。毕竟,没有收录排名,何来...

0 1123
客服QQ:341553759
扫码咨询 常见问题 >
官方交流群:90432500
点击加入