博客列表 >PHP 文件上传

PHP 文件上传

Yang_Sir
Yang_Sir原创
2020年05月13日 15:36:20868浏览
  • 上传的文件保存在临时文件夹中,如没有另外保存,脚本结束后就没了
  • 大文件上传,如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.演示截图

上传文件:

打印结果:

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议