首页 > 语言 > PHP > 正文

PHP一步步实现文件上传及上传文件类

2024-09-04 11:45:13
字体:
来源:转载
供稿:网友

一,比较简单的实现文件上传

文件上传原理:文件上传原理:将客户端的文件先上传到服务器端,然后再将服务器端的临时文件移动到指定的目录。

客户端配置:要上传文件,我们需要采用表单,并且表单发送的形式来POST请求,而且要求将enctype设置为multipart/form-data,总结上传的条件如下:

浏览器表单页面:表单发送方式为post,指定enctype=multipart/form-data,客户端的代码:

  1. <form action="uploadFile.php" method="post" accept-charset="utf-8" enctype="multipart/form-data"
  2.     请选择要上传的文件: 
  3.     <input type="file" name="myfile"
  4.     <input type="submit" value="上传文件"
  5. </form> 

$_FILES文件变量,下面是上传一个图片然后打印整理出来的数据:

  1. // name => 'QC8054R7QPGQ_1000x500.jpg' 
  2. // type => 'image/jpeg' 
  3. // tmp_name => '/Applications/MAMP/tmp/php/php1X5KZU' 
  4. // error => 0 
  5. // size => 229936 

$_FILES上传的参数含义说明:

name:上传的文件的名称

type: 上传的文件的MIME类型

tmp_name:文件上传到服务器的临时路径

site:上传的文件的大小

error:上传的文件的错误码,0表示上传成功UPLOAD_ERR_OK

移动文件

移动文件方式一:上传文件到服务器端是在一个临时路径下,我们需要将文件移动到指定的目录下,我们可以通过下面的函数来实现移动:将指定的文件移到的目录路径下,要求待移动的文件是通过HTTP POST上传的.

bool move_uploaded_file ( string $filename , string $destination )

我们需要判断一下是否是通过HTTP POST上传的,下面的方法可以判断:判断文件是否是通过HTTP POST上传的,如果是返回TRUE,否则返回FALSE

bool is_uploaded_file ( string $filename )

移动文件方式二:

我们还可以通过下面的函数来实现移动文件:

参数一:待移动的文件

参数二:移动到的目标路径

bool copy ( string $source , string $dest [, resource $context ] )

处理上传:

  1. define('UPLOAD_PATH''Uploads'); 
  2.  
  3. $name = $_FILES['myfile']['name']; 
  4. $type = $_FILES['myfile']['type']; 
  5. $tmp_name = $_FILES['myfile']['tmp_name']; 
  6. $error = $_FILES['myfile']['error']; 
  7. $size = $_FILES['myfile']['size']; 
  8.  
  9. if ($error == UPLOAD_ERR_OK) { 
  10.     if (is_uploaded_file($tmp_name)) { 
  11.         move_uploaded_file($tmp_name, UPLOAD_PATH . '/' . $name); 
  12.     } else { 
  13.         if (is_file($tmp_name) && !copy($tmp_name, UPLOAD_PATH . '/' . $name)) { 
  14.             var_dump('ok'); 
  15.         } //Vevb.com 
  16.     } 
  17. else { 
  18.     // 上传到服务器就已经出错了 
  19.     var_dump($error); 

php.ini上传配置:

假设我们要支持上传20M的文件,那么我们可以设置以下选项:

一定要设置为On,才能上传文件,若设置为Off,则服务器是接收不到文件数据的

file_uploads = On

指定上传文件到服务器的临时目录,默认为不打开的,可以不写

upload_tmp_dir = "d:/uploads_tmp"

支持上传的文件的最大为20M

upload_max_filesize = 20M

设置POST请求允许一次请求的最大值为100M

post_max_size = 100M

上传操作允许的最长时间,超过600秒则会停止脚本运行,0表示无限制

max_execution_time = 600

PHP脚本解析请求数据所用的最大时间,默认为60秒,0表示无限制

max_input_time = 600

单个PHP脚本所能申请的最大内存,-1表示无限制!

memory_limit = 128M

上传文件错误码:

UPLOAD_ERR_OK:代表上传成功

UPLOAD_ERR_EXTENSION:上传的文件被PHP扩展程序中断

UPLOAD_ERR_PARTIAL:文件只有部分被上传

UPLOAD_ERR_CANT_WRITE:文件写入失败

UPLOAD_ERR_FORM_SIZE:表单文件超过了post_max_size

UPLOAD_ERR_INI_SIZE:文件大小超过了限制上传的大小

UPLOAD_ERR_NO_FILE:没有文件被上传

UPLOAD_ERR_NO_TMP_DIR:找不到临时目录

客户端限制上传:

我们可以通过隐藏域来实现限制上传的文件大小,同时可以通过accept来限制上传的文件的类型,如下所示:

  1. <form action="uploadFile.php" method="post" accept-charset="utf-8" enctype="multipart/form-data"
  2.     <input type="hidden" name="MAX_FILE_SIZE" value="1024"
  3.     请选择要上传的文件: 
  4.     <input type="file" name="myfile" accept="image/png"
  5.     <input type="submit" value="上传文件"
  6. </form> 

服务端限制上传:

我们可以通过在服务端来判断文件类型、文件大小,上传方式等来判断是否满足条件,然后才处理文件!

  1. define('UPLOAD_PATH''Uploads'); 
  2. define('MAX_FILE_SIZE', 2 * 1024 * 1024); 
  3.  
  4. header('Content-type:text/html;Charset=utf-8'); 
  5.  
  6. $name = $_FILES['myfile']['name']; 
  7. $type = $_FILES['myfile']['type']; 
  8. $tmp_name = $_FILES['myfile']['tmp_name']; 
  9. $error = $_FILES['myfile']['error']; 
  10. $size = $_FILES['myfile']['size']; 
  11.  
  12. $allowExt = array('png''jpg''jpeg'); 
  13.  
  14. if ($error == UPLOAD_ERR_OK) { 
  15.     if ($size > MAX_FILE_SIZE) { 
  16.         exit('上传的文件过大'); 
  17.     } 
  18.  
  19.     // 取上传的文件的扩展类型 
  20.     $ext = pathinfo($name, PATHINFO_EXTENSION); 
  21.     if (!in_array($ext$allowExt)) { 
  22.         exit('非法文件类型'); 
  23.     } 
  24.  
  25.     if (!is_uploaded_file($tmp_name)) { 
  26.         exit('文件不是HTTP POST上传过来的'); 
  27.     } 
  28.  
  29.     if (move_uploaded_file($tmp_name, UPLOAD_PATH . '/' . $name)) { 
  30.         echo '文件上传成功'
  31.     } else { 
  32.         echo "文件上传失败"
  33.     } 
  34. else { 
  35.     // 上传到服务器就已经出错了 
  36.     var_dump($error); 

忽略文件重名之类的问题,那些需要额外添加一些小处理哦!

二,上传文件类

  1. ini_set('display_errors''On'); 
  2. error_reporting(E_ALL); 
  3. header('Content-type:text/html;Charset=utf-8'); 
  4.  
  5. /** 
  6. * Class for Uploading a single image   
  7. */ 
  8. class Upload { 
  9.     protected $fileName/* eg, $_FILES['file'], the name is file. */ 
  10.     protected $allowExt/* Allow extension for uploading a file */ 
  11.     protected $allowMIMEType;      /* Allow uploading file mine types */ 
  12.     protected $fileMaxSize/* Limit a uploading file size */ 
  13.     protected $uploadPath;  /* The destination path */ 
  14.     protected $isImageFlag;     /* Note that file is an image or not. */ 
  15.     protected $errorMessage;     
  16.     protected $fileExt
  17.     protected $fileInfos
  18.     protected $fileUniqueName
  19.     protected $fileDestPath
  20.  
  21.     public function __construct($fileName = 'file'$uploadPath = './Uploads'$isImageFlag = true, $fileMaxSize = 1048576, $allowExt = array('png''jpg''jpeg''gif'), $allowMIMEType = array('image/png''image/jpeg''image/gif')) { 
  22.         $this->fileName = $fileName
  23.         $this->allowExt = $allowExt
  24.         $this->allowMIMEType = $allowMIMEType
  25.         $this->uploadPath = $uploadPath
  26.         $this->isImageFlag = $isImageFlag
  27.         $this->fileMaxSize = $fileMaxSize
  28.         // print_r($_FILES); 
  29.         $this->fileInfos = $_FILES[$fileName]; 
  30.     } 
  31.  
  32.     public function uploadFile() { 
  33.         if ($this->isValidExt()  
  34.             && $this->isValidMIMEType()  
  35.             && $this->isValidFileSize()  
  36.             && $this->isRealImage() 
  37.             && $this->isHTTPPOST() 
  38.             && !$this->hasError()) { 
  39.             $this->isUploadPathExist(); 
  40.             $this->fileUniqueName = $this->getUniqueName(); 
  41.             $this->fileDestPath = $this->uploadPath . '/' . $this->fileUniqueName . '.' . $this->fileExt; 
  42. // echo iconv('gb2312', 'UTF-8', $this->fileDestPath); 
  43.             if (@move_uploaded_file($this->fileInfos['tmp_name'], $this->fileDestPath)) { 
  44.                 return $this->fileDestPath; 
  45.             } else { 
  46.                 $this->errorMessage = '文件上传失败'
  47.             } 
  48.         } else { 
  49.             $this->errorMessage = '文件上传失败'
  50.         } 
  51.  
  52.         exit('<span style="color:red">'.$this->errorMessage.'</span>');  
  53.     } 
  54.  
  55.     protected function hasError() { 
  56.         $ret = true; 
  57.  
  58.         if (!is_null($this->fileInfos)) { 
  59.             switch ($this->fileInfos['error']) { 
  60.                 case UPLOAD_ERR_INI_SIZE: 
  61.                    $this->errorMessage = '文件大小超过PHP.ini文件中upload_max_filesize'
  62.                    break
  63.                 case UPLOAD_ERR_FORM_SIZE: 
  64.                     $this->errorMessage = '文件大小超过了表单中MAX_FILE_SIZE设置的值'
  65.                     break
  66.                 case UPLOAD_ERR_NO_TMP_DIR: 
  67.                     $this->errorMessage = '找不到临时文件目录'
  68.                     break
  69.                 case UPLOAD_ERR_NO_FILE: 
  70.                     $this->errorMessage = '没有选择任何文件上传'
  71.                     break
  72.                 case UPLOAD_ERR_CANT_WRITE: 
  73.                     $this->errorMessage = '文件不可写'
  74.                     break
  75.                 case UPLOAD_ERR_PARTIAL: 
  76.                     $this->errorMessage = '只有部分文件被上传'
  77.                     break
  78.                 case UPLOAD_ERR_EXTENSION: 
  79.                     $this->errorMessage = '文件上传过程中被PHP扩展程序中断'
  80.                     break
  81.                 default
  82.                     $this->errorMessage = ''
  83.                     $ret = false; 
  84.             } 
  85.         } else { 
  86.             $this->errorMessage = '文件上传出错'
  87.         } 
  88.  
  89.         return $ret
  90.     } 
  91.  
  92.     protected function isValidFileSize() { 
  93.         if ($this->fileInfos['size'] > $this->fileMaxSize) { 
  94.             $this->errorMessage = '文件太大'
  95.             return false; 
  96.         } 
  97.  
  98.         return true; 
  99.     } 
  100.  
  101.     protected function isValidExt() { 
  102.         $ext = pathinfo($this->fileInfos['name'], PATHINFO_EXTENSION); 
  103.         if (!in_array($ext$this->allowExt)) { 
  104.             $this->errorMessage = '不支持的文件类型'
  105.             return false; 
  106.         } 
  107.  
  108.         $this->fileExt = $ext
  109.         return true;; 
  110.     } 
  111.  
  112.     protected function isValidMIMEType() { 
  113.         $type = $this->fileInfos['type']; 
  114.  
  115.         if (!in_array($type$this->allowMIMEType)) { 
  116.             $this->errorMessage = '不支持的文件MIME类型'
  117.             return false; 
  118.         } 
  119.  
  120.         return true; 
  121.     } 
  122.  
  123.     protected function isHTTPPOST() { 
  124.         if (!is_uploaded_file($this->fileInfos['tmp_name'])) { 
  125.             $this->errorMessage = '文件不是通过HTTP POST传上来的'
  126.  
  127.             return false; 
  128.         } 
  129.  
  130.         return true; 
  131.     } 
  132.  
  133.     protected function isRealImage() { 
  134.         if ($this->isImageFlag && !getimagesize($this->fileInfos['tmp_name'])) { 
  135.             $this->errorMessage = '文件不是图片';  
  136.             return false; 
  137.         } 
  138.  
  139.         return true; 
  140.     } 
  141.  
  142.     protected function isUploadPathExist() { 
  143.         if (!file_exists($this->uploadPath)) { 
  144.             mkdir($this->uploadPath, 0777, true); 
  145.         }  
  146.     } 
  147.  
  148.     protected function getUniqueName() { 
  149.         return md5(microtime(true), true); 
  150.     } 
  151.  
  152. $upload = new Upload('myfile'); 
  153. if ($upload->uploadFile()) { 
  154.     echo "文件上传成功"
  155. }

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表