美文网首页
开发企业网站9 -- 文件上传

开发企业网站9 -- 文件上传

作者: 潘肚饿兵哥哥 | 来源:发表于2019-10-18 20:21 被阅读0次

    \color{rgba(254, 67, 101, .8)}{上传同样的需要html页面显示和php文件处理业务}
    \color{rgba(254, 67, 101, .8)}{在上传文件页面,html原来是这样:}

    <h3>上传文件</h3>
    <from action="upload.php" method="post" >
    <p>
      <input type="file" name="file">
    </p>
    <p>
      <button>提交</button>
    </p>
    

    \color{rgba(254, 67, 101, .8)}{用post提交,然后类型是file,这个表单的名字是file}
    \color{rgba(254, 67, 101, .8)}{在php文件里,接收文件名为file的数据}

    <?php 
      $file=$_POST['file'];
    ?>
    

    \color{rgba(254, 67, 101, .8)}{这是之前的做法,但是这里还是这样做的话}
    \color{rgba(254, 67, 101, .8)}{例如上传一张图片,就只会接收到图片名称,图片内容是接收不到的}
    \color{rgba(254, 67, 101, .8)}{在form里这样改}

    添加enctype="multipart/form-data"
    
    <h3>上传文件</h3>
    <from action="upload.php" method="post"  enctype="multipart/form-data">
    <p>
      <input type="file" name="file">
    </p>
    <p>
      <button>提交</button>
    </p>
    

    定义和用法
    enctype 属性规定在发送到服务器之前应该如何对表单数据进行编码。

    默认地,表单数据会编码为 "application/x-www-form-urlencoded"。就是说,在发送到服务器之前,所有字符都会进行编码(空格转换为 "+" 加号,特殊符号转换为 ASCII HEX 值)。

    image.png

    \color{rgba(254, 67, 101, .8)}{上传文件需要用这个属性,但使用了这个属性之后,会报错}
    \color{rgba(254, 67, 101, .8)}{因为之前是用post接收的file类型}
    \color{rgba(254, 67, 101, .8)}{这里加了enctype 属性之后,file就不管用了}
    \color{rgba(254, 67, 101, .8)}{文件域里的file用post接收就不行了}
    \color{rgba(254, 67, 101, .8)}{需要用另外一个系统预处理超全局数组}

    $GLOBALS
    $_SERVER
    $_REQUEST
    $_POST
    $_GET
    $_FILES:    HTTP 文件上传变量
    $_ENV
    $_COOKIE
    $_SESSION

    \color{rgba(254, 67, 101, .8)}{用files变量来接收}

    <?php 
      $file = $_FILES['file'];
    ?>
    

    \color{rgba(254, 67, 101, .8)}{用enctype属性编码后,用files数组接收文件,接收到的数组就不只是一个文件名}
    \color{rgba(254, 67, 101, .8)}{而是一个带着文件名、文件类型和文件路径的数组}
    \color{rgba(254, 67, 101, .8)}{还有是否报错和文件大小}
    \color{rgba(254, 67, 101, .8)}{这个路径是服务器的路径,文件已经传到服务器里面了}
    \color{rgba(254, 67, 101, .8)}{此时是以临时文件的形式放在这里}
    \color{rgba(254, 67, 101, .8)}{文件上传就是把这个临时文件移动到需要的地方去}
    \color{rgba(254, 67, 101, .8)}{在移动的过程中,要更改文件名}
    \color{rgba(254, 67, 101, .8)}{因为不知道是模板还是什么会改动文件名后再保存为临时文件}
    \color{rgba(254, 67, 101, .8)}{这就实现了上传}

    移动:
    move_uploaded_file(要移动的路径,要移动的内容(文件名));

    \color{rgba(254, 67, 101, .8)}{文件上传html页面代码}

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    <body>
        <H3>上传文件</H3>
        <!-- 上传要用post   -->
        <form action="../../admin/upload.php" method="post" enctype="multipart/form-data" />
            <p>
                <input type="file" name="file">
            </p>
            <p>
                <button>提交</button>
            </p>
        </form>
    </body>
    </html>
    
    image.png

    \color{rgba(254, 67, 101, .8)}{文件上传php文件}

    <?php
        // 调用这个函数这样写:$ret是接收到的函数的返回值
        // 这个返回值有两个,一是成功或失败,二是如果失败,是什么原因失败
        // 如果不是写成一个函数,那这个if和die就可以写在代码中
        // 但是如果要封装函数,就要在外面写
        // 如果上传成功,就显示图片(路径,url)
        $ret = upload('file');
        if($ret['error'] == 1){
            die($ret['message']);
        }else{
            echo "<img src='{$ret['url']}' />";
        }
    
    
    
    
        //将这段上传文件代码封装成一个函数
        function upload($name, $path='uploads', $allow_type=['jpg', 'png', 'gif'], $max_size=2*1024*1024){
            // 在上传页面填的文件名是file,所以在这里接收这个名叫file的文件
            $file = $_FILES[$name];
    
    
            //在接收上传文件之前,需要进行一些限制,不能用户上传什么我们就接收什么
            // 首先要判断用户有没有上传文件,如果没有,就显示提示信息后终止执行程序
            // 返回值有两个,但是只能写一个return,就用关联数组,如果上传失败,返回值是1
            if(!empty($file['name'])){
                return ['error'=>1, 'message'=>'没有上传文件'];
            }
    
    
            //strrchr() 函数查找字符串在另一个字符串中最后一次出现的位置,并返回从该位置到字符串结尾的所有字符。
            // 用于获取上传文件的后缀,下面这行代码表示获取文件名点后面的内容
            $suffix = strrchr($file['name'], '.');
    
    
    
            // 如果用户上传了文件,那么需要进行判定是不是允许的文件类型,那就先要写好允许上传的文件是哪些
            // 有两个办法可以完成,一是上传的文件信息中有一个type,type中就带有文件格式信息,但是这种麻烦,因为文件类型太多,所以用第二中办法
            // 先写好一个数组,把允许上传的文件类型都写在数组中,只要上传的文件不是这几种格式就禁止上传
            // 用in_array();函数判断接收到的文件类型在不在这个数组中,在就允许上传,不在就禁止
            // 上面$suffix变量取得的后缀是带点的,要把这个点去掉,用substr();函数截取从下标1开始的内容,第0位就是点
            // 但是这个变量如果这样写,这段代码就只能上传图片,所以不在这里写了,把它通过传参的形式来传,可以拓展这个函数的适用范围
            //$allow_type = ['jpg', 'png', 'gif'];
            if(in_array(substr($suffix, 1), $allow_type)){
                return ['error'=>1, 'message'=>'文件类型不允许'];
            }
    
    
            // 用户上传文件的大小也需要进行限制,1024*1024就是1M
            // 配置文件php.ini文件中(upload_max_filesize)默认上传的大小限制就是2M,如果需要更大,要先改配置文件
            // 这里尺寸写死了就没法改了,通过给函数传参的形式可以灵活设置尺寸大小
            // $max_size = 2*1024*1024;
            if($file['size'] > $max_size){
                return ['error'=>1, 'message'=>'上传文件不能超过2M'];
            }
    
    
            // 上传文件必须要从html页面提交来,否则不接收
            // is_uploaded_file();判断文件是否用post或get上传
            if(!is_uploaded_file($file['tmp_name'])){
                return ['error'=>1, 'message'=>'非法上传'];
            }
        
    
            // 文件先建一个文件夹uploads,然后再建一个子文件夹用年月日格式命名,用于装移动过来的文件(上传的文件)
            // 这里如果这样写,路径也写死了,文件夹名就不能改了,所以,文件夹名也用传参的方式传进来
            // $path = 'uploads/'.date('Ymd').'/';
            $path = $path.'/'.date('Ymd').'/';
    
    
            // 首先判断这个保存文件的路径存不存在,用is_dir这个函数进行判断
            if(!is_dir($path)){
                // 如果目录不存在,就创建一个目录
                // 创建目录函数: mkdir(目录,权限,是否递归创建(缺省为否));
                // 权限,windows系统不限,linux不能乱填,所以为了通用,要按规则填,目录一般填0755,文件一般填0644,就是没有执行权限
                // 0755是八进制,每一个数代表一个权限,每一个目录都有三种角色:所有者、所有组、其他人
                //每一个文件、目录都有三个权限,读、写、执行,用数字代替就是读4,写2,执行1,就是2的0次方,1次方,2次方
                /*
                            读4    写2    执行1
                所有者
                所有组
                其他人
                0755就是这三个数的组合
                */
                //递归创建目录就是能不能创建多级目录,默认不允许
    
                mkdir($path, 0755, true);
            }
    
            // 这里文件名和文件类型都不能写死了,因为文件类型不同,而且文件名不能重名
            // $filename = $path.'1.jpg';
            // 文件名用年月日时分秒,并且每秒中之内产生的文件名再用随机数生成一个数,之后md5加密
            //文件后缀名要在前面$_FILES之后进行接收
            $filename = $path.md5(date('YmdHis').mt_rand(10, 99)).'.$suffix';
    
    
            // 上传其实就是把一个文件移动到另一个文件夹中去
            // 如果成功返回值0,并且返回路径,如果失败,返回值1,并提示上传失败
            if(move_uploaded_file($file['tmp_name'], $filename)){
                return ['error' => 0, 'url' => 'filename'];
            }else{
                return ['error'=>1, 'message'=>'上传失败'];
            }
        }
            
        
    ?>
    

    相关文章

      网友评论

          本文标题:开发企业网站9 -- 文件上传

          本文链接:https://www.haomeiwen.com/subject/uyhfmctx.html