博客列表 >php文件上传原理

php文件上传原理

赵大叔
赵大叔原创
2020年05月13日 18:46:03912浏览

一、PHP配置

序号 配置项 默认值 描述
1 file_uploads On on支持文件上传;off 不支持
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 允许的尽可能最大的文件上传(以字节为单位)

二、上传文件描述信息$_FILES

超全局变量
上传文件的描述信息,全部保存在系统全局变量$_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 文件写入失败

四、演示代码

单文件上传

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>单文件上传</title>
  6. <style>
  7. form {
  8. width: 240px;
  9. }
  10. fieldset {
  11. background-color: #BED3DC;
  12. }
  13. legend {
  14. font-size: 20px;
  15. }
  16. form button {
  17. width: 60px;
  18. margin-top: 15px;
  19. }
  20. </style>
  21. </head>
  22. <body>
  23. <!-- action:处理上传脚本, method: 必须是POST, multipart/form-data:允许接收表单提交的文件 -->
  24. <form action="" method="POST" enctype="multipart/form-data">
  25. <fieldset>
  26. <legend>单文件上传</legend>
  27. <!-- 这个上传文件大小的限制字段,必须写到file字段的前面 -->
  28. <input type="hidden" name="MAX_FILE_SIZE" value="3000000">
  29. <input type="file" name="user_pic">
  30. <button>上传</button>
  31. </fieldset>
  32. </form>
  33. </body>
  34. </html>
  35. <?php
  36. //自定义异常类
  37. use Exception;
  38. class MyException extends Exception
  39. {
  40. // 改写__tostring方法
  41. public function __toString() :string
  42. {
  43. return <<<HEREDOC
  44. <style>
  45. table {width: 238px;border-collapse: collapse;border:1px solid black;text-align: center;margin-top: 20px;}
  46. td {border:1px solid black;padding: 5px;}
  47. tr > td:first-of-type {background-color: yellow;font-size: 20px}
  48. span {color: red}
  49. </style>
  50. <table>
  51. <tr>
  52. <td>异常<span>内容</span></td>
  53. <td>$this->message</td>
  54. </tr>
  55. <tr>
  56. <td>异常<span>代码</span></td>
  57. <td>$this->code</td>
  58. </tr>
  59. <tr>
  60. <td>异常<span>行号</span></td>
  61. <td>$this->line</td>
  62. </tr>
  63. </table>
  64. HEREDOC;
  65. }
  66. }
  67. // 使用自定义异常类检测上传出错的代码
  68. try {
  69. $errorCode = $_FILES['user_pic']['error'];
  70. if ($errorCode > UPLOAD_ERR_OK) {
  71. switch ($errorCode) {
  72. case UPLOAD_ERR_INI_SIZE:
  73. throw new MyException('上传的文件超过了php.ini中upload_max_filesize选项限制的值');
  74. break;
  75. case UPLOAD_ERR_FORM_SIZE:
  76. throw new MyException('上传文件的大小超过了HTML表单中 MAX_FILE_SIZE选项指定的值');
  77. break;
  78. case UPLOAD_ERR_PARTIAL:
  79. throw new MyException('文件只有部分被上传');
  80. break;
  81. case UPLOAD_ERR_NO_FILE:
  82. throw new MyException('没有文件被上传');
  83. break;
  84. case UPLOAD_ERR_NO_TMP_DIR:
  85. throw new MyException('找不到临时文件夹');
  86. break;
  87. case UPLOAD_ERR_CANT_WRITE:
  88. throw new MyException('文件写入失败');
  89. break;
  90. default:
  91. // throw new MyException('未知类型错误');
  92. }
  93. }
  94. // 判断文件类型
  95. $fileType = $_FILES['user_pic']['type'];
  96. // echo (strstr($fileType, '/', true));die;
  97. if (strstr($fileType, '/', true) !== 'image') throw new MyException('文件类型错误');
  98. // 将文件从临时目录 移动到用户自定义的目标目录中
  99. // $tempFileName:临时文件名
  100. $tempFileName = $_FILES['user_pic']['tmp_name'];
  101. if (is_uploaded_file($tempFileName)) {
  102. // 原始文件名
  103. $originalFileName = $_FILES['user_pic']['name'];
  104. // 目标文件名
  105. $destFileName = 'images/'.md5(time().mt_rand(1,1000)).strstr($originalFileName, '.');
  106. // 移动文件到目标目录使用的函数
  107. if (move_uploaded_file($tempFileName, $destFileName)) {
  108. echo "<p>$originalFileName: 上传成功...</p>";
  109. // 预览
  110. echo "<img src='{$destFileName}' width='200'>";
  111. }
  112. }
  113. } catch (MyException $er) {
  114. echo $er;
  115. }
  116. ?>

演示效果:

多文件逐条上传

  1. <form action="" method="POST" enctype="multipart/form-data">
  2. <fieldset>
  3. <legend>多文件逐个上传</legend>
  4. <!-- 这个上传文件大小的限制字段,必须写到file字段的前面 -->
  5. <input type="hidden" name="MAX_FILE_SIZE" value="3000000">
  6. <input type="file" name="user_pic[]">
  7. <input type="file" name="user_pic[]">
  8. <input type="file" name="user_pic[]">
  9. <input type="file" name="user_pic[]">
  10. <button>上传</button>
  11. </fieldset>
  12. </form>
  13. <?php
  14. // 判断文件类型
  15. $fileType = $_FILES['user_pic']['type'];
  16. // echo (strstr($fileType, '/', true));die;
  17. if (strstr($fileType, '/', true) !== 'image') throw new MyException('文件类型错误');
  18. if ($_FILES['user_pic'])
  19. foreach ($_FILES['user_pic']['error'] as $key => $error) {
  20. // 只要判断 error === 0
  21. if ($error === UPLOAD_ERR_OK) {
  22. // 临时文件名
  23. $tmpFileName = $_FILES['user_pic']['tmp_name'][$key];
  24. // 原始文件名
  25. $originalFileName = $_FILES['user_pic']['name'][$key];
  26. // 目标文件名
  27. $destFileName = 'images/'.md5(time().mt_rand(1,1000)).strstr($originalFileName, '.');
  28. // 移动文件
  29. move_uploaded_file($tmpFileName, $destFileName);
  30. echo "<p>$originalFileName: 上传成功...</p>";
  31. // 预览
  32. echo "<img src='{$destFileName}' width='200'>";
  33. }
  34. }
  35. } catch (MyException $er) {
  36. echo $er;
  37. }
  38. ?>

演示效果:

多文件批量上传

<input type="file" name="user_pic[]" multiple>
multiple

  1. <form action="" method="POST" enctype="multipart/form-data">
  2. <fieldset>
  3. <legend>多文件逐个上传</legend>
  4. <!-- 这个上传文件大小的限制字段,必须写到file字段的前面 -->
  5. <input type="hidden" name="MAX_FILE_SIZE" value="3000000">
  6. <input type="file" name="user_pic[]" multiple>
  7. <button>上传</button>
  8. </fieldset>
  9. </form>

演示效果:

总结:面向对象基础还是不牢靠,封装有点思路但是还不清晰,后期再慢慢研究研究。

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