09-文件上传原理与实现过程

1、单文件上传

<?php
//$_FILES
print_r($_FILES);
printf('<pre>%s</pre>', print_r($_FILES, true));
//isset()函数用于判断某一个变量是否存在
if (isset($_FILES['my_pic'])) {
    //Array=>$_FILES
    //[my_pic]=>$_FILES[my_pic]
    //原始文件名 [name] =>$_FILES[my_pic][name]
    //临时文件名 [tmp_name] =>$_FILES[my_pic][tmp_name]
    //错误代码   [error]    =>$_FILES[my_pic][error]
    $name = $_FILES['my_pic']['name'];
    $tmpName = $_FILES['my_pic']['tmp_name'];
    $error = $_FILES['my_pic']['error'];
    if ($error > 0) {
        echo '上传失败';
        //如果想查看错误原因
        $tips = '<span style="color:red">上传失败!</span><br>';
        switch ($error) {
            case 1:
                $tips .= '大小超过了php.ini中的允许上传的文件大小';
                break;
            case 2:
                $tips .= '大小超过了表单中MAX_FILE_SIZE的允许上传的文件大小';
                break;
            case 3:
                $tips .= '文件只有部分被上传';
                break;
            case 4:
                $tips .= '没有文件被上传';
                break;
            case 5:
                $tips .= '5是预留的,没有定义';
                break;
            case 6:
                $tips .= '找不到临时目录';
                break;
            case 7:
                $tips .= '文件写入失败,请检查目录权限,一般出现在Linux系统';
                break;
        }
        echo "<p>$tips</p>";
    } else {
        //!判断上传方式是不是合法,POST?
        if(is_uploaded_file($tmpName)){
            //文件类型白名单
            $allow = ['jpg','jpeg','png','webp','gif'];
            //扩展名
            //!pathinfo()返回一个数组,包括文件的dirname(目录名),basename(当前整体名),extension(扩展名),filename(文件名)
            $ext = pathinfo($name)['extension'];

            //!in_array(要查询的某个值,判断的范围数组)判断某一个值是否在数组中
            if(in_array($ext,$allow)){
                //如果上传方式合法,且是允许的类型,则可以把他移动到指定的目标目录中了
                //!加斜杠表示它是个目录,不加也可,加了更直观
                $path = 'uploads/';

                //!为了防止同名覆盖,应该给目标文件名重命名,用md5进行加密
                $dest = $path . md5($name) . '.' . $ext;
                //将文件从临时目录移动到目标目录中
                if(move_uploaded_file($tmpName,$dest)){
                    echo '<p>上传成功</p>';
                    //预览
                    echo "<img src='$dest' width='300'>";
                }else{

                }
            }else{
                echo '<p>文件类型错误</p>';
            }
        }else{
            echo '<p>上传方式非法</p>';
        }
    }
}
?>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>支持文件上传的表单,$_FILES(实际上就是一个数值)</title>
</head>

<body>
    <!-- 1.method:POST如果是get请求,参数在地址栏,地址栏传值最大长度4k,不能满足需要 -->
    <!-- 2.enctype="multipart/form-data"设置编码 -->
    <form action="" method="POST" enctype="multipart/form-data">
        <fieldset>
            <legend>单文件上传</legend>
            <!-- name="my_pic":给服务器编程语言用的变量名,用$_FILES来读取 -->
            <!-- 字节是计算机数据的最小单位,一个字节=8bit -->
            <!-- 内存地址就是按照字节来进行编码 -->
            <input type="hidden" name="MAX_FILE_SIZE" value="800000">
            <input type="file" name="my_pic">
            <button>上传</button>
        </fieldset>
    </form>
</body>

</html>

上述运行结果:

 2、多文件上传(方法一)

<?php
//$_FILES
printf('<pre>%s</pre>', print_r($_FILES, true));

foreach($_FILES as $file){
    //只要判断$file['error']===0 即表示上传成功
    if($file['error']===0){
        //暂不加密目标文件名
        $dest = 'uploads/' . $file['name']; 
        //移动到目标目录
        move_uploaded_file($file['tmp_name'],$dest);

        //预览
        echo "<img src='$dest' width='200'>";
    }
}
?>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>多文件上传</title>
</head>

<body>
    <!-- 1.method:POST如果是get请求,参数在地址栏,地址栏传值最大长度4k,不能满足需要 -->
    <!-- 2.enctype="multipart/form-data"设置编码 -->
    <form action="" method="POST" enctype="multipart/form-data">
        <fieldset>
            <legend>多文件上传-1:逐个上传</legend>
            <!-- name="my_pic":给服务器编程语言用的变量名,用$_FILES来读取 -->
            <!-- 字节是计算机数据的最小单位,一个字节=8bit -->
            <!-- 内存地址就是按照字节来进行编码 -->
            <input type="hidden" name="MAX_FILE_SIZE" value="800000">
            <input type="file" name="my_pic1">
            <input type="file" name="my_pic2">
            <input type="file" name="my_pic3">
            <button>上传</button>
        </fieldset>
    </form>
</body>

</html>

 上述运行结果:

  3、多文件上传(方法二)

<?php
//$_FILES
printf('<pre>%s</pre>', print_r($_FILES, true));

// if(isset($_FILES['my_pic'])){
    foreach ($_FILES['my_pic']['error'] as $key => $error) {
        //!可以把0换成UPLOAD_ERR_OK
        if ($error === UPLOAD_ERR_OK) {
            //临时文件名
            $tmpName = $_FILES['my_pic']['tmp_name'][$key];
            //原始文件名
            $name = $_FILES['my_pic']['name'][$key];
            //目标文件名
            $dest = 'uploads/' . $name;
            //移动到目标目录
            move_uploaded_file($tmpName, $dest);
            //预览
            echo "<img src='$dest' width='200'>";
        }
    }
// }

?>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>多文件上传</title>
</head>

<body>
    <!-- 1.method:POST如果是get请求,参数在地址栏,地址栏传值最大长度4k,不能满足需要 -->
    <!-- 2.enctype="multipart/form-data"设置编码 -->
    <form action="" method="POST" enctype="multipart/form-data">
        <fieldset>
            <legend>多文件上传-2:逐个上传</legend>
            <!-- name="my_pic":给服务器编程语言用的变量名,用$_FILES来读取 -->
            <!-- 字节是计算机数据的最小单位,一个字节=8bit -->
            <!-- 内存地址就是按照字节来进行编码 -->
            <input type="hidden" name="MAX_FILE_SIZE" value="800000">
            <input type="file" name="my_pic[]">
            <input type="file" name="my_pic[]">  
            <input type="file" name="my_pic[]">
            <button>上传</button>
        </fieldset>
    </form>
</body>

</html>

上述运行结果:

Notice:Undefined index:my_pic in ....

需要先检查一下my_pic在不在,否则会有警告,当然这个警告可以关闭

 if(isset($_FILES['my_pic'])){
    foreach ($_FILES['my_pic']['error'] as $key => $error) {
        //!可以把0换成UPLOAD_ERR_OK
        if ($error === UPLOAD_ERR_OK) {
            //临时文件名
            $tmpName = $_FILES['my_pic']['tmp_name'][$key];
            //原始文件名
            $name = $_FILES['my_pic']['name'][$key];
            //目标文件名
            $dest = 'uploads/' . $name;
            //移动到目标目录
            move_uploaded_file($tmpName, $dest);
            //预览
            echo "<img src='$dest' width='200'>";
        }
    }
 }

 修改后的运行结果:

 但是,这种上传方式还是有缺陷的,因为不能够用Ctrl键选择多个文件上传

  4、多文件上传(方法三)

<?php
//$_FILES
printf('<pre>%s</pre>', print_r($_FILES, true));

 if(isset($_FILES['my_pic'])){
    foreach ($_FILES['my_pic']['error'] as $key => $error) {
        //!可以把0换成UPLOAD_ERR_OK
        if ($error === UPLOAD_ERR_OK) {
            //临时文件名
            $tmpName = $_FILES['my_pic']['tmp_name'][$key];
            //原始文件名
            $name = $_FILES['my_pic']['name'][$key];
            //目标文件名
            $dest = 'uploads/' . $name;
            //移动到目标目录
            move_uploaded_file($tmpName, $dest);
            //预览
            echo "<img src='$dest' width='20'>";
        }
    }
 }

?>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>多文件上传</title>
</head>

<body>
    <!-- 1.method:POST如果是get请求,参数在地址栏,地址栏传值最大长度4k,不能满足需要 -->
    <!-- 2.enctype="multipart/form-data"设置编码 -->
    <form action="" method="POST" enctype="multipart/form-data">
        <fieldset>
            <legend>多文件上传-2:逐个上传</legend>
            <!-- name="my_pic":给服务器编程语言用的变量名,用$_FILES来读取 -->
            <!-- 字节是计算机数据的最小单位,一个字节=8bit -->
            <!-- 内存地址就是按照字节来进行编码 -->
            <input type="hidden" name="MAX_FILE_SIZE" value="800000">
            <!-- multiple:允许同时选择多个 -->
            <input type="file" name="my_pic[]" multiple>
            <button>上传</button>
        </fieldset>
    </form>
</body>

</html>

上述运行结果:

与demo3.php相比,只改了两个地方

 1.只保留一个my_pic[]

 2.加一个multiple属性,支持多选

 php处理上传的代码,和demo3.php完全一样,不用动

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

七色的天空

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值