zoukankan      html  css  js  c++  java
  • PHP基础之文件的上传与下载

    文件上传与下载

    文件上传

    • 文件上传表单
      • 表单的提交方式必须为POST
      • enctype="multipart/form-data"
        • 说明浏览器可以提供文件上传功能
        • 该属性提示表单中有二进制文件数据
        • <input type="hidden" name="max_file_size" value="30000">
          • 可以指定允许上传文件的最大尺寸
          • MAX_FILE_SIZE必须在文件域的上面。
    <!-- form.html -->
    <form action="upload.php" enctype="multipart/form-data" method="post">
      <input type="hidden" name="max_file_size" value="30000">
      选择文件:<input type="file" name="userfile">
      <input type="submit" value="上传文件">
    </form>
    
    • 文件域 表单的enctype属性

      • 默认情况下,表单传递是字符流,不能传递二进制流
      • 通过设置表单的enctype属性传递复合数据
      • enctype属性的值有
        • application/x-www-form-urlencoded (默认)表示传递的是带格式的文本数据
        • multipart/form-data 复合的表单数据(字符串文件),文件上传必须设置此值
        • text/plain 用于向服务器传递无格式的文本数据,主要用户电子邮件
    • PHP处理上传文件

      • PHP会自动生成一个$_FILES二维数组,该数组保存了上传文件的信息
    # upload.php
    <?php
        $name= $_FILES['userfile']['name'];
        $type= $_FILES['userfile']['type'];
        $size= $_FILES['userfile']['size'];
        $tmpName= $_FILES['userfile']['tmp_name'];
        $error= $_FILES['userfile']['error'];
        echo "{$name}<br>{$type}<br>{$size}<br>{$tmpName}<br>{$error}";
    ?>
    
    • $_FILES['userfile'] 键值说明

      • $_FILES['userfile']['name'] 上传文件的名称
      • $_FILES['userfile']['type'] 上传文件的MIME类型(image/jpeg、image/gif、image/png)
      • $_FILES['userfile']['size'] 上传文件的大小,以字节为单位
      • $_FILES['userfile']['tmp_name'] 文件上传时的临时文件
      • $_FILES[][‘error’] 错误编码(值有0、1、2、3、4、6、7)
        • 0 - 正确
        • 4 - 没有文件上传
        • 1 - 文件大小超过了php.ini中允许的最大值 upload_max_filesize = 2M
        • 2 - 文件大小超过了表单允许的最大值
        • 3 - 只有部分文件上传
        • 6 - 找不到临时文件
        • 7 - 文件写入失败
    • 与文件上传有关的配置

      • post_max_size = 8M 表单允许的最大值
      • upload_max_filesize = 2M 允许上传的文件大小
      • upload_tmp_dir =F:wamp mp 指定临时文件地址,如果不知道操作系统指定
      • file_uploads = On 是否允许文件上传
      • max_file_uploads = 20 允许同时上传20个文件
    <?php
      echo ini_get('post_max_size');
      echo ini_get('upload_max_filesize');
      echo ini_get('upload_tmp_dir');
      echo ini_get('file_uploads');
      echo ini_get('max_file_uploads');
    ?>
    
    • 将上传文件移动到指定位置
      • move_uploaded_file() 临时地址,目标地址
      • 上传的同名的文件要给覆盖
    # upload.php
    <?php
      mkdir('D:Program Filesxampphtdocsuploads');
      $newDir= "uploads/".$_FILES['userfile']['name'];
      if(!empty($_POST)) {
        if($_FILES['userfile']['error']== 0){  
          if(move_uploaded_file($_FILES['userfile']['tmp_name'], $newDir)){
            echo "上传成功";
          };
        }else{
          echo '上传有误';
          echo '错误码:'.$_FILES['userfile']['error'];
          exit;
        }
      }
    ?>
    

    优化文件上传

    • 更改文件名
      • 通过时间戳做文件名
      • 通过uniqid()实现
        • uniqid() 生成唯一的ID
        • uniqid('goods_') 带有前缀
        • uniqid('goods_',true) 唯一ID+随机数
    # upload.php
    <?php
        # 判断是否存在目录
        $dir= 'D:Program Filesxampphtdocsuploads';
        if(!is_dir($dir)){
            mkdir($dir);
        }
        # 通过时间戳做文件名
        $newName= time().rand(100,999).strrchr($_FILES['userfile']['name'],'.'); 
        $newDir= "uploads/".$newName;
        # 上传服务处理
        if(!empty($_POST)) {
            if($_FILES['userfile']['error']== 0){  
                if(move_uploaded_file($_FILES['userfile']['tmp_name'], $newDir)){
                    echo "上传成功";
                };
            }else{
                echo '上传有误';
                echo '错误码:'.$_FILES['userfile']['error'];
                exit;
            }
        }
    ?>
    
    # upload.php
    <?php
        # 判断是否存在目录
        $dir= 'D:Program Filesxampphtdocsuploads';
        if(!is_dir($dir)){
            mkdir($dir);
        }
        # 通过uniqid()实现
        $newName= uniqid('goods_',true).strrchr($_FILES['userfile']['name'],'.'); 
        $newDir= "uploads/".$newName;
        # 上传服务处理
        if(!empty($_POST)) {
            if($_FILES['userfile']['error']== 0){  
                if(move_uploaded_file($_FILES['userfile']['tmp_name'], $newDir)){
                    echo "上传成功";
                };
            }else{
                echo '上传有误';
                echo '错误码:'.$_FILES['userfile']['error'];
                exit;
            }
        }
    ?>
    
    • 验证文件格式
      • 将文件的后缀和允许的后缀对比 (不能识别文件伪装)
      • 通过$_FIELS[]['type']类型判断 (不能识别文件伪装)
      • 在php.ini中开启fileinfo扩展 (可以防止文件伪装)
    # # upload.php
    <?php
      if(!empty($_POST)) {
        # 判断是否存在目录
        $dir= 'D:Program Filesxampphtdocsuploads';
        if(!is_dir($dir)){
          mkdir($dir);
        }
        # 通过uniqid()实现重命名
        $newName= uniqid('goods_',true).strrchr($_FILES['userfile']['name'],'.'); 
        $newDir= "uploads/".$newName;
        # 文件名拓展名验证
        $allow= array('.jpg','.png','.gif');
        $ext= strrchr($_FILES['userfile']['name'],'.');
        if(!in_array($ext,$allow)){
          echo '文件上传不合法';
          exit;
        }
        # 上传服务处理
        if($_FILES['userfile']['error']== 0){  
          if(move_uploaded_file($_FILES['userfile']['tmp_name'], $newDir)){
            echo "上传成功";
          };
        }else{
          echo '上传有误';
          echo '错误码:'.$_FILES['userfile']['error'];
          exit;
        }
      }
    ?>
    
    # upload.php
    <?php
      if(!empty($_POST)) {
        # 判断是否存在目录
        $dir= 'D:Program Filesxampphtdocsuploads';
        if(!is_dir($dir)){
          mkdir($dir);
        }
        # 通过uniqid()实现重命名
        $newName= uniqid('goods_',true).strrchr($_FILES['userfile']['name'],'.'); 
        $newDir= "uploads/".$newName;
        # 文件名拓展名验证
        $allow= array('image/jpeg','image/png','image/gif');
        $ext= $_FILES['userfile']['type'];
        if(!in_array($ext,$allow)){
          echo '文件上传不合法';
          exit;
        }
        # 上传服务处理
        if($_FILES['userfile']['error']== 0){  
          if(move_uploaded_file($_FILES['userfile']['tmp_name'], $newDir)){
            echo "上传成功";
          };
        }else{
          echo '上传有误';
          echo '错误码:'.$_FILES['userfile']['error'];
          exit;
        }
      }
    ?>
    
    # upload.php
    <?php
      if(!empty($_POST)) {
        # 判断是否存在目录
        $dir= 'D:Program Filesxampphtdocsuploads';
        if(!is_dir($dir)){
          mkdir($dir);
        }
        # 通过uniqid()实现重命名
        $newName= uniqid('goods_',true).strrchr($_FILES['userfile']['name'],'.'); 
        $newDir= "uploads/".$newName;
        # 文件名拓展名验证
        $info=finfo_open(FILEINFO_MIME_TYPE);
        $ext= finfo_file($info, $_FILES['userfile']['tmp_name']);
        $allow= array('image/jpeg','image/png','image/gif');
        if(!in_array($ext,$allow)){
          echo '文件上传不合法';
          exit;
        }
        # 上传服务处理
        if($_FILES['userfile']['error']== 0){  
          if(move_uploaded_file($_FILES['userfile']['tmp_name'], $newDir)){
            echo "上传成功";
          };
        }else{
          echo '上传有误';
          echo '错误码:'.$_FILES['userfile']['error'];
          exit;
        }
      }
    ?>
    
    • 优化文件上传
    <?php
        if(!empty($_POST)) {
            # 判断是否存在目录
            $dir= 'D:Program Filesxampphtdocsuploads';
            if(!is_dir($dir)){
                mkdir($dir);
            }
            # 通过uniqid()实现重命名
            $newName= uniqid('goods_',true).strrchr($_FILES['userfile']['name'],'.'); 
            $newDir= "uploads/".$newName;
            # 文件名拓展名验证
            $info=finfo_open(FILEINFO_MIME_TYPE);
            $ext= finfo_file($info, $_FILES['userfile']['tmp_name']);
            $allow= array('image/jpeg','image/png','image/gif');
            if(!in_array($ext,$allow)){
                echo '只能上传 '.implode(' , ',$allow).' 等文件格式';
                exit;
            }
            # 验证文件大小
            $fileSize= ini_get('upload_max_filesize');
            if(substr($fileSize, -1, 1)== 'k'){
                $fileSize= (integer)$fileSize* 1024;
            }elseif(substr($fileSize, -1, 1)== 'M'){
                $fileSize= (integer)$fileSize* 1024* 1024;
            }elseif(substr($fileSize, -1, 1)== 'G'){
                $fileSize= (integer)$fileSize* 1024* 1024* 1024;
            }elseif(substr($fileSize, -1, 1)== 'T'){
                $fileSize= (integer)$fileSize* 1024* 1024* 1024* 1024;
            }
            if($_FILES['userfile']['size']> $fileSize){
                echo '文件大小不能超过'.number_format($fileSize/1024, 1).'K';
                exit;
            }
            # 验证是否是http上传
            if(!is_uploaded_file($_FILES['userfile']['tmp_name'])){
                echo '文件不是HTTP POST上传的<br>';
                exit;
            }
            # 上传服务处理
            if($_FILES['userfile']['error']== 0){  
                if(move_uploaded_file($_FILES['userfile']['tmp_name'], $newDir)){
                    echo "上传成功";
                };
            }else{
                switch($_FILES['userfile']['error']) {
                    case 1:
                        echo '文件大小超过了php.ini中允许的最大值,最大值是:'.ini_get('upload_max_filesize');
                        break;  
                    case 2:
                        echo '文件大小超过了表单允许的最大值';
                        break; 
                    case 3:
                        echo '只有部分文件上传';
                        break; 
                    case 4:
                        echo '没有文件上传';
                        break; 
                    case 6:
                        echo '找不到临时文件';
                        break; 
                    case 7:
                        echo '文件写入失败';
                        break; 
                    default:
                        echo '未知错误';
                        break; 
                }
            }
        }
    ?>
    

    文件下载

    • 方法解释

      • __FILE__ 当前文件的带文件名的绝对路径
      • dirname(__FILE__) 返回路径中的目录部分
      • iconv() 文件编码转换
      • feof() 检测流上的文件结束符的函数,如果文件结束,则返回非0值,否则返回0
    • 响应头设置

      • Content-type: application/octet-stream 指定文件类型
      • Content-Disposition: attachment; filename={$file_name} 指定文件描述
    <?php
        header('Content-Type:text/html; charset=utf-8');
        define('ROOT_PATH', dirname(__FILE__));
    
        function downfile($file_path){
            $file_path= iconv('utf-8', 'gb2312', $file_path);
            if(!file_exists($file_path)){
                exit('文件不存在!');
            }
    
            $file_name= basename($file_path);
            $file_size= filesize($file_path);
            $file= fopen($file_path, 'r');
            header("Content-type: application/octet-stream");
            header("Content-Disposition: attachment; filename={$file_name}");
    
            $buffer= 1024;
            $file_count= 0;
    
            while(!feof($file) && ($file_size- $file_count> 0)){
                $file_data= fread($file, $buffer);
                $file_count+= $buffer;
                echo $file_data;
            }
    
            fclose($file);
        }
        downfile(ROOT_PATH.".imgpigger.jpg");
    ?>
    
  • 相关阅读:
    图书管理系统---基于form组件和modelform改造添加和编辑
    Keepalived和Heartbeat
    SCAN IP 解释
    Configure Active DataGuard and DG BROKER
    Oracle 11gR2
    我在管理工作中積累的九種最重要的領導力 (李開復)
    公募基金公司超融合基础架构与同城灾备建设实践
    Oracle 11g RAC for LINUX rhel 6.X silent install(静默安装)
    11gR2 静默安装RAC 集群和数据库软件
    Setting Up Oracle GoldenGate 12
  • 原文地址:https://www.cnblogs.com/SharkJiao/p/14023629.html
Copyright © 2011-2022 走看看