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

帝国CMS教程

帝国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,原始文件名没有扩展名,就导致实际的文件名没有扩展名。

修改后的完整代码如下:

<?phpclassUploader{private$fileField;//文件域名private$file;//文件上传对象private$base64;//文件上传对象private$config;//配置信息private$oriName;//原始文件名private$fileName;//新文件名private$fullName;//完整文件名,即从当前配置目录开始的URLprivate$filePath;//完整文件名,即从当前配置目录开始的URLprivate$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]:'';//判断是否是合法urlif(!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);//判断是否是私有ipif(!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

标签: 帝国cms官网