Blogger Information
Blog 119
fans 3
comment 1
visits 94367
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
php文件上传原理
赵大叔
Original
913 people have browsed it

一、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>

演示效果:

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

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