首页 > 语言 > PHP > 正文

php多文件上传与上传文件原理分析

2024-09-04 11:44:56
字体:大 中 小
来源:转载
供稿:网友

首先用php的socket函数库建立一个临时的http服务器,在某一端口监听,然后把 ip地址和端口号通知客户端,客户端把上传表单提交(临时服务器),临时服务器接受客户端请求,并读取post数据,分析并获取客户端上传的文件信息,把文件保存在服务器上,然后关闭临时服务器,释放资源,上传完成,有点绕,不过思路还是简单的,代码如下:

  1. <?php
  2. class upload {  
  3. public $up_ext=array(), $up_max=5210, $up_dir;  
  4. private $up_name, $up_rename=true, $up_num=0, $up_files=array(), $up_ret=array(); 
  5.  
  6. function __construct($name, $ext=array(), $rename=true) {  
  7. if (!emptyempty($name)) {  
  8. $this->up_name = $name;  
  9. !emptyempty($ext) && $this->up_ext = $ext;  
  10. $this->up_rename = $rename;  
  11. $this->up_dir = website_dirroot.  
  12. $globals['cfg_upload_path'];  
  13. $this->initupload();  
  14. } else {  
  15. exit('upload文件域名称为空,初始化失败!');  
  16. }  
  17. } 
  18.  
  19. private function initupload() {  
  20. if (is_array($_files[$this->up_name])) {  
  21. $up_arr = count($_files[$this->up_name]);  
  22. $up_all = count($_files[$this->up_name], 1);  
  23. $up_cnt = ($up_all - $up_arr) / $up_arr;  
  24. for ($i = 0; $i < $up_cnt; $i ++) {  
  25. if ($_files[$this->up_name]['error'][$i] != 4) {  
  26. $this->up_files[] = array(  
  27. 'tmp_name' => $_files[$this->up_name]['tmp_name'][$i],  
  28. 'name' => $_files[$this->up_name]['name'][$i],  
  29. 'type' => $_files[$this->up_name]['type'][$i],  
  30. 'size' => $_files[$this->up_name]['size'][$i],  
  31. 'error' => $_files[$this->up_name]['error'][$i]  
  32. );  
  33. }  
  34. }  
  35. $this->up_num = count($this->up_files);  
  36. } else {  
  37. if (isset($_files[$this->up_name])) {  
  38. $this->up_files = array(  
  39. 'tmp_name' => $_files[$this->up_name]['tmp_name'],  
  40. 'name' => $_files[$this->up_name]['name'],  
  41. 'type' => $_files[$this->up_name]['type'],  
  42. 'size' => $_files[$this->up_name]['size'],  
  43. 'error' => $_files[$this->up_name]['error']  
  44. );  
  45. $this->up_num = 1;  
  46. } else {  
  47. exit('没找找到需要upload的文件!');  
  48. }  
  49. } 
  50.  
  51. $this->chkupload();  
  52. } 
  53.  
  54. private function chkupload() {  
  55. if (emptyempty($this->up_ext)) {  
  56. $up_mime = array('image/wbmp', 'image/bmp', 'image/gif', 'image/pjpeg', 'image/x-png');  
  57. foreach ($this->up_files as $up_file) {  
  58. $up_allw = false;  
  59. foreach ($up_mime as $mime) {  
  60. if ($up_file['type'] == $mime) {  
  61. $up_allw = true; break;  
  62. }  
  63. }  
  64. !$up_allw && exit('不允许上传'.$up_file['type'].'格式的文件!'); 
  65.  
  66. if ($up_file['size'] / 1024 > $this->up_max) {  
  67. exit('不允许上传大于 '.$this->up_max.'k 的文件!');  
  68. }  
  69. }  
  70. } else {  
  71. foreach ($this->up_files as $up_file) {  
  72. $up_ext = end(explode('.', $up_file['name'])); 
  73.  
  74. $up_allw = false;  
  75. foreach ($this->up_ext as $ext) {  
  76. if ($up_ext == $ext) {  
  77. $up_allw = true; break;  
  78. }  
  79. }  
  80. !$up_allw && exit('不允许上传.'.$up_ext.'格式的文件!'); 
  81.  
  82. if ($up_file['size'] / 1024 > $this->up_max) {  
  83. exit('不允许上传大于 '.$this->up_max.'k 的文件!');  
  84. }  
  85. }  
  86. } 
  87.  
  88. $this->uploading();  
  89. } 
  90.  
  91. private function uploading() {  
  92. if (io::dircreate($this->up_dir)) {  
  93. if (chmod($this->up_dir, 0777)) {  
  94. if (!emptyempty($this->up_files)) {  
  95. foreach ($this->up_files as $up_file) {  
  96. if (is_uploaded_file($up_file['tmp_name'])) {  
  97. $file_name = $up_file['name'];  
  98. if ($this->up_rename) {  
  99. $file_ext = end(explode('.', $file_name));  
  100. $file_rnd = substr(md5(uniqid()), mt_rand(0, 26), 6);  
  101. $file_name = date('ymdhis').'_'.$file_rnd.'.'.$file_ext;  
  102. }  
  103. $file_name = $this->up_dir.'/'.$file_name; 
  104.  
  105. if (move_uploaded_file($up_file['tmp_name'], $file_name)) {  
  106. $this->up_ret[] = str_replace(website_dirroot, '', $file_name);  
  107. } else {  
  108. exit('文件上传失败!');  
  109. }  
  110. }  
  111. }  
  112. }  
  113. } else {  
  114. exit('未开启写入权限!');  
  115. }  
  116. } else {  
  117. exit('上传目录创建失败!');  
  118. }  
  119. } 
  120.  
  121. public function getupload() {  
  122. return emptyempty($this->up_ret) ? false : $this->up_ret;  
  123. } 
  124.  
  125. function __destruct() {}  
  126. }  
  127. ?> 

那么上传的流程就是如下了:

1.给form标签的enctype属性赋值multipart/form-date,这个是必须的,而且也必须指定的,不然文件无法上传.

2.判断

这个判断一般有三个判断,一个是类型判断,一个是大小判断,一个是文件是否存在的判断,因为这三个判断是保证安全以及成功上传的前提.

3.保存上传的文件

因为文件上传的时候都被存放在一个临时的地方,所以要通过方法将其转移到指定的地方,这样调用也会很方便.

说了原理和流程,就是实际操作以及一些重要函数了,首先就是指定文件规定类型,但是不能直接指定,必须指定mime类型,不然php会报错.

上传的文件的信息一般都包含在一个叫$_files的关联数组中,它包含了五方面的信息.

$_files['file']['name'] =>要上传的文件的原名

$_files['file']['type'] =>要上传的文件的类型

$_files['file']['size'] =>文件的大小

$_files['file']['tmp_name'] =>储存的临时文件名,一般是系统默认

$_files['file']['error'] =>上传相关的错误代码

错误代码可以是一串数字,也可以是一些常量,比如0->upload_err_ok->上传成功,你可以在这儿看到详细的对应.

在转移文件之前,最好使用is_uploaded_file()函数来测试临时文件是否是通过http post上传的,也可以检测文件是否存在,一般用文件的临时名作为参数,让后就是使用move_uploaded_file()函数来转移上传的文件,这个函数有两个参数,第一个是指定要转移的文件,第二个是指定要转移的文件,要转移的文件一般是临时文件,所以用临时文件名(tmp_name)来指定,而第二参数一般也作为新的文件名,存进数据库,以后就可以调用了.

这里要说的一个就是大文件上传,在不借助第三方工具的情况下,可以通过设定php.ini的参数来完成,一个是upload_max_filesize,这个是指定上传的最大限制,默认是2m,还有一个就是max_input_time,它指定了表单提交的最长时间限制,因为一般大文件上传比较好时,所以这个也是必须的.

表单还可以有一些其他的控制,比如post_max_size是控制表单能接受的最大值,而memory_list可以指定每个php页面能占有的最大内存,默认是8m,max_input_time可以指定每个php页面接受数据的最长时间,默认是60秒.

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表