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

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

878 2021-02-20 09:30:34

收藏

帝国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之一,其程序效率毫无疑问。但,帝国CMS真的可以做...

19 1362
帝国cms怎样删除收藏的信息?
帝国cms怎样删除收藏的信息?

帝国cms是支持收藏功能的,但如果要删除收藏则不是很方便,通过本教程可以实现...

1 361
帝国cms安装报错fatal error:require():Failed opening required ../class/EmpireCMS_version.php(include_path=.
帝国cms安装报错fatal error:require():Failed opening required ../class/EmpireCMS_version.php(include_path=.

帝国CMS安装报错 fatal error:require():Failed opening required ../clas...

1 724
帝国cms会员中心怎样调用我提交的反馈历史记录?
帝国cms会员中心怎样调用我提交的反馈历史记录?

帝国cms信息反馈表非常好用,通过合理开发信息反馈功能,我么可以实现用户留言...

1 359
帝国cms灵动标签日期用英文显示的方法
帝国cms灵动标签日期用英文显示的方法

我们知道,帝国cms的日期可以根据需要调用问多种格式,如x年x月x日、年-月-日、...

0 400
帝国CMS怎样配置勾选会员注册协议才能注册
帝国CMS怎样配置勾选会员注册协议才能注册

帝国CMS默认注册是没有会员注册协议的。但如果从严谨的角度出发,不勾选&ldqu...

0 731
帝国cms彩色tag标签样式分享
帝国cms彩色tag标签样式分享

帝国cms标签列表如果做死板的展示可能不大好看,如果能增加一些色彩,无疑会让...

0 467
栏目目录搭建的帝国cms网站怎样写伪静态规则?
栏目目录搭建的帝国cms网站怎样写伪静态规则?

如果用栏目搭建帝国cms站点,伪静态规则该怎么写呢?如果直接作用于根目录,可能...

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

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

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

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

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

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

0 1148
帝国cms纳米数据接口(足球比赛中最新数据)
帝国cms纳米数据接口(足球比赛中最新数据)

帝国cms 对接纳米数据(www.nami.com)接口,本接口主要接收、整理足球比赛实时数...

0 452
帝国cms访问统计ip地址链接与封禁插件下载
帝国cms访问统计ip地址链接与封禁插件下载

下载鸥开发了这款帝国cms封禁ip插件,自动记录访问情况,让我们可以更快的识别...

0 1059
帝国cms联想词搜索高级搜索插件下载
帝国cms联想词搜索高级搜索插件下载

帝国CMS自带的搜索功能虽然强大,但也有很强的局限性 -- 必须关键词完全匹配...

0 759
帝国cms百度AI黑白图像上色api接口对接插件
帝国cms百度AI黑白图像上色api接口对接插件

百度开放了系列AI功能api如图像上色、图像去雾、图像修复、无损放大、清晰...

0 451
帝国cms百度AI图像无损放大api接口对接插件
帝国cms百度AI图像无损放大api接口对接插件

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

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