• 简述php文件上传原理


    文件上传的原理

    当我们点击提交表单时,会将file文件域里面的文件,先上传到临时的目录(可以在php的配置文件中设置),默认的临时目录是c:/windows/temp,

    如果需要持久的保存,需要通过php的函数move_uploaded_file()移动到指定的位置,如果不移动,当php脚本执行结束,临时文件就会消失。

    文件上传相关知识

    文件上传,其实也是通过表单提交的。

    form表单:
    action属性应该指向一个php文件
    method属性必须设置为post
    enctype属性:
    取值:

    application/x-www-url-encoded (默认)只能上文本数据
    multipart/form-data 可以上传多 种类型的数据(上传文件)

    表单提交的数据分为如下两种:
    (1)字节流数据:输入框、单选框、复选框、多行文本域等都是通过字节的数据传输到服务器,服务器通过$_GET $_POST接收(enctype=‘application/x-www-url-encoded’)
    (2)二进制文件流的形式;当需要提交一些文件的时候,由于文件采用的二进制的形式进行编码,所以需要先将二进制文件转码,然后再提交到服务器(enctype=‘multipart/form-data’)

    文件提交的时候,需要通过input type=”file” 文件域上传

    服务器接收的时候,通过$_FILES进行接收,并且通过$_FILES服务端可以控制文件上传的格式、大小与做错误处理
    
    • 1

    在前端可以对上传的文件类型,大小进行限制:

    <!--表单隐藏域对上传大小进行限制-->
    <input type="hidden" name="MAX_FILE_SIZE" value="2097152">
    <!--accept 对文件类型限制-->
    <input type="file" name="myfile" accept="image/jpeg,image/png">
    
    • 1
    • 2
    • 3
    • 4

    注意限制是以字节为单位
    在服务器端也要做响应的限制:

    header('Content-type:text/html;charset=utf-8');
    $myfile=$_FILES['myfile'];
    //获取文件数组['myfile']的属性tmp_name与name
    //$tmp=$myfile['tmp_name'];
    //$picname=$myfile['name'];
    //windows采用GBK编码,PHP采用utf-8编码,需要改变文件名的编码格式
    //$picname=iconv('utf-8','GBK',$picname);
    //将零时文件$tmp移动到指定目录userpic并命名为$picname
    //copy($tmp,"userpic/".$picname);
    
    $size=$myfile['size'];//获取文件大小
    $MaxSize=2097152;//设置最大允许字节
    $type=$myfile['type'];//获取图片类型
    $AllowTypr=array('image/jpeg','image/png','image/gif');//允许类型数组
    if ($error==0){//为0,代表上传成功
      if ($size>$MaxSize){
        echo "";
        echo "";
        exit();
      }
      if (!in_array($type,$AllowTypr)){
        echo "";
        echo "";
        exit();
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    错误处理

    $error=$myfile['myfile']['error'];
      if ($error==0){//为0,代表上传成功
        if (move_uploaded_file($tmp,"userpic/".$picname)) {
          echo "移动文件成功";
        }else{
          echo "移动文件失败";
        }
      }else{//不为0,匹配错误信息
        switch ($error){
          case 1:
            echo "超过文件最大上传限制";//PHP.ini中upload_max_filesize
            break;
          case 2:
            echo "超过表单文件大小限制";//HTML表单中MAX_FILE_SIZE选项
            break;
          case 3:
            echo "文件部分被上传";
            break;
          case 4:
            echo "未选择上传文件";
            break;
          case 7://文件写入失败
          case 8:
            echo "系统错误";
            break;
        }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    文件上传配置

    PHP.ini文件中的file uploads部分定义了相关文件上传配置,

    file_uploads=On         开启HTTP上传
    upload_tmp_dir          临时文件保存目录
    upload_max_filesize=2M  最大上传文件大小
    post_max_size=8M        POST方式传输最大数据值
    max_file_uploads        一次上传最大文件数
    memory_limit=128M       单线程最大内存占用量
    max_excution_time=-1    脚本解析所允许的最大执行时间(s),默认为-1未开启
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    copy、rename与move_uploaded_file区别

    copy()复制文件 - 您现在有2个文件,对于大文件,这可能需要很长时间

    rename()更改文件的名称,这可能意味着在目录之间移动它。

    move_uploaded_file()与rename()基本相同,但它仅适用于通过PHP上传机制上传的文件。这是一项安全功能,可防止用户欺骗您的脚本向他们展示与安全相关的数据。

    多文件上传

    前端

    <form action="" method="post" enctype="multipart/form-data">  
        <input type="file" name="file[]"/><hr>  
        <input type="file" name="file[]"/><hr>  
        <input type="submit" name="submit" value="提交" />  
    </form>  
    
    • 1
    • 2
    • 3
    • 4
    • 5

    服务端,多文件、单文件处理逻辑一样

    $array = $_FILES['file']['name'];  
    $length = count($array);  
    for($i=0;$i<$length;$i++){  
        echo "文件名为".$array[$i]."
    "
    ; echo "原先保存位置: " . $_FILES["file"]["tmp_name"][$i]."
    "
    ; move_uploaded_file($_FILES["file"]["tmp_name"][$i],"./upload/" . $array[$i]); echo "提交后保存位置: " . "./upload/里的" . $array[$i]."
    "
    ; }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    获取文件mime类型几种方法

    说明:
    多用途internet邮件扩展,mime类型的出现,跟着电子邮件出现的
    早期,发送电子邮件的时候,里面可能会附带一些附件,计算机系统根据附件的类型找到对应的设备打开,例如:传输的是视频,就会找到视频播放器去打开,如果传输的是网页文件,那么会自动使用浏览器去打开

    MIME类型,包括2个部分:第一个部分是该文件所属的一个大类,第二个部分是文件细节小类,

    例如:
    text/html,属于文本文件,html这样的文本文件
    image/jpg,属于图像大类,jpg这种类型的图像

    1、php上传文件获取MIME类型:$_FILES[‘uploadfile’][‘type’]

    2、mime_content_type或Fileinfo函数

    echo mime_content_type('php.gif') ."\n";//输出image/gif
    echo mime_content_type('test.php'); //输出text/plain
    
    $finfo    = finfo_open(FILEINFO_MIME);
    $mimetype = finfo_file($finfo, $filename);
    finfo_close($finfo);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3、image_type_to_mime_type()获取图片MIME类型
    该函数用来判断一个 IMAGETYPE 常量的 MIME 类型,如果需要判断MIME类型的文件只有图像文件,那么首先可以使用exif_imagetype()函数获取图像类型常量,再用image_type_to_mime_type()函数将图像类型常量转换成图片文件的MIME类型。

    注意:需要在php.ini中配置打开extension=php_mbstring.dll(Windows需要)和extension=php_exif.dll

    $file = 'path/to/image.jpg';
    $image_mime = image_type_to_mime_type(exif_imagetype($file));
    
    • 1
    • 2

    参考链接:
    https://www.cwhello.com/10062.html
    http://www.viiis.cn/news/show_36704.html
    https://www.iteye.com/blog/570109268-2413455
    https://www.thinbug.com/q/3924016
    https://www.youranshare.com/push/manual/php-manual/3927.html

  • 相关阅读:
    mysql批量插入性能优化:executeBatch如何通过rewriteBatchedStatements参数逆袭
    龙芯下如何进行.net core程序开发部署
    CSS_精灵图
    概率DP—二刷
    1.0、什么是软件测试
    Sqli-labs靶场第15关详解[Sqli-labs-less-15]自动化注入-SQLmap工具注入
    【ICCV】PointDC,基于深度聚类的无监督3D场景语义分割,FaceChain团队联合出品
    重学Elasticsearch第3章 : ElasticSearch高级查询、索引库原理、倒排索引、DSL高级检索
    echarts 仪表盘统计图
    J2EE基础:maven(1)
  • 原文地址:https://blog.csdn.net/heshihu2019/article/details/125880930