Blogger Information
Blog 32
fans 0
comment 0
visits 27413
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
PHP 文件上传
Yang_Sir
Original
861 people have browsed it
  • 上传的文件保存在临时文件夹中,如没有另外保存,脚本结束后就没了
  • 大文件上传,如50M以上的,除了php.ini还需要配置apache中httpd.conf文件里FcgidMaxRequestLen 的值,不然会出现Internal Server Error

基本概念

1.客户端上传

  • html中用户可以通过form表单上传文件,
  • form表单中input标签的type属性设置为file时,即规定输入内容作为文件处理。
  • 表单的上传方式必须是POST
  • enctype属性规定上传的内容类型,文件使用multipart/form-data类型
  • 文件上传的方式有单文件上传和多文件上传,
  • 多文件上传又分为三种类型:
  • 1.逐一上传,表单中每个input的name属性值不同
  • 2.批量上传,限定文件个数,每个input的name属性值相同为数组类型,每次可选 一个文件
  • 3.批量上传,不限定个数,input的name属性值为数组类型,并添加multiple属 性,可以同时选多个文件

2.服务器处理

  • PHP中以全局变量$_FILES记录上传的文件信息,
  • $_FILES二维键名为客户端form表单中的name属性值,其值是五个固定的文件信息
序号 键名 描述
1 name 文件在客户端的原始文件名(即存在用户电脑上的文件名)
2 type 文件的 MIME 类型, 由浏览器提供, PHP 并不检查它
3 tmp_name 文件被上传到服务器上之后,在临时目录中临时文件名
4 error 和该文件上传相关的错误代码
5 size 已上传文件的大小(单位为字节)

error错误信息描述:

序号 常量 描述
1 UPLOAD_ERR_OK 0 没有错误发生,文件上传成功
2 UPLOAD_ERR_INI_SIZE 1 文件超过php.iniupload_max_filesize
3 UPLOAD_ERR_FORM_SIZE 2 文件大小超过表单中MAX_FILE_SIZE指定的值
4 UPLOAD_ERR_PARTIAL 3 文件只有部分被上传
5 UPLOAD_ERR_NO_FILE 4 没有文件被上传
6 UPLOAD_ERR_NO_TMP_DIR 6 找不到临时文件夹
7 UPLOAD_ERR_CANT_WRITE 7 文件写入失败
  • 服务器接收文件后保存在临时文件中,通过move_uploaded_file()方法保存到指定位置

示例演示

1.创建上传页面

  • 创建4种不同上传方式的form表单
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6. <title>文件上传</title>
  7. </head>
  8. <style>
  9. fieldset {
  10. height: 100px;
  11. padding: 20px 20px;
  12. }
  13. </style>
  14. <body>
  15. <form action="upload2.php" method="POST" enctype="multipart/form-data">
  16. <fieldset>
  17. <legend>单文件上传</legend>
  18. <input type="hidden" name="MAX_FILE_SIZE" value="500000" />
  19. <input type="file" name="my_pic" />
  20. <button>上传</button>
  21. </fieldset>
  22. </form>
  23. <br />
  24. <form action="upload2.php" method="POST" enctype="multipart/form-data">
  25. <fieldset>
  26. <legend>多文件上传: 逐个上传</legend>
  27. <input type="hidden" name="MAX_FILE_SIZE" value="300" />
  28. <input type="file" name="my_pic1" />
  29. <input type="file" name="my_pic2" />
  30. <input type="file" name="my_pic3" />
  31. <button>上传</button>
  32. </fieldset>
  33. </form>
  34. <br />
  35. <form action="upload2.php" method="POST" enctype="multipart/form-data">
  36. <fieldset>
  37. <legend>多文件上传: 批量上传(限文件数)</legend>
  38. <input type="hidden" name="MAX_FILE_SIZE" value="3000000" />
  39. <!-- 将name属性值能数组的形式提供 -->
  40. <input type="file" name="my_pic[]" />
  41. <input type="file" name="my_pic[]" />
  42. <input type="file" name="my_pic[]" />
  43. <button>上传</button>
  44. </fieldset>
  45. </form>
  46. <br />
  47. <form action="upload.php" method="POST" enctype="multipart/form-data">
  48. <fieldset>
  49. <legend>多文件上传: 批量上传(不限数)</legend>
  50. <input type="hidden" name="MAX_FILE_SIZE" value="3000000" />
  51. <!-- 将name属性值能数组的形式提供 -->
  52. <input type="file" name="my_pic[]" multiple />
  53. <button>上传</button>
  54. </fieldset>
  55. </form>
  56. </body>
  57. </html>

效果图:

" class="reference-link">

" class="reference-link">

2.创建PHP上传文件处理类

  • 通过构造函数把多文件上传的文件信息保存到二维数组中
  • self::$files保存上传成功的文件信息,self::$files_err保存上传失败的文件信息
  • 然后可以通过saveFile()方法保存上传成功的文件到指定位置
  1. <?php
  2. class Upload
  3. {
  4. public static $path='uploads/';//设置文件保存位置
  5. public static $rename=0;//设置是否重命名,0 否,其它值 是
  6. public static $files = array();//保存成功上传的文件
  7. public static $files_err = array();//保存上传失败的文件信息
  8. public static $result = array("success"=>[],"error"=>[]);//记录保存结果
  9. public static $error_code = '';//错误码
  10. public static $specify_type=array();//指定上传文件的格式
  11. const ERR_MESSAGE = ['没有错误发生,文件上传成功','文件超过`php.ini`中`upload_max_filesize`值','文件大小超过表单中`MAX_FILE_SIZE`指定的值',
  12. '文件只有部分被上传','没有文件被上传','', '找不到临时文件夹','文件写入失败','文件格式错误'];
  13. /**
  14. * 获取所有上传的文件信息,转为二维数组
  15. * $files,$files_err,分开保存上传成功和失败的文件
  16. */
  17. public function __construct()
  18. {
  19. foreach($_FILES as $key=>$val){
  20. //name如果是数组,循环获取数据,转为二维数组
  21. if(is_array($val['name'])){
  22. $count = count($val['name']);
  23. for($i=0;$i<$count;$i++){
  24. //判断是否以POST方式上传了文件
  25. if($val['error'][$i]===0&&is_uploaded_file($val['tmp_name'][$i])){
  26. self::$files[]=array(
  27. 'name'=>$val['name'][$i],
  28. 'type'=>$val['type'][$i],
  29. 'tmp_name'=>$val['tmp_name'][$i],
  30. 'error'=>$val['error'][$i],
  31. 'size'=>$val['size'][$i]
  32. );
  33. }else{
  34. self::$files_err[]=array(
  35. 'name'=>$val['name'][$i],
  36. 'type'=>$val['type'][$i],
  37. 'tmp_name'=>$val['tmp_name'][$i],
  38. 'error'=>$val['error'][$i],
  39. 'size'=>$val['size'][$i]
  40. );
  41. }
  42. }
  43. }else{
  44. //如果不是数组,直接获取数据
  45. if($val['error']===0&&is_uploaded_file($val['tmp_name']))
  46. {
  47. self::$files[]=$val;
  48. }else{
  49. self::$files_err[]=$val;
  50. }
  51. }
  52. }
  53. }
  54. /**
  55. * 保存上传成功的文件,用户选择路径、是否重命名、限定文件类型
  56. * $rename 重命名:0 否 ; 其它 是
  57. */
  58. public function saveFile(string $path='uploads/',int $rename=0,array $specify_type=[]):array
  59. {
  60. self::$path=$path;
  61. self::$rename=$rename;
  62. self::$specify_type=$specify_type;
  63. foreach(self::$files as $val){
  64. $filename = $this->rename($val['name'],$rename);//重命名
  65. if(!empty($specify_type)){
  66. //如果不属于指定的类型,保存错误信息,跳出本次循环
  67. if(!in_array($val['type'],$specify_type)){
  68. self::$result['error'][] = $val['name'].":文件类型不符";
  69. continue;
  70. }
  71. }
  72. if(move_uploaded_file($val['tmp_name'], self::$path.$filename)){
  73. self::$result['success'][] = $val['name'].':'.self::$path.$filename;
  74. }else{
  75. self::$result['error'][] = $val['name'].":保存失败";
  76. }
  77. }
  78. return self::$result;
  79. }
  80. /**
  81. * 按规则生成文件名
  82. * $type : 0 否,其它 是
  83. */
  84. public function rename(string $filename,int $type=0):string{
  85. $suffix = strrchr($filename,'.');//后缀
  86. $finalname = $filename;
  87. //如果文件名存在,又不重新命名,就在原文件名后加(1)
  88. if(file_exists(self::$path.$filename)&&$type===0){
  89. $finalname = basename($filename,strrchr($filename,'.')).'(1)'.$suffix;
  90. }elseif($type!==0){
  91. $finalname = date('Ymd',time()).rand(1000,9999).$suffix;
  92. }
  93. if(file_exists(self::$path.$finalname)){//再次检测名称是否已存在(重新生成)
  94. $finalname = $this->rename($filename,$type);
  95. }
  96. return $finalname;
  97. }
  98. }
  99. $upload = new Upload;
  100. print_r($upload::$files);//上传成功的文件
  101. print_r($upload::$files_err);//上传失败的文件
  102. print_r($upload->saveFile('uploads',1,['text/plain','image/jpeg']));

3.演示截图

上传文件:

打印结果:

Correcting teacher:天蓬老师天蓬老师

Correction status:qualified

Teacher's comments:这应该是有史以来最完整的文件上传方案
Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!