<?
if(!defined("CLASS_GggFileUpload"))
{
define("CLASS_GggFileUpload","1");
class GggFileUpload
{
var $mIsDebug=false; //设置调试状态,在类中调试会有错,不要在类中调试 false true
var $mStrErr=""; //出错的文本信息,如果IsDebug为真,则在出错后自动中止程序执行,输出错误信息
var $mIsErr=false; //上传是否出错状态标志
var $mIsFileRight=true; //ture将保证上传后的文件名只能由字母,数字,上下划线,点号组成
var $mIsFileLower=true; //ture将把文件名采用小写,在由于win与unix系统对文件名大小字敏感不同,会在下载文件时出现很多麻烦
var $mMaxFileNameLen=30; //文件名允许的最大长度
var $ExtFilter=array('php' => 'php_'); //这里设置要过虑的扩展名,比如所用户上传的 .php 的文件改成 .php_ 程序采用替换的的方法 比如 .php3 的会变被换成 .php_3
var $mInputName; //<input type=file name=aaa> 所对应的aaa, *保存的是一个字符窜
var $mFileType; //文件上传的类型
var $mFileSize; //文件上传的大小
var $mFileName; //文件上传的名字
var $mFileTmpName; //文件上传后的临时名
var $mFileUpPath; //文件要上传服务器地址
var $mFileUpType; //文件上传所允许的类型
var $mFileUpSize; //文件上传所允许的最大字节
var $mFileUpName; //文件上传后所用的名字,也就是要更改成的名字
var $mErrorFile="failt"; //文件名不法时更改成在 mErrorFile 为开始的文件名
/**+-----------------------------------------------
函 数 名: GggFileUpload
功能描述: GggFileUpload初始化
函数说明: 类的构造函数 用于初始化类的成员变量
调用函数: GggFileUpload()
参数:
$inputName
<input type=file name=aaa> 所对应的aaa, 保存的是一个字符窜
$fileUpPath
文件要上传服务器地址
$fileUpType
文件上传所允许的类型
$fileUpSize
文件上传所允许的最大字节 默认为 150000 字节
返 回: 无
设 计 者: ggg 日期: 2004-9-1 1:17
修 改 者: ggg 日期: 2004-9-1 1:17
版 本: 1.0
**+-----------------------------------------------
*/
function GggFileUpload($inputName,$fileUpPath,$fileUpType="",$fileUpSize=150000)
{
$this->Set_File($inputName);
$this->Set_FileUpPath($fileUpPath);
$this->Set_FileUpSize($fileUpSize);
$this->Set_FileUpType($fileUpType);
}//END GggFileUpload
function Show_Debug()
{
// if($this->mIsDebug && !empty($this->Get_StrErr()))
if($this->mIsDebug && !empty($this->mStrErr))
{
printf("<br>Debug:<font color=#ff00ff> %s</font><br>/n", $this->Get_StrErr());
}
}
//********************** Set 区
//设置错误变量
function Set_StrErr($varName)
{
$this->mIsErr=true;
if(!empty($varName))
$this->mStrErr=trim($varName);
}
//设置文件的属性
function Set_File($inputName)
{
if(!empty($inputName))
{
$this->mInputName=$inputName; //<input type=file name=aaa> 所对应的aaa, *保存的是一个字符窜
$this->mFileType=$_FILES[$inputName]["type"]; //文件上传的类型
$this->mFileSize=$_FILES[$inputName]["size"]; //文件上传的大小
$this->mFileName=$_FILES[$inputName]["name"]; //文件上传的名字
$this->mFileTmpName=$_FILES[$inputName]["tmp_name"]; //文件上传后的临时名
}
}
//设置文件文件名
function Set_FileName($filename)
{
if(!empty($filename))
$this->mFileName=trim($filename);
}
//设置文件要上传服务器地址
function Set_FileUpPath($fileUpPath)
{
if (strlen($fileUpPath) && substr($fileUpPath, -1) != '/')
{
$fileUpPath .= '/';
}
$this->mFileUpPath=trim($fileUpPath);
}
//设置文件上传所允许的最大字节
function Set_FileUpSize($fileUpSize)
{
if(!empty($fileUpSize) && ereg("^[1-9][0-9]*$",$fileUpSize))
$this->mFileUpSize=$fileUpSize;
}
//设置文件上传所允许的类型
function Set_FileUpType($fileUpType)
{
if(!empty($fileUpType))
$this->mFileUpType=trim($fileUpType); //文件上传所允许的类型
}
//********************** Get 区
//得到文件名
function Get_FileName()
{
return $this->mFileName;
}
//得到文件的类型
function Get_FileType()
{
return $this->mFileType;
}
//得到文件的大小
function Get_FileSize()
{
return $this->mFileSize;
}
//文件上传后的临时名
function Get_FileTmpName()
{
return $this->mFileTmpName;
}
//得到文件要上传服务器地址
function Get_FileUpPath()
{
return $this->mFileUpPath;
}
//得到文件上传所允许的最大字节
function Get_FileUpSize()
{
return $this->mFileUpSize;
}
//得到文件上传所允许的类型
function Get_FileUpType()
{
return $this->mFileUpType;
}
//得到错误代码
function Get_StrErr()
{
return $this->mStrErr;
}
//********************** Check 区
/**+-----------------------------------------------
函 数 名: Check_File
功能描述: 检查文件的合法性
函数说明: 直接调用
调用函数: Check_File()
参数:
设 计 者: ggg 日期: 2004-9-1 7:06
修 改 者: ggg 日期: 2004-9-1 7:06
版 本: 1.0
**+-----------------------------------------------
*/
function Check_File()
{
$file_tmp_name=$this->Get_FileTmpName(); //得到临时文件名
$file_name=$this->Get_FileName(); //得到文件名
$file_size=$this->Get_FileSize(); //得到文件大小
$file_up_size=$this->Get_FileUpSize(); //得到文件上传大小
//检查上传的文件是否存在
if(empty($file_tmp_name) || $file_tmp_name=="none" || !File_exists($file_tmp_name) || empty($file_size))//没选择要上传的文件,返回
{
$this->Set_StrErr("上传的文件不存在!");
$this->Show_Debug();
return false;
}
if(!is_writeable($this->Get_FileUpPath())) //如果上传至的目录可写
{
$this->Set_StrErr("上传文件目录:".$this->Get_FileUpPath()." 不存在或不可写,请先更改目录属性!");
$this->Show_Debug();
return false;
}
//验证上传文件的文件名的合法性
if($file_size>$file_up_size) //换成小写
{
$this->Set_StrErr("上传文件允许的最大尺寸为".$file_up_size."字节!!");
$this->Show_Debug();
return false;
}
//验证文件类型是否正确
if(false==$this->Check_FileUpType())
{
return false;
}
//验证上传文件的文件名的合法性
if($this->mIsFileLower) //换成小写
$file_name=$this->MyStrTolower($file_name);
//得到文件名与扩展名
$file_name_name=trim($this->Get_Str_Head($file_name,'.'));
$file_name_ext=trim($this->Get_Str_End($file_name,'.'));
if($this->mIsFileRight) //如果要保证文件名只能由字母,数字,上下划线,点号组成
{
if(!ereg("^[0-9a-z/._/-]+$",$file_name_ext))//看扩展名的合法性
{
$this->Set_StrErr("上传的扩展名:".$file_name_ext." 不符合标准,已去除扩展名");
$file_name_ext=""; //这里的处理是直接删除扩展名
$this->Show_Debug();
}
if(!ereg("^[0-9a-z/._/-]+$",$file_name_name)) //看文件名的合法性
{
//srand((double)microtime()*1000000);
$this->Set_StrErr("上传的文件名:".$file_name_name." 不符合标准");
$file_name_name=time().$this->mErrorFile;
//$file_name_name=rand(1,999).$this->mErrorFile;
$this->mStrErr.=",已改成:".$file_name_name."!";
$this->Show_Debug();
}
$file_name=$file_name_name.$file_name_ext; //重新得到新的文件名
}
//文件名过长处理
if(strlen($file_name)>$this->mMaxFileNameLen) //文件名过长
{
if(strlen($file_name_ext)>$this->mMaxFileNameLen) //如果扩展名大于所允许的最长字符 可能性很小
{
$this->Set_StrErr("扩展名长度大于:".$this->mMaxFileNameLen." !");
$file_name_ext=substr($file_name_name,0,5);
$this->Show_Debug();
}
if(strlen($file_name_name)>$this->mMaxFileNameLen) //如果文件名大于所允许的最长字符,也进行截取
{ //文件名的长度是根据 总长度 减 扩展名长度得到
$this->Set_StrErr("文件名长度大于:".$this->mMaxFileNameLen." !");
$file_name_name=substr($file_name_name,0,$this->mMaxFileNameLen-strlen($file_name_ext));
$this->Show_Debug();
}
}
//对扩展名进行过滤检查
while(list($k, $v) = each($this->ExtFilter))
{
if(strstr($file_name_ext,$k)) //扩展名包含了关键字了
{
$this->mStrErr.="扩展名包含了关键字了:".$k." !";
$file_name_ext=str_replace($k,$v,$file_name_ext);
$this->Show_Debug();
}
}
$file_name=$file_name_name.$file_name_ext; //重新得到新的文件名
//此时已得到最终的文件名
$this->Set_FileName($file_name); //重新设置类成员变量的文件名称
return !false;
}//END Check_File
/**+-----------------------------------------------
函 数 名: Check_File_Exits
功能描述: 检查上传的文件文件是否已存在
函数说明: 直接调用
调用函数: Check_File_Exits(fileName)
参数:
返 回: 返回 文件名
设 计 者: ggg 日期: 2004-9-1 21:45
修 改 者: ggg 日期: 2004-9-1 21:45
版 本: 1.0
**+-----------------------------------------------
*/
function Check_File_Exits($fileName)
{
//得到文件名与扩展名
$file_name_name=trim($this->Get_Str_Head($fileName,'.'));
$file_name_ext=trim($this->Get_Str_End($fileName,'.'));
//看将要上传的文件是不是已存在了,修改文件名
if(File_exists($this->Get_FileUpPath().$fileName))
{
$this->mStrErr.="要上传的文件名已存在:".$this->Get_FileUpPath().$fileName." !";
$file_name_name=substr($file_name_name,0,$this->mMaxFileNameLen);//为防止连续重复后文件名变得过长,在此截除
$count_i=0;
while(File_exists($this->Get_FileUpPath().$file_name_name.$count_i.$file_name_ext))$count_i++;//a1 a2 a3
$fileName=$file_name_name.$count_i.$file_name_ext; //重新得到新的文件名
}
return $fileName;
}
/**+-----------------------------------------------
函 数 名: Check_FileUpType
功能描述: 检查文件上传所允许的类型
函数说明: 直接调用
调用函数: Check_FileUpType()
参数:
返 回: 返回 true 或 false ,表示验证是否成功
设 计 者: ggg 日期: 2004-9-1 7:04
修 改 者: ggg 日期: 2004-9-1 7:04
版 本: 1.0
**+-----------------------------------------------
*/
function Check_FileUpType()
{
$file_up_type=$this->Get_FileUpType();
if(empty($file_up_type)) //如果文件类型没指定就表示允许所有的类型
{
return !false;
}
$file_type=$this->Get_FileType();
$array_filetype= explode(",", $file_up_type); //判断传过来的文件类型是否符合 以,分隔
for($count_i=0;$count_i<count($array_filetype);$count_i++)
{
$cnt_filetype=trim($array_filetype[$count_i]); //得到这次循环的文件类型
//$cnt_filetype_len=strlen($cnt_filetype);
if(strstr($file_type,$cnt_filetype)) //只要一个类型符合就通过
// if(substr($file_type, -$cnt_filetype_len)==$cnt_filetype) //只要一个类型符合就通过
{
break;
}
}
if($count_i==count($array_filetype)) //表示一项类型都不符合
{
$this->Set_StrErr("请确认上传的类型为".$file_up_type."!");
$this->Show_Debug();
return false;
}
return !false;
}// END Check_FileUpType
/**+-----------------------------------------------
函 数 名: UpLoad
功能描述: 上传文件
函数说明: 类的构造函数 用于初始化类的成员变量
可以采用 GggFileUpload("aaa.gif","aaa.gif");来更新文件的功能 来达到先删除服务器上 aaa.gif 再次上传的文件改成 aaa.gif 功能
如果不指定 originalFile 可运用于第一次添加文件的状态
调用函数: GggFileUpload($keepName,$originalFile)
参数:
$keepName
指定其参数表示上传文件后以keepName命名文件名,但如果该文件已存在或文件名检查不通过程序会在对该文件名进行修改
$originalFile
原来的文件名,设置该项用于更新.程序会在文件上传前先删除originalFile
返 回: 上传失败返回空 否则返回上传成功后的文件名
设 计 者: ggg 日期: 2004-9-1 5:55
修 改 者: ggg 日期: 2004-9-1 5:55
版 本: 1.0
**+-----------------------------------------------
*/
function UpLoad($keepName="",$originalFile="")
{
if(!empty($keepName))
{
$this->Set_FileName($keepName); //改变上传的文件名
$this->Set_StrErr("改变上传的文件名1: ".$this->Get_FileName());
$this->Show_Debug();
}
//检查上传的文件大小类型等,并重命名有问题的文件名..
if(false==$this->Check_File())
{
// $this->Set_StrErr("检查上传的文件有问题: Check_File ");
// $this->Show_Debug();
if(!empty($originalFile))
return $originalFile;
else
return "";
}
//删除原来存在的文件 编辑状态使用
if(!empty($originalFile) && File_exists($this->Get_FileUpPath().$originalFile))
{
@unlink($this->Get_FileUpPath().$originalFile);//先删除originalFile文件
$this->Set_StrErr("删除了: ".$this->Get_FileUpPath().$originalFile." 文件");
$this->Show_Debug();
}
$this->Set_FileName($this->Check_File_Exits($this->Get_FileName())); //检查文件是否存在,生成新文件名
/*
$this->Set_File($inputName);
$this->Set_FileUpPath($fileUpPath);
$this->Set_FileUpSize($fileUpSize);
$this->Set_FileUpType($fileUpType);
print($this->mInputName."<br>");
print($this->mFileUpType."<br>");
print($this->mFileUpSize."<br>");
print($this->mFileUpPath."<br>");
print($this->mFileType."<br>");
print($this->mFileSize."<br>");
print($this->mFileName."<br>");
print($this->mFileTmpName."<br>");
*/
if(is_uploaded_file($this->Get_FileTmpName()))
{
@move_uploaded_file($this->Get_FileTmpName(),$this->Get_FileUpPath().$this->Get_FileName());
}
else
{
$this->Set_StrErr("检查上传的文件有问题: ".$this->Get_FileTmpName()." is_uploaded_file");
$this->Show_Debug();
return "";
}
/* 即使复制成功也返回失败。不知道是什么原因
if(copy($this->Get_FileTmpName(),$this->Get_FileUpPath().$this->Get_FileName())==false); //上传文件
{
$this->Set_StrErr("复制档案: ".$this->Get_FileUpPath().$this->Get_FileName()." 失败");
$this->Show_Debug();
return "";
}*/
//@unlink($this->Get_FileTmpName());//删除临时文件
return $this->Get_FileName();
}
/* 得到以某字符间隔的字符头,尾部 */
function Get_Str_Head($varName,$separator='.') //返回文件的名字
{
// print($varName);
// die();
$file_len=0;
if(!($file_len=strrpos($varName, $separator))) //如果文件没有扩展名,文件名即为全文件
{
$file_len=strlen($varName);
}
$file_name=substr($varName,0,$file_len); //得到上传文件名字
return(substr($varName,0,$file_len));
}//Get_Str_Head()
function Get_Str_End($varName,$separator='.') //返回文件的扩展名
{
$file_len=0;
$file_ext="";
if($file_len=strrpos($varName, $separator)) //如果文件没有扩展名,文件名即为全文件,扩展名空
{
$file_ext=substr($varName,-(strlen($varName)-$file_len)); //得到上传文件的扩展名
}
return($file_ext);
}//Get_Str_End()
// 自定义将字串里的小写全部转成大写,但不破坏中文字
function MyStrTolower($varName)
{
return preg_replace('/[A-Z]+/e',"strtolower('//0')",$varName);
}
}// END class GggFileUpload
}
//********************* 类测试
//********************* 类测试
//********************* 类测试
/*
if("submit"==$_POST["command"])
{
//允许多种文件上传可以用 text,image,application 用逗号间隔进行传递
$t = new GggFileUpload("filename","../test/","text,image"); //如果不指定允许的文件类型。默认是所有文件
// $t->UpLoad("ggg.txt","ggg.txt"); //上传文件前先删除 ggg.txt 文件,然后把上传后的文件名改成ggg.txt
$new_file_name=$t->UpLoad(); //直接把 文件上传到网上
if(empty($new_file_name)) //new_file_name 为空肯定是文件上传失败
{
print("文件上传失败");
}
else
{
print("文件上传成功");
}
print($t->Get_FileName());
// $t = new GggFileUpload("filename","../test/","text,image");
// $t->UpLoad($keepName="ggg.txt",$originalFile="ggg.txt");//这里实现同名覆盖
// $t->Set_File("filename1","../test/","text,image");//这里设置第二个文件上传参数
// $t->UpLoad();//进行第二个文件的上传.
// $t->Set_File("filename2");//这里设置第三个文件上传参数
// $t->UpLoad();//进行第三个文件的上传.
}
else
{
// $str="用C++C扩展PHP.html";
// $str=preg_replace('/[A-Z]+/e',"strtolower('//0')",$str);
// $str=preg_replace('/[/x0-/x9f][A-Z]+/e',"strtolower('//0')",$str);
echo $str;
print("<HTML><HEAD><TITLE>文件上传类测试</TITLE><META HTTP-EQUIV='Content-Type' CONTENT='text/html; charset=gb2312'> </HEAD><BODY BGCOLOR='#FFFFFF' TEXT='#000000'><TABLE WIDTH='80%' BORDER='1' CELLSPACING='0' CELLPADDING='0' ALIGN='CENTER'> <FORM NAME='form1' METHOD='post' ACTION='".$HTTP_SERVER_VARS['PHP_SELF']."' ENCTYPE=multipart/form-data> <TR><TD ALIGN='CENTER'>文件上传类测试<INPUT TYPE='file' NAME='filename'><INPUT TYPE='submit' NAME='Submit2' VALUE='上传文件'><INPUT TYPE='hidden' NAME='command' VALUE='submit'></></TD></TR> </FORM></TABLE> </BODY></HTML>");
}
*/
//!!!!!!!!!!!!!!!!!!!!! 类测试
//!!!!!!!!!!!!!!!!!!!!! 类测试
//!!!!!!!!!!!!!!!!!!!!! 类测试
?>