帝国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("&","&",$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
声明:有的资源均来自网络转载,版权归原作者所有,如有侵犯到您的权益 请联系邮箱:123456@qq.com 我们将配合处理!
原文地址:帝国cms默认编辑器UEdito读取远程图片失效发布于2022-07-16 07:44:12