博客列表 >PHP大牛成长之路:单文件与多文件上传

PHP大牛成长之路:单文件与多文件上传

周Sir-BLOG
周Sir-BLOG原创
2020年08月02日 21:35:37644浏览

1、文件上传基本信息

朱老师整理资料,便于记忆

1.1、 php 关于文件上传的配置

文件上传项目项在php.ini中设置,常用的配置项有:

序号 配置项 默认值 描述
1 file_uploads On 使 PHP 支持文件上传
2 upload_tmp_dir /tmp 指示应该临时把上传的文件存储在什么位置
3 max_file_uploads 20 单次请求时允许上传的最大文件数量
4 max_execution_time 30 设置 PHP 最长执行时间(秒)
5 max_input_time 60 设置 PHP 通过 POST/GET/PUT 接收数据的时长(秒)
6 memory_limit 128M 系统分配给当前脚本执行可用的最大内存容量
7 post_max_size 8M 允许的 POST 数据的总大小(以字节为单位)
8 upload_max_filesize 32M 允许的尽可能最大的文件上传(以字节为单位)

1.2、 $_FILE

  • 上传文件的描述信息,全部保存在系统全局变量$_FILES
  • $_FILES以二维数组形式保存: $_FILES['form_file_name']['key']
  • 'form_file_name': 对应着表单中<input type="file" name="my_pic">name属性值
  • 'key': 共有 5 个键名, 描述如下:
序号 键名 描述
1 name 文件在客户端的原始文件名(即存在用户电脑上的文件名)
2 type 文件的 MIME 类型, 由浏览器提供, PHP 并不检查它
3 tmp_name 文件被上传到服务器上之后,在临时目录中临时文件名
4 error 和该文件上传相关的错误代码
5 size 已上传文件的大小(单位为字节)
  • 文件上传错误信息描述
序号 常量 描述
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 文件写入失败

2、单文件上传实战

  1. // $_FILES: 文件上传变量,超全局的变量数组, 保存着所有与文件上传的相关信息
  2. printf('<pre>%s</pre>', print_r($_FILES, true));
  3. // 1、获取Post上传参数
  4. // 原始文件名
  5. $fileName=$_FILES['my_pic']['name'] ?? null;
  6. // 临时文件名
  7. $tmpFileName=$_FILES['my_pic']['tmp_name'] ?? null;
  8. // 获取文件类型(取后缀名前面字符:image/png -> image)
  9. $fileType = strstr(($_FILES['my_pic']['type'] ?? null),'/',true);
  10. // 获取上传错误的代码
  11. $errorCode = $_FILES['my_pic']['error'] ?? null;
  12. // 目标文件名
  13. $saveFileName = 'uploads/' . md5(time(). mt_rand(1,1000)) .strstr($fileName, '.');
  14. // 查看php.ini中的关于上传文件大小的配置项
  15. // echo ini_get('upload_max_filesize');
  16. // 2、对上传文件进行判断
  17. // 首先临时文件名是存在,并且必须是通过POST上传的
  18. if (!$tmpFileName && is_uploaded_file($tmpFileName)) $errorCode=100;
  19. // 判断文件类型是否为'image'
  20. if ($fileType !== 'image') $errorCode=110;
  21. // 自定义文件上传的异常处理类
  22. class UpExt extends Exception
  23. {
  24. public function __toString()
  25. {
  26. return <<< UPLOAD
  27. <table>
  28. <tr>
  29. <td>编号</td>
  30. <td>信息</td>
  31. <td>文件</td>
  32. <td>行号</td>
  33. </tr>
  34. <tr>
  35. <td>$this->code</td>
  36. <td>$this->message</td>
  37. <td>$this->file</td>
  38. <td>$this->line</td>
  39. </tr>
  40. </table>
  41. <style>
  42. table {border-collapse: collapse;border:1px solid black;text-align: center;}
  43. td {border:1px solid black;padding: 5px;}
  44. tr:first-of-type {background-color:#eee;}
  45. tr:last-of-type td {color: red;}
  46. </style>
  47. UPLOAD;
  48. }
  49. }
  50. try {
  51. // 使用系统常量判断错误代码
  52. if ($_FILES && $errorCode > UPLOAD_ERR_OK) {
  53. switch ($errorCode) {
  54. case 100:
  55. throw new UpExt('上传参数不正确', 100);
  56. break;
  57. case 110:
  58. throw new UpExt('文件类型错误', 110);
  59. break;
  60. case UPLOAD_ERR_INI_SIZE:
  61. throw new UpExt('上传的文件超过了 php.ini 中 upload_max_filesize 选项限制的值', 1);
  62. break;
  63. case UPLOAD_ERR_FORM_SIZE:
  64. throw new UpExt('上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值', 2);
  65. break;
  66. case UPLOAD_ERR_PARTIAL:
  67. throw new UpExt('文件只有部分被上传', 3);
  68. break;
  69. case UPLOAD_ERR_NO_FILE:
  70. throw new UpExt('没有文件被上传', 4);
  71. break;
  72. case UPLOAD_ERR_NO_TMP_DIR:
  73. throw new UpExt('找不到临时文件夹', 5);
  74. break;
  75. case UPLOAD_ERR_CANT_WRITE:
  76. throw new UpExt('文件写入失败', 6);
  77. break;
  78. default:
  79. // 测试时建议关掉default: 避免误报影响
  80. throw new UpExt('未知类型错误', 7);
  81. }
  82. }
  83. if (move_uploaded_file($tmpFileName, $saveFileName)) {
  84. echo '<p>'. $_FILES['my_pic']['name'].': 上传成功</p>';
  85. // 预览图片
  86. echo "<img src='{$saveFileName}' width='200'>";
  87. }
  88. } catch (UpExt $e) {
  89. echo $e;
  90. }
  91. ?>
  92. <!DOCTYPE html>
  93. <html lang="zh-cn">
  94. <head>
  95. <meta charset="UTF-8">
  96. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  97. <title>单文件上传</title>
  98. </head>
  99. <body>
  100. <!-- 上传文件表单的属性设置:
  101. methods="POST"
  102. enctype="multipart/form-data" -->
  103. <form action="" method="POST" enctype="multipart/form-data">
  104. <fieldset>
  105. <legend>单文件上传</legend>
  106. <!-- 前端设置上传文件的大小:字节 -->
  107. <!-- <input type="hidden" name="MAX_FILE_SIZE" value=" 380"> -->
  108. <input type="file" name="my_pic" id="my_pic" >
  109. <button>上传</button>
  110. </fieldset>
  111. </form>
  112. </body>
  113. </html>

3、多文件上传实战

  1. try {
  2. $total =count((array)$_FILES['my_pic']['name']);
  3. for($i=0; $i<$total; $i++) {
  4. // 1、获取Post上传参数
  5. // 原始文件名
  6. $fileName=$_FILES['my_pic']['name'][$i] ?? null;
  7. // 临时文件名
  8. $tmpFileName=$_FILES['my_pic']['tmp_name'][$i] ?? null;
  9. // 获取文件类型(取后缀名前面字符:image/png -> image)
  10. $fileType = strstr(($_FILES['my_pic']['type'][$i] ?? null),'/',true);
  11. // 获取上传错误的代码
  12. $errorCode = $_FILES['my_pic']['error'][$i] ?? null;
  13. // 目标文件名
  14. $saveFileName = 'uploads/' . md5(time(). mt_rand(1,1000)) .strstr($fileName, '.');
  15. // 2、对上传文件进行判断
  16. // 首先临时文件名是存在,并且必须是通过POST上传的
  17. if (!$tmpFileName && is_uploaded_file($tmpFileName)) $errorCode=100;
  18. // 判断文件类型是否为'image'
  19. if ($fileType !== 'image') $errorCode=110;
  20. if ($_FILES && $errorCode > UPLOAD_ERR_OK) {
  21. switch ($errorCode) {
  22. case 100:
  23. throw new UpExt('上传参数不正确', 100);
  24. break;
  25. case 110:
  26. throw new UpExt('文件类型错误', 110);
  27. break;
  28. case UPLOAD_ERR_INI_SIZE:
  29. throw new UpExt('上传的文件超过了 php.ini 中 upload_max_filesize 选项限制的值', 1);
  30. break;
  31. case UPLOAD_ERR_FORM_SIZE:
  32. throw new UpExt('上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值', 2);
  33. break;
  34. case UPLOAD_ERR_PARTIAL:
  35. throw new UpExt('文件只有部分被上传', 3);
  36. break;
  37. case UPLOAD_ERR_NO_FILE:
  38. throw new UpExt('没有文件被上传', 4);
  39. break;
  40. case UPLOAD_ERR_NO_TMP_DIR:
  41. throw new UpExt('找不到临时文件夹', 5);
  42. break;
  43. case UPLOAD_ERR_CANT_WRITE:
  44. throw new UpExt('文件写入失败', 6);
  45. break;
  46. default:
  47. // 测试时建议关掉default: 避免误报影响
  48. throw new UpExt('未知类型错误', 7);
  49. }
  50. }
  51. if (move_uploaded_file($tmpFileName, $saveFileName)) {
  52. echo '<p>'. $fileName.': 上传成功</p>';
  53. // 预览图片
  54. echo "<img src='{$saveFileName}' width='200'>";
  55. }
  56. }
  57. } catch (UpExt $e) {
  58. echo $e;
  59. }
  60. class UpExt extends Exception
  61. {
  62. public function __toString()
  63. {
  64. return <<< UPLOAD
  65. <table>
  66. <tr>
  67. <td>编号</td>
  68. <td>信息</td>
  69. <td>文件</td>
  70. <td>行号</td>
  71. </tr>
  72. <tr>
  73. <td>$this->code</td>
  74. <td>$this->message</td>
  75. <td>$this->file</td>
  76. <td>$this->line</td>
  77. </tr>
  78. </table>
  79. <style>
  80. table {border-collapse: collapse;border:1px solid black;text-align: center;}
  81. td {border:1px solid black;padding: 5px;}
  82. tr:first-of-type {background-color:#eee;}
  83. tr:last-of-type td {color: red;}
  84. </style>
  85. UPLOAD;
  86. }
  87. }
  88. ?>
  89. <!DOCTYPE html>
  90. <html lang="zh-cn">
  91. <head>
  92. <meta charset="UTF-8">
  93. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  94. <title>多文件上传</title>
  95. </head>
  96. <body>
  97. <!-- 上传文件表单的属性设置:
  98. methods="POST"
  99. enctype="multipart/form-data" -->
  100. <form action="" method="POST" enctype="multipart/form-data">
  101. <fieldset>
  102. <legend>多文件上传</legend>
  103. <!-- 前端设置上传文件的大小:字节 -->
  104. <!-- <input type="hidden" name="MAX_FILE_SIZE" value=" 380"> -->
  105. <input type="file" name="my_pic[]" id="my_pic" multiple>
  106. <button>上传</button>
  107. </fieldset>
  108. </form>
  109. </body>
  110. </html>

总结

  • 做个上传研究了半天,多文件上传没有思路,最终通过for循环实现了多维数组文件输出。
  • 上传封装没有研究,眼睛痛,交作业休息了。
声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议
老周2020-08-03 19:05:111楼
@Peter-Zhu 朱老师,课堂上的都听明白了,我说的是 input控件使用multiple属性获取的数组没有思路,三维数组遍历没头绪,后来用for也实现了。