帝国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

声明:有的资源均来自网络转载,版权归原作者所有,如有侵犯到您的权益 请联系邮箱:123456@qq.com 我们将配合处理!

原文地址:帝国cms默认编辑器UEdito读取远程图片失效发布于2022-07-16 07:44:12

相关推荐