好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

php多文件上传与上传文件原理分析 - php上传下载

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上传下载的详细内容...

  阅读:60次