php多文件上传与上传文件原理分析
首先用php的socket函数库建立一个临时的http服务器,在某一端口监听,然后把 ip地址和端口号通知客户端,客户端把上传表单提交(临时服务器),临时服务器接受客户端请求,并读取post数据,分析并获取客户端上传的文件信息,把文件保存在服务器上,然后关闭临时服务器,释放资源,上传完成,有点绕,不过思路还是简单的,代码如下:
<?php class upload { public $up_ext = array (), $up_max =5210, $up_dir ; private $up_name , $up_rename =true, $up_num =0, $up_files = array (), $up_ret = array (); function __construct( $name , $ext = array (), $rename =true) { if (! empty empty ( $name )) { $this ->up_name = $name ; ! empty empty ( $ext ) && $this ->up_ext = $ext ; $this ->up_rename = $rename ; $this ->up_dir = website_dirroot. $globals [ 'cfg_upload_path' ]; $this ->initupload(); } else { exit ( 'upload文件域名称为空,初始化失败!' ); } } private function initupload() { if ( is_array ( $_files [ $this ->up_name])) { $up_arr = count ( $_files [ $this ->up_name]); $up_all = count ( $_files [ $this ->up_name], 1); $up_cnt = ( $up_all - $up_arr ) / $up_arr ; for ( $i = 0; $i < $up_cnt ; $i ++) { if ( $_files [ $this ->up_name][ 'error' ][ $i ] != 4) { $this ->up_files[] = array ( 'tmp_name' => $_files [ $this ->up_name][ 'tmp_name' ][ $i ], 'name' => $_files [ $this ->up_name][ 'name' ][ $i ], 'type' => $_files [ $this ->up_name][ 'type' ][ $i ], 'size' => $_files [ $this ->up_name][ 'size' ][ $i ], 'error' => $_files [ $this ->up_name][ 'error' ][ $i ] ); } } $this ->up_num = count ( $this ->up_files); } else { if (isset( $_files [ $this ->up_name])) { $this ->up_files = array ( 'tmp_name' => $_files [ $this ->up_name][ 'tmp_name' ], 'name' => $_files [ $this ->up_name][ 'name' ], 'type' => $_files [ $this ->up_name][ 'type' ], 'size' => $_files [ $this ->up_name][ 'size' ], 'error' => $_files [ $this ->up_name][ 'error' ] ); $this ->up_num = 1; } else { exit ( '没找找到需要upload的文件!' ); } } $this ->chkupload(); } private function chkupload() { if ( empty empty ( $this ->up_ext)) { $up_mime = array ( 'image/wbmp' , 'image/bmp' , 'image/gif' , 'image/pjpeg' , 'image/x-png' ); foreach ( $this ->up_files as $up_file ) { $up_allw = false; foreach ( $up_mime as $mime ) { if ( $up_file [ 'type' ] == $mime ) { $up_allw = true; break ; } } ! $up_allw && exit ( '不允许上传' . $up_file [ 'type' ]. '格式的文件!' ); if ( $up_file [ 'size' ] / 1024 > $this ->up_max) { exit ( '不允许上传大于 ' . $this ->up_max. 'k 的文件!' ); } } } else { foreach ( $this ->up_files as $up_file ) { $up_ext = end ( explode ( '.' , $up_file [ 'name' ])); $up_allw = false; foreach ( $this ->up_ext as $ext ) { if ( $up_ext == $ext ) { $up_allw = true; break ; } } ! $up_allw && exit ( '不允许上传.' . $up_ext . '格式的文件!' ); if ( $up_file [ 'size' ] / 1024 > $this ->up_max) { exit ( '不允许上传大于 ' . $this ->up_max. 'k 的文件!' ); } } } $this ->uploading(); } private function uploading() { if (io::dircreate( $this ->up_dir)) { if ( chmod ( $this ->up_dir, 0777)) { if (! empty empty ( $this ->up_files)) { foreach ( $this ->up_files as $up_file ) { if ( is_uploaded_file ( $up_file [ 'tmp_name' ])) { $file_name = $up_file [ 'name' ]; if ( $this ->up_rename) { $file_ext = end ( explode ( '.' , $file_name )); $file_rnd = substr (md5(uniqid()), mt_rand(0, 26), 6); $file_name = date ( 'ymdhis' ). '_' . $file_rnd . '.' . $file_ext ; } $file_name = $this ->up_dir. '/' . $file_name ; if (move_uploaded_file( $up_file [ 'tmp_name' ], $file_name )) { $this ->up_ret[] = str_replace (website_dirroot, '' , $file_name ); } else { exit ( '文件上传失败!' ); } } } } } else { exit ( '未开启写入权限!' ); } } else { exit ( '上传目录创建失败!' ); } } public function getupload() { return empty empty ( $this ->up_ret) ? false : $this ->up_ret; } function __destruct() {} } ?>那么上传的流程就是如下了:
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秒.
查看更多关于php多文件上传与上传文件原理分析 - php上传下载的详细内容...
声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://www.haodehen.cn/did29336