zoukankan      html  css  js  c++  java
  • php上传文件原理

    上传文件原理

    总述:将本地的文件上传到服务器中。
    php上传文件的步骤:

    第一步:将本地的文件上传到服务器的临时目录
    第二步:将上传的文件从临时目录移动到指定的目录中。

    method属性:传值的方法 method=’post’
    enctype属性:上传文件进行编码 enctype=”multipart/form-data”

    简单原理 :
    表单部分
    这里写图片描述
    PHP代码部分:
    这里写图片描述
    超全局变量 $_FILES
    这里写图片描述
    这里写图片描述
    这里写图片描述

    对上传文件的判断需要考虑到?

    /**
    *
    * 1)判断是否是HTTP POST上传的
    * 2)判断是否有错误
    * 3)判断文件大小
    * 4)判断文件扩展名
    * 5)判断文件类型
    * 6)构建临时文件
    * 7)构建目标文件
    */
    1)判断文件是否是通过HTTP POST 上传的
    is_uploaded_file //判断文件是否是通过HTTP POST上传的
    这里写图片描述
    2)上传文件错误代码

    这里写图片描述
    3)对上传文件大小的判断
    在php.ini中设置上传文件的大小:
    upload_max_filesize // 上传允许的单文件的最大值
    max_file_uploads //上传文件的允许最大数量

    这里写图片描述
    这里写图片描述
    4)对上传文件扩展名的判断
    strrpos //计算指定字符串在目标字符串中最后一次出现的位置
    strrchr //查找指定字符在字符串中的最后一次出现
    这里写图片描述
    5)上传文件类型的判断(MIME)
    这里写图片描述
    这里写图片描述
    利用php_fileinfo.dll 对MIME类型进行严格检查:
    开启php_fileinfo.dll扩展,finof_open(FILEINFO_MIME_TYPE);finfo_file();
    这里写图片描述
    这里写图片描述
    这里写图片描述
    6上传文件:move_uploaded_file
    move_uploaded_file(tmpname,dst_name) //将上传的文件移动到新的路径
    说明:
    1)tmpname//2)dst_name //将上传文件移动到指定的路径中,并设置新的文件名.
    这里写图片描述
    如果上传文件打不开:
    关于没有temp访问权限,添加一个everyone的用户
    这里写图片描述
    表单代码:
    index.php 如下

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
    <form action="upload.php" method="post" enctype="multipart/form-data">
        请选择上传文件:<input type='file' name='upload'></input>
        <input type="submit" name="submit" value="立即上传"></input>
    </form>
    </body>
    </html>

    后台逻辑
    接收代码

    <?php 
    header("content-type:text/html;charset=utf-8");
    if (isset($_POST['submit'])) {
        //打印一下$_FILES
        echo "<pre>";
        print_r($_FILES);
        echo "</pre>";
    
        //判断文件是不是通过表单上传的
        //is_uploaded_file(上传的临时文件)
        if(!is_uploaded_file($_FILES['upload']['tmp_name'])){
            exit('上传的文件有问题');
        }
    
        //上传文件是否有错误
        if($_FILES['upload']['error'] != 0){
            exit('上传文件有错误,请重新上传');
        }
        //判断文件大小
        //允许上传小于2MB的文件
        if ($_FILES['upload']['size']>2*1024*1024) {
            exit('上传文件过大,请重新上传');
        }
    
        //获取文件扩展名
        //方法一:
        //strrpos — 计算指定字符串在目标字符串中最后一次出现的位置
        //strrpos(大海, 针);
        //$index = strrpos($_FILES['upload']['name'], ".");
        //echo $index; 9
        //$ext = substr($_FILES['upload']['name'], $index);
        //echo $ext;  .jpg
    
        //方法二:
        //strrchr — 查找指定字符在字符串中的最后一次出现
        $ext = strrchr($_FILES['upload']['name'], '.');
    
        //判断文件类型
        //使用第三扩展
        $fs = finfo_open(FILEINFO_MIME_TYPE);
        //var_dump($fs);
        //finfo_file(资源类型,上传的临时文件)
        $mime = finfo_file($fs,$_FILES['upload']['tmp_name']);
        //image/jpeg
        //本网站对用户上传文件的类型有限制
        $arr_mime = array('image/jpeg' ,'image/png');
        //in_array — 检查数组中是否存在某个值
        //in_array(needle, haystack)
         if(!in_array($mime, $arr_mime)){
            exit('上传的文件类型不合法,请重新上传');
         }
    
        //构建临时文件
        $filename = $_FILES['upload']['tmp_name'];
        //构建目标文件的文件名及路径
        $path ='./upload/'; //在服务器的目录
        $destination = $path.date('YmdHis').$ext;  //$ext是文件的扩展名
        if(!move_uploaded_file($filename, $destination)){
            exit('上传失败');
        }
    
    } else {
        echo "<script>alert('非法上传');location.href='index.php'</script>";
    }
    
    ?>

    将上传封装为函数
    在上传的代码中,可以由用户自己来定义的通过设置为形参
    表单代码还是之前的
    后台逻辑分开
    upload.php

    <?php 
    header("content-type:text/html;charset=utf-8");
    require_once './config.php';
    if (isset($_POST['submit'])) {
    
        $file = $_FILES['upload'];
        $arr_mime = array('image/jpeg' ,'image/png');
        $path = 'upload';
    
        //调用函数
        upload($file,$arr_mime,$path);
    
    } else {
        echo "非法上传";
    }
    ?>

    封装的上传文件函数
    哪里需要用就可以直接include
    config.php代码如下

    <?php 
    /**
     * [upload description]
     * @param  [type] $file     [表单中文件域name的值 如: $_FILES['upload']]
     * @param  [type] $arr_mime [允许上传的文件类型]
     * @param  [type] $path     [自己定义的上传文件的路径]
     * @return [type]           [description]
     */
    function upload($file,$arr_mime,$path){
        //判断文件是不是通过表单上传的
        //is_uploaded_file(上传的临时文件)
        if(!is_uploaded_file($file['tmp_name'])){
            exit('上传的文件有问题');
        }
    
        //上传文件是否有错误
        if($file['error'] != 0){
            exit('上传文件有错误,请重新上传');
        }
        //判断文件大小
        //允许上传小于2MB的文件
        if ($file['size']>2*1024*1024) {
            exit('上传文件过大,请重新上传');
        }
    
        //方法二:
        //strrchr — 查找指定字符在字符串中的最后一次出现
        $ext = strrchr($file['name'], '.');
    
        //判断文件类型
        //使用第三扩展
        $fs = finfo_open(FILEINFO_MIME_TYPE);
        //var_dump($fs);
        //finfo_file(资源类型,上传的临时文件)
        $mime = finfo_file($fs,$file['tmp_name']);
        //image/jpeg
        //本网站对用户上传文件的类型有限制
    
        //in_array — 检查数组中是否存在某个值
        //in_array(needle, haystack)
         if(!in_array($mime, $arr_mime)){
            exit('上传的文件类型不合法,请重新上传');
         }
        //构建临时文件
        $filename = $file['tmp_name'];
        //构建目标文件的文件名及路径
        //$path ='./upload/'; //在服务器
    
        $destination = $path.'/'.date('YmdHis').$ext;  //$ext是文件的扩展名
    
        if(!move_uploaded_file($filename, $destination)){
            exit('上传失败');
        }
    
    }
    
     ?>

    多文件上传

    这里写图片描述
    将三维数组转为二维数组
    这里写图片描述
    以临时文件为例进行foreach遍历
    key,value对应的值如下图:
    这里写图片描述
    文件名处理:
    生成唯一的ID目录文件名,
    这里写图片描述
    在其它判断中,$key的使用方法:
    如在遍历中,文件大小的判断
    这里写图片描述

    表单代码

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
    <form action="upload.php" method="post" enctype="multipart/form-data">
        请选择上传文件:<br><br>
        <input type='file' name='upload[]'></input><br><br>
        <input type='file' name='upload[]'></input><br><br>
        <input type='file' name='upload[]'></input><br><br>
        <input type="submit" name="submit" value="立即上传"></input>
    </form>
    </body>
    </html>

    后台逻辑代码`

    <?php 
    header("content-type:text/html;charset=utf-8");
    
    if (isset($_POST['submit'])) { 
        /*echo "<pre>";
        print_r($_FILES);
        echo "</pre>";
        echo "<hr>";*/
        //将三维数组转为二维数组,为了便于操作
        $arr = $_FILES['upload'];
        echo "<pre>";
        print_r($arr);
        echo "</pre>";
        echo "<hr>";
    
        foreach ($arr['tmp_name'] as $key => $value) {
    
        //如判断文件的大小
        if($arr['size'][$key]>2*1024*1024){
            exit('文件过大');
        }
        //文件的扩展名
        $ext = strrchr($arr['name'][$key], '.');
        //构建目标文件的文件名及路径
        $path ='./upload'; //在服务
        //多文件上传注意重命名的问题
        //uniqid();
        $destination = $path.'/'.uniqid('itcast').date('YmdHis').'.jpg';  
    
            if(!move_uploaded_file($value, $destination)){
                exit('上传失败');
            }
        }
    } else {
        echo "非法上传";
    }
    ?>
  • 相关阅读:
    基于ASP.NET WEB API实现分布式数据访问中间层(提供对数据库的CRUD)
    C# 实现AOP 的几种常见方式
    SignalR的另类实现技巧
    通过winform+模拟登录实现快速一键登录到人才招聘网站
    Winform应用程序实现通用遮罩层二
    近期开发项目中用到的编码小技巧汇总说明
    详解:基于WEB API实现批量文件由一个服务器同步快速传输到其它多个服务器功能
    关于Quartz.NET作业调度框架的一点小小的封装,实现伪AOP写LOG功能
    trackViewer 氨基酸位点变异位置图谱展示
    python基础-PyYaml操作yaml文件
  • 原文地址:https://www.cnblogs.com/liuqun/p/12655251.html
Copyright © 2011-2022 走看看