第一篇博文 !,就发一个文件上传类吧,这个类是基于兄弟连高老师上课将的那个文件上传类,之不过我觉得视频中在上传方法调用校验函数那一块,程序的结构不好理解(也许是我笨一点!),我稍作了一些修改,变得更清晰点,现在就把代码,贴给大家,希望大家多多指正,有不理解的地方可以留言给我。
根据寻求单独写。<?php
class FileUpload{
/*
用法:
$up = new FileUpload(array('path'=>'[必填]'));
if($up->Upload()){
$up->getNewFileName(); 插入数据库
}else{
$up->getErrorMsg(); 返回给用户
我觉得这里可以直接返回错误号, 错误信息用这个类外根据寻求单独写。
}
*/
private $filepath;//上传路径
private $allowtype = array('jpg','png','gif');//允许文件类型
private $maxsize = 1000000;//最大上传尺寸 private $israndname = true; //是否随机新文件名
private $originName; //从$_FILE数组中得到
private $tmpFileName;//从$_FILE数组中得到
private $fileSize;//从$_FILE数组中得到
private $errorNum;//从$_FILE数组中得到
private $fileType;//用文件名后缀
private $newFileName;//新文件名称 (可能就是老名字)
private $errorMsg='';//错误消息
/*@param string $filepath 上传文件的路径。
@param string $allowsize 允许的上传文件类型
@param string $maxsize 最大上传尺寸
@param string $israndname 是否随机新文件名
*/
function __construct($option = array()){//数组传参
foreach($option as $key=>$value){
$key = strtolower($key);
//初始化数组的键值得属于这个类的成员属性名。
if(array_key_exists($key,get_class_vars(get_class($this))))
$this->setOption($key,$value);
}
}
//赋值函数,将数组中的键与值和对象中的成员属性名和成员属性值映射。
private function setOption($key,$value){
return $this->$key = $value;
}
//上传文件
public function uploadFile( $fileField){
$result = true;
if(!$this->checkFilePath()){
$this->errorMsg = $this->getError();
return false;
}
$name = $_FILES[$fileField]["name"];
$tmp_name = $_FILES[$fileField]["tmp_name"];
$size = $_FILES[$fileField]["size"];
$error = $_FILES[$fileField]["error"];
//=======多文件上传======
if(is_array($name)){
/* 说明:这里批量上传文件,除了最后一步移动文件'move_uploaded_file()'出错,
其他的步骤一旦有一个文件出错,则都不上传。
*/
$errorMsgs = array();
//*****这个循环是校验*****
for($i=0; $i<count($name); $i++){
//看上传数据时 $_FILES[]["error"] 是否有错。
if($this->setFile($name[$i],$tmp_name[$i],$size[$i],$error[$i])){
//校验文件类型是否满足条件
if( !$this->checkFileType() ){
$errorMsgs[] = $this->getError();
}
//校验文件的大小是否大于初始化值。
if( !$this->checkFileSize() ){
$errorMsgs[] = $this->getError();
}
}else{
$errorMsgs[] = $this->getError();
}
if(!$result)
$this->setFile();
}
//*****记录了所有校验错误*****
if(!empty($errorMsgs)){
$result = false;
}
//*****没错就循环是上传*****
if( $result ){
$newNames=array();
for( $i=0; $i<count($name);$i++ ){
$this->setFile($name[$i],$tmp_name[$i],$size[$i],$error[$i]);
$this->setNewFileName();
if(!$this->copyFile()){
$errorMsgs[] = $this->getError();
}else{
$newNames[] = $this->newFileName;
}
}
// PHP的上传函数出错,这个几率应该非常小吧
if(!empty($errorMsgs)){
$result = false;
}
}
//*******将输出值换成数组******
if( !$result ){
$this->errorMsg = $errorMsgs;
}else{
$this->newFileName = $newNames;
}
}else{
//=======单文件上传=====
if($this->setFile($name, $tmp_name, $size, $error)){
if( !$this->checkFileType() ){
$this->errorMsg = $this->getError();
$result = false;
}
if( !$this->checkFileSize() ){
$this->errorMsg .= $this->getError();
$result = false;
}
if( $result ){
$this->setNewFileName();
if( !$this->copyFile() ){//
$this->errorMsg = $this->getError();
$result = false;
}
}
}else{
$this->errorMsg = $this->getError();
$result = false;
}
}
return $result;
}
//和FILE相关的成员属性赋值
private function setFile($name, $tmp_name, $size, $error){
$this->setOption('errorNum',$error);
if($this->errorNum == 0){
$this->setOption("originName", $name);
$this->setOption("tmpFileName",$tmp_name);
$this->setOption("fileSize",$size);
$this->setOption("fileType",strtolower(array_pop(explode(".",$name))));
return true;
}
return false;
}
//检查上传路径
private function checkFilePath(){
if($this->filepath == ''){
$this->setOption("errorNum",-5);
return false;
}
if(!file_exists($this->filepath) || !is_writable($this->filepath)){
if(!@mkdir($this->filepath,755)){
$this->setOption("errorNum",-4);
return false;
}
}
return true;
}
//检查文件类型
private function checkFileType(){
if( !in_array($this->fileType, $this->allowtype) ){
$this->setOption("errorNum",-1);
return false;
}
return true;
}
//检查文件大小
private function checkFileSize(){
if( $this->fileSize > $this->maxsize ){
$this->setOption("errorNum",-2);
return false;
}
return true;
}
//设置新文件名
private function setNewFileName(){
if($this->israndname){
$this->setOption('newFileName',$this->proRandName());
}else{
$this->setOption('newFileName', $this->originName);
}
}
//确定是否需要随机文件名
private function proRandName(){
return date("YmdHis",time()).rand(100,999).'.'.$this->fileType;
}
//移动上传文件
private function copyFile(){
if($this->errorNum){
return false;
}
$path = rtrim($this->filepath,'/').'/'.$this->newFileName;
if(@move_uploaded_file($this->tmpFileName,$path))
return true;
$this->setOption('errorNum',-3);
return false;
}
//得到错误消息
private function getError(){
$str = "文件<font color='red'>{$this->originName}</font>上传出错: ";
switch($this->errorNum){
case 4: $sub = '没有文件被上传'; break;
case 3: $sub = '上传文件不完整'; break;
case 2: $sub = '上传文件大小超过了HTML表单中的MAX_FILE_SIZE选项指定的值'; break;
case 1: $sub = '上传文件大小超过了php.ini中 upload_Max_filesize选项的值'; break;
case -1: $sub = '未允许类型'; break;
case -2: $sub = '文件过大,上传文件不能超过'.$this->maxsize.'个字节'; break;
case -3: $sub = '上传失败'; break;
case -4: $sub = '建立存放上传目录失败请重新指定上传目录'; break;
case -5: $sub = '必须指定上传文件路径'; break;
default: $sub = '未知上传错误';
}
$str .= '<b>'.$sub.'</b><br/>';
return $str;
}
//如果上传成功返回上传文件的新文件名
public function getNewFileName(){
return $this->newFileName;
}
//如果上传失败返回错误消息
public function getErrorMsg(){
//return $this->errorNum;
return $this->errorMsg;
}
}