PHP通用文件上传类

由于做项目中经常遇到文件上传,因此封装了一个通用的文件上传类,作用支持组文件上传,并且不同的上传域可以上传不同的文件类型,不同的文件类型限制的文件大小也可能不相同。举例来说:用户可上传一种展品并可为该展品上传一张缩略图,那么缩略图文件限制类型可能为jpg,gif,png等,而展品文件限制类型可能为mov,avi,mpeg等,而图片大小可能限制为100KB,音频视频大小可能限制为2MB。类代码如下:/*文件上传类*/classUpload{public$InputName;//文件上传域控件名/***允许上传的文件类型*形式为array(”image/jpeg”,”image/png”,”image/gif”)或包含此类数组的数组*/public$FileType;/***最大上传文件大小*形式为array(”image”=$size,”audio”=$size)或包含此类数组的数组或一数值*/public$FileMaxSize;public$FileSavePath;//文件保存路径public$FileSaveName;//文件保存名public$NoteFileFalse;//文件错误提示public$NoteFileType;//文件类型不符提示public$NoteFileSize;//文件大小超出提示/*上传文件并返回文件名信息*/publicfunctionUploadFile(){$this-CheckFile();//检验文件$file=$_FILES[$this-InputName];$file_number=count($file[”name”]);//要上传的文件数$file_save_full_name=array();//文件保存名for($i=0;$i$file_number;$i++){$name=$file[”name”][$i];if(!empty($name))//文件不为空{/*确定文件保存路径*/if(is_array($this-FileSavePath)){$file_save_path=$this-FileSavePath[$i];}else{$file_save_path=$this-FileSavePath;}/*确定文件保存名*/if(is_array($this-FileSaveName)){$file_save_name=$this-FileSaveName[$i];}else{$file_save_name=$this-FileSaveName;}/*开始保存*/$this-CreatePath($file_save_path);//如果路径不存在则创建路径if(!move_uploaded_file($file[tmp_name][$i],$file_save_path.$file_save_name.$this-GetSuffix($file[”name”][$i]))){die($name.”文件上传失败”);}else{$file_save_full_name[]=$file_save_name.$this-GetSuffix($file[”name”][$i]);}}else{$file_save_full_name[]=null;}}unlink($file);/*如果只有一个文件,则返回单个文件名*/if(count($file_save_full_name)==1){$file_save_full_name=$file_save_full_name[0];}return$file_save_full_name;}/*检验文件*/privatefunctionCheckFile(){$file=$_FILES[$this-InputName];$file_number=count($file[”name”]);//要上传的文件数for($i=0;$i$file_number;$i++){if(!empty($file[”name”][$i]))//文件不为空{$name=$file[”name”][$i];$type=$file[”type”][$i];$size=$file[”size”][$i];$error=$file[”error”][$i];/*确定允许上传文件类型列表*/if(is_array($this-FileType[0])){$file_type=$this-FileType[$i];}else{$file_type=$this-FileType;}/*确定最大上传文件大小*/if(is_array($this-FileMaxSize)){$file_max_size_key=explode(”/”,$type);$file_max_size_key=$file_max_size_key[0];if(is_array($this-FileMaxSize[0])){$file_max_size=$this-FileMaxSize[$i][$file_max_size_key];}else{$file_max_size=$this-FileMaxSize[$file_max_size_key];}}else{$file_max_size=$this-FileMaxSize;}/*文件错误*/if($error0){die($name.
$this-NoteFileFalse);}/*文件类型不符*/if(!in_array($type,$file_type)){die($name.
$this-NoteFileType);}/*文件大小超过最大上传文件大小*/if(!is_null($file_max_size)$size$file_max_size){die($name.
$this-NoteFileSize);}}}}/*获取文件后缀名*/privatefunctionGetSuffix($fileName){returnsubstr($fileName,strrpos($fileName,.));}/*如果路径不存在则创建路径*/privatefunctionCreatePath($filePath){if(!file_exists($filePath)){mkdir($filePath);}}}
使用方法:接着以本文开头所举例子来说明该类的调用方法:$upload_澳门新葡萄京官网注册 ,obj = new
Upload(); // 文件上传对象$upload_obj-InputName = ”upload_test”; //
文件上传域控件名$upload_obj-FileType = array(array(”image/jpeg”,
”image/png”), array(”audio/mpeg”, ”video/x-msvideo”)); //
允许上传的文件类型$upload_obj-FileMaxSize = array(”image” = 100 *
1024, ”audio” = 2 * 1024 * 1024, ”video” = 2 * 1024 * 1024);
$upload_obj-FileSavePath = array(”upload/files/s/”,
”upload/files/z/”);$upload_obj-FileSaveName =
time();$upload_obj-NoteFileFalse =
”文件错误”;$upload_obj-NoteFileType =
”文件类型不符”;$upload_obj-NoteFileSize =
”文件大小超出”;$file_save_full_name = $upload_obj-UploadFile(); //
上传并获取文件全名总结:就此可轻松实现若干文件上传,其实归根结底用到了PHP组文件上传,要注意的就是控件名的name后别忘了加上[],这样的好处就是遇到多个文件上传时就不用在调用层进行循环或一个一个处理上传了,我们的应用也因此而轻松。

示例代码:

 代码如下

<form action=”” method=”post” enctype=”multipart/form-data” >
<input type=”file” name=”uploadfile[]”>   命名必是这样有”[]”
<input type=”file” name=”uploadfile[]”>

//设置允许用户上传的文件类型。
$type = array(‘gif’, ‘jpg’, ‘png’, ‘zip’, ‘rar’);
$upload = new uploadfile($_files[‘uploadfile’], ‘/’, 1024*1024,
$type);
参数说明:1:表单的文件,2:上传目录,3:支持文件大小,4:允许文件类型
$icount = $upload->upload();
if($icount > 0) { //上传成功
   print_r($upload->getsaveinfo());
  */

class uploadfile {
var $postfile = array();       // 用户上传的文件
var $custompath = “”;          // 自定义文件上传路径
var $maxsize = “”;             // 文件最大尺寸
var $lasterror = “”;           // 最后一次出错信息
var $allowtype = array(‘gif’, ‘jpg’, ‘png’, ‘zip’, ‘rar’, ‘txt’, ‘doc’,
‘pdf’);
var $endfilename = “”;         // 最终保存的文件名
var $saveinfo = array();       // 保存文件的最终信息
var $root_dir = “”; // 项目在硬盘上的位置

/**
* 构造函数
* @access public
*/

 代码如下

function uploadfile($arrfile, $path=”_”, $size = 2097152, $type = 0)
{
   $this->postfile     = $arrfile;
   $this->custompath   = $path == “_” ? “” : $path ;
   $this->maxsize      = $size;
   if($type!=0)   $this->allowtype   = $arrfile;
   $this->root_dir      = $_server[‘document_root’];
   $this->_mkdir($this->custompath);
}

/**
* 文件上传的核心代码
* @access public
* @return int 上传成功文件数
*/

 代码如下

function upload() {
   $ilen = sizeof($this->postfile[‘name’]);
   for($i=0;$i<$ilen;$i++){
    if ($this->postfile[‘error’][$i] == 0) {
//上传时没有发生错误
      //取当前文件名、临时文件名、大小、扩展名,后面将用到。
     $sname   = $this->postfile[‘name’][$i];
     $stname = $this->postfile[‘tmp_name’][$i];
     $isize   = $this->postfile[‘size’][$i];
     $stype   = $this->postfile[‘type’][$i];
     $sextn   = $this->_getextname($sname);
   
     //检测当前上传文件大小是否合法。
     if($this->_checksize){
      $this->lasterror =
“您上传的文件[“.$sname.”],超过系统支持大小!”;
      $this->_showmsg($this->lasterror);
      continue;
     }

     if(!is_uploaded_file($stname)) {
      $this->lasterror = “您的文件不是通过正常途径上传!”;
      $this->_showmsg($this->lasterror);
      continue;
     }
     $_filename = basename($sname,”.”.$sextn).”_”.time().”.”.$sextn;
     $this->endfilename = $this->custompath.$_filename;
   
     if(!move_uploaded_file($stname,
$this->root_dir.$this->endfilename)) {
      $this->lasterror = $this->postfile[‘error’][$i];
      $this->_showmsg($this->lasterror);
      continue;
     }

     //存储当前文件的有关信息,以便其它程序调用。
     $this->save_info[] =   array(“name” => $sname, “type”
=> $sextn, “size” => $isize,   “path” =>
$this->endfilename);
    }
   }

   return sizeof($this->save_info);
}

 

 

/**
* 得到上传信息
* @access public
* @return array 保存信息
*/
function getsaveinfo(){
   return $this->save_info;
}

 

/**
* 得到文件名的扩展名
* @access private
* @return string 返回文件扩展名
*/
private function _getextname($filename){
   $arrparts = pathinfo($filename);
   return $arrparts[‘extension’];
}

/**
* 判断文件大小
* @access private
* @return boolean 传入size大于系统定义,则true,反之false
*/
private function _checksize($size){
   return $size > $this->maxsize;
}

/**
* 输出错误信息
* @access private
* @return void
*/
private function _showmsg($msg){
   printf(“<b><错误信息:></b> %s <br>n”,
$msg);
}

/**
* 新增多级目录
* @access private
* @return void
*/
private function _mkdir($p){
   $ap = split(‘[/]’, $p);
   foreach($ap as $v){
    if(!empty($v)){
     if(empty($path)) $path=$v;
     else $path.=’/’.$v;
     file_exists($this->root_dir.”/”.$path) or
mkdir($this->root_dir.”/”.$path);
    }
   }
}
}

/*

}

 

/**//*
//注意,上传组件name属性不管是一个还是多个都要使用数组形式,如:
<input type=”file” name=”user_upload_file[]”>
<input type=”file” name=”user_upload_file[]”>

//如果用户点击了上传按钮。
if ($_post[‘action’] == “上传”) {
//设置允许用户上传的文件类型。
$type = array(‘gif’, ‘jpg’, ‘png’, ‘zip’, ‘rar’);
//实例化上传类,第一个参数为用户上传的文件组、第二个参数为存储路径、
//第三个参数为文件最大大小。如果不填则默认为2m
//第四个参数为充许用户上传的类型数组。如果不填则默认为gif, jpg, png,
zip, rar, txt, doc, pdf
$upload = new uploadfile($_files[‘user_upload_file’], ‘j:/tmp’,
100000, $type);
//上传用户文件,返回int值,为上传成功的文件个数。
$num = $upload->upload();
if ($num != 0) {
echo “上传成功<br>”;
//取得文件的有关信息,文件名、类型、大小、路径。用print_r()打印出来。
print_r($upload->getsaveinfo());

echo $num.”个文件上传成功”;
}
else {
echo “上传失败<br>”;
}
}

* @(#)uploadfile.php
*
* 可同时处理用户多个上传文件。效验文件有效性后存储至指定目录。
*
可返回上传文件的相关有用信息供其它程序使用。(如文件名、类型、大小、保存路径)
* 使用方法请见本类底部(uploadfile类使用注释)信息。
*
*/
class uploadfile {

var $user_post_file = array(); //用户上传的文件
var $save_file_path;    //存放用户上传文件的路径
var $max_file_size;     //文件最大尺寸
var $last_error;     //记录最后一次出错信息
//默认允许用户上传的文件类型
var $allow_type = array(‘gif’, ‘jpg’, ‘png’, ‘zip’, ‘rar’, ‘txt’,
‘doc’, ‘pdf’);
var $final_file_path; //最终保存的文件名

var $save_info = array(); //返回一组有用信息,用于提示用户。

/**//**
* 构造函数,用与初始化相关信息,用户待上传文件、存储路径等
*
* @param array $file 用户上传的文件
* @param string $path 存储用户上传文件的路径
* @param integer $size 允许用户上传文件的大小(字节)
* @param array $type   此数组中存放允计用户上传的文件类型
*/
function uploadfile($file, $path, $size = 2097152, $type = ”) {
$this->user_post_file = $file;
$this->save_file_path = $path;
$this->max_file_size = $size;
//如果用户不填写文件大小,则默认为2m.
if ($type != ”)
   $this->allow_type = $type;
}

 

 

/**//**
* 存储用户上传文件,检验合法性通过后,存储至指定位置。
* @access public
* @return int    值为0时上传失败,非0表示上传成功的个数。
*/
function upload() {

for ($i = 0; $i < count($this->user_post_file[‘name’]); $i++)
{
   //如果当前文件上传功能,则执行下一步。
   if ($this->user_post_file[‘error’][$i] == 0) {
    //取当前文件名、临时文件名、大小、扩展名,后面将用到。
    $name = $this->user_post_file[‘name’][$i];
    $tmpname = $this->user_post_file[‘tmp_name’][$i];
    $size = $this->user_post_file[‘size’][$i];
    $mime_type = $this->user_post_file[‘type’][$i];
    $type =
$this->getfileext($this->user_post_file[‘name’][$i]);
    //检测当前上传文件大小是否合法。
    if (!$this->checksize($size)) {
     $this->last_error = “the file size is too big. file name is:
“.$name;
     $this->halt($this->last_error);
     continue;
    }
    //检测当前上传文件扩展名是否合法。
    if (!$this->checktype($type)) {
     $this->last_error = “unallowable file type: .”.$type.” file
name is: “.$name;
     $this->halt($this->last_error);
     continue;
    }
    //检测当前上传文件是否非法提交。
    if(!is_uploaded_file($tmpname)) {
     $this->last_error = “invalid post file method. file name is:
“.$name;
     $this->halt($this->last_error);
     continue;
    }
    //移动文件后,重命名文件用。
    $basename = $this->getbasename($name, “.”.$type);
    //移动后的文件名
    $saveas = $basename.”-“.time().”.”.$type;
    //组合新文件名再存到指定目录下,格式:存储路径 + 文件名 + 时间 +
扩展名
    $this->final_file_path =
$this->save_file_path.”/”.$saveas;
    if(!move_uploaded_file($tmpname, $this->final_file_path)) {
     $this->last_error =
$this->user_post_file[‘error’][$i];
     $this->halt($this->last_error);
     continue;
    }
    //存储当前文件的有关信息,以便其它程序调用。
    $this->save_info[] = array(“name” => $name, “type” =>
$type,
           “mime_type” => $mime_type,
                             “size” => $size, “saveas” =>
$saveas,
                             “path” =>
$this->final_file_path);
   }
}
return count($this->save_info); //返回上传成功的文件数目
}

/**//**
* 返回一些有用的信息,以便用于其它地方。
* @access public
* @return array 返回最终保存的路径
*/
function getsaveinfo() {
return $this->save_info;
}

/**//**
* 检测用户提交文件大小是否合法
* @param integer $size 用户上传文件的大小
* @access private
* @return boolean 如果为true说明大小合法,反之不合法
*/
function checksize($size) {
if ($size > $this->max_file_size) {
   return false;
}
else {
   return true;
}
}

/**//**
* 检测用户提交文件类型是否合法
* @access private
* @return boolean 如果为true说明类型合法,反之不合法
*/
function checktype($extension) {
foreach ($this->allow_type as $type) {
   if (strcasecmp($extension , $type) == 0)
    return true;
}
return false;
}

/**//**
* 显示出错信息
* @param $msg    要显示的出错信息    
* @access private
*/
function halt($msg) {
printf(“<b><uploadfile error:></b> %s <br>n”,
$msg);
}

/**//**
* 取文件扩展名
* @param string $filename 给定要取扩展名的文件
* @access private
* @return string      返回给定文件扩展名
*/
function getfileext($filename) {
$stuff = pathinfo($filename);
return $stuff[‘extension’];
}
/**//**
* 取给定文件文件名,不包括扩展名。
* eg: getbasename(“j:/hexuzhong.jpg”); //返回 hexuzhong
*
* @param string $filename 给定要取文件名的文件
* @access private
* @return string 返回文件名
*/
function getbasename($filename, $type) {
$basename = basename($filename, $type);
return $basename;
}
}
/**//******************** uploadfile类使用注释

*/
?>

一个简单实例

<form enctype=”multipart/form-data” action=”up.php”
method=”post”>
send this file: <input name=”userfile[]” type=”file”
/><br>
send this file: <input name=”userfile[]” type=”file”
/><br>
send this file: <input name=”userfile[]” type=”file”
/><br>
<input type=”submit” value=”send file” />
</form>

<?php
// in php versions earlier than 4.1.0, $http_post_files should be used
instead
// of $_files.

$uploaddir = ‘./’;
/*
print “<pre>”;

if (move_uploaded_file($_files[‘userfile’][‘tmp_name’],
$uploadfile)) {
print “file is valid, and was successfully uploaded. “;
print “here’s some more debugging info:n”;
print_r($_files);
} else {
print “possible file upload attack! here’s some debugging info:n”;
print_r($_files);
}

print “</pre>”;
*/
?>

<?php

function rearrayfiles(&$file_post) {

$file_ary = array();
$file_count = count($file_post[‘name’]);
$file_keys = array_keys($file_post);

for ($i=0; $i<$file_count; $i++) {
foreach ($file_keys as $key) {
$file_ary[$i][$key] = $file_post[$key][$i];
}
}

return $file_ary;
}

print “<pre>”;

if ($_files[‘userfile’]) {
$file_ary = rearrayfiles($_files[‘userfile’]);

发表评论

电子邮件地址不会被公开。 必填项已用*标注