PHP入门学习笔记六

一、表单的参数传递

1.1 复选框参数传递

复选框参数传递存在问题,例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
<?php
    if (isset($_POST['button'])) {
    
    
        echo $_POST['languages'];
    }
?>
    <form action="" method="post">
        语言:<input type="checkbox" name="languages" value="PHP">PHP
        <input type="checkbox" name="languages" value="javascript">javascript
        <input type="checkbox" name="languages" value="node">node
        <input type="checkbox" name="languages" value="vue">vue
        <button type="submit" name="button">确定</button>
    </form>
</body>
</html>

效果:
在这里插入图片描述
可以很直观的发现,复选框当我们选择两个以上时只会选择最后一个,那么我们需要在复选框的name属性后加个[ ]表示这个是一系列的数组,如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
<?php
    if (isset($_POST['button'])) {
    
    
        print_r($_POST['languages']);
    }
?>
    <form action="" method="post">
        语言:<input type="checkbox" name="languages[]" value="PHP">PHP
        <input type="checkbox" name="languages[]" value="javascript">javascript
        <input type="checkbox" name="languages[]" value="node">node
        <input type="checkbox" name="languages[]" value="vue">vue
        <button type="submit" name="button">确定</button>
    </form>
</body>
</html>

效果:
在这里插入图片描述
这样就可以解决复选框的问题了。

1.2 其他表单参数传递

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
<?php
    if (isset($_POST['button'])) {
    
    
        echo '姓名:'.$_POST['username'].'<br/>';
        echo '密码:'.$_POST['password'].'<br/>';
        echo '性别:'.$_POST['sex'].'<br/>';
        echo '居住地:'.$_POST['area'].'<br/>';
        echo '留言:'.$_POST['mark'].'<br/>';
    }
    echo '<hr/>';
?>
    <form action="" method="post">
        姓名:<input type="text" name="username"><br/>
        密码:<input type="password" name="password"><br/>
        性别:<input type="radio" name="sex" value="1" checked><input type="radio" name="sex" value="0"><br/>
        爱好:
        居住地:
        <select name="area">
            <option value="amoy">厦门</option>
            <option value="fuzhou">福州</option>
        </select><br/>
        备注:<textarea name="mark" cols="30" rows="5"></textarea>
        <button type="submit" name="button">确定</button>
    </form>
</body>
</html>

效果:
在这里插入图片描述

二、文件参数的传递(二进制)

2.1 文件域

开发中需要上传图片、音乐、视频等等,这种上传传递是二进制数据。
文件域:<input type="file" name="image">

2.2 表单enctyoe属性

enctype 属性规定在发送到服务器之前应该如何对表单数据进行编码。默认地,表单数据会编码为 “application/x-www-form-urlencoded”。就是说,在发送到服务器之前,所有字符都会进行编码。

表单的enctype属性,默认情况下,表单传递的是字符流,不能传递二进制,通过enctype属性设置可以传递复合数据。
enctype有三种格式:
在这里插入图片描述

  1. application/x-www-form-urlencoded 只能传字符串,带格式的,xml
  2. multipart/form-data 能传字符串或者二进制数据,文件上传必须设置这个。
  3. text/plain 传字符串,不带格式。

2.3 接收文件$_FILES

超全局变量$_FILES是一个二维数组,用来保存客户端上传到服务器的文件信息。二维数组的行是文件域的名称,列有5个。
例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
<?php
    if (!empty($_POST)) {
    
    
        echo '<pre/>';
        print_r($_FILES);
    }
?>
    <form action="" method="post" enctype="multipart/form-data">
        <input type="file" name="image">
        <button type="submit" name="button">上传</button>
    </form>
</body>
</html>

效果:
在这里插入图片描述

  1. name:上传的文件名
  2. type:上传的类型,这个类型是MIME类型
  3. size:文件的大小,以字节为单位
  4. tmp_name:文件上传时的临时文件
  5. error:错误的编码(值有0、1、2、3、4、6、7)0表示正确
    error值描述:
error值 错误描述
0 正确
1 文件大小超过了php.ini允许的最大值
2 文件大小超过了表单允许的最大值
3 只有部分文件上传
4 没有文件上传
6 找不到临时文件
7 文件写入失效

可以在php.ini中设置允许的最大值:
在这里插入图片描述
php.ini中设置允许最大为2M。

设置表单允许的最大值:
在这里插入图片描述
只要掌握错误号,0和4即可。

2.4 将上传文件移到指定位置。move_uploaded_file(临时地址, 目标地址)

函数:move_uploaded_file(临时地址, 目标地址)
例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
<?php
    if (!empty($_POST)) {
    
    
        // 如果有文件上传并且正确,进行上传文件移到指定位置
        if ($_FILES['image']['error'] == 0) {
    
    
            move_uploaded_file($_FILES['image']['tmp_name'], './'.$_FILES['image']['name']);
        }
    }
?>
    <form action="" method="post" enctype="multipart/form-data">
        <input type="file" name="image">
        <button type="submit" name="button">上传</button>
    </form>
</body>
</html>

效果:
在这里插入图片描述
可以看到已经从桌面上传到www文件夹下了。

php.ini中与上传文件相关的一些配置:

  1. post_max_size = 8M(表单允许的最大值)
    在这里插入图片描述
  2. upload_max_filesize = 2M(允许上传文件的大小)
    在这里插入图片描述
  3. upload_tmp_dir =“F:/Program/tmp”(指定临时文件地址)
    在这里插入图片描述
  4. file_uploads = On(是否允许文件上传)
    在这里插入图片描述
  5. max_file_uploads = 20(允许同时上传20个文件)
    在这里插入图片描述

2.5 优化文件上传,同名处理。

在文件上传时,如果是相同名字的将覆盖,那这个肯定不是我们想要的,接下来来优化下这个问题。

在这之前,先介绍两个处理字符串的函数strchr( )strrchr( )。例:

<?php
    $path='counter.name.jpg';
    echo strchr($path, '.');
?>

效果:
在这里插入图片描述
strchr( 匹配的字符串,以什么为选择起始标志) :这个方法从左边开始匹配。

<?php
    $path='counter.name.jpg';
    echo strrchr($path, '.');
?>

效果:
在这里插入图片描述
strrchr( 匹配的字符串,以什么为选择起始标志) :这个方法从右边开始匹配。

  1. 通过时间戳拼接3位随机数做文件名
<?php
    $path='counter.name.jpg';
    echo time().rand(100,999).strrchr($path, '.');
?>

效果:
在这里插入图片描述
2. 通过php自带的uniqid( )做文件名
uniqid(前缀,true)。
例:

<?php
    $path='counter.name.jpg';
    echo uniqid('goods_').strrchr($path, '.'), '<br/>';
    echo uniqid('goods_', true).strrchr($path, '.');
?>

效果:
在这里插入图片描述

2.6 验证文件格式

  1. 判断文件后缀名。
    例:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
<?php
    if (!empty($_POST)) {
    
    
        $arr=array('.jpg','.png','.gif'); // 允许的扩展名
        $ext=strrchr($_FILES['languages']['name'],'.'); // 上传文件扩展名
        if (in_array($ext, $arr)) {
    
    
            echo '允许上传';
        }
        else {
    
    
            echo '不允许上传';
        }
    }
?>
    <form action="" method="post" enctype="multipart/form-data">
        <input type="file" name="languages">
        <button type="submit" name="button">上传</button>
    </form>
</body>
</html>

效果:
在这里插入图片描述
但是如果我在桌面新建一个记事本,aa.txt,然后我将后缀改为.jpg,那么它也是允许上传的,但是他的本质还是文本,所以这里的安全系数不高。不能防止文件伪装。

  1. 判断mime类型
    例:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
<?php
    if (!empty($_POST)) {
    
    
        $arr=array('image/jpeg','image/png','image/gif'); // 允许的扩展名
        $mime=$_FILES['languages']['type']; // mime类型
        if (in_array($mime, $arr)) {
    
    
            echo '允许上传';
        }
        else {
    
    
            echo '不允许上传';
        }
    }
?>
    <form action="" method="post" enctype="multipart/form-data">
        <input type="file" name="languages">
        <button type="submit" name="button">上传</button>
    </form>
</body>
</html>

效果:
在这里插入图片描述
可以看到判断mime类型也不能防止文件伪装。

  1. php_fileinfo扩展
    在php.ini配置中找到如图:
    在这里插入图片描述
    开启扩展后,就可以调用里面定义的函数。例:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
<?php
    if (!empty($_POST)) {
    
    
        // 1.创建finfo资源
        $info=finfo_open(FILEINFO_MIME_TYPE);
        var_dump($info);
        // 2.将finfo资源和文件做比较
        echo finfo_file($info,$_FILES['languages']['tmp_name']);
    }
?>
    <form action="" method="post" enctype="multipart/form-data">
        <input type="file" name="languages">
        <button type="submit" name="button">上传</button>
    </form>
</body>
</html>

效果:
在这里插入图片描述
那么这个就可以防止文件伪装了,它可以强大到你的记事本是空的都知道,如果写了内容或者脚本也能分析出来,这边就不试了,就是在aa.jpg中写入js脚本,它也能检测出来。感兴趣的小伙伴可以自己试试。

三、优化文件上传例题

  1. 验证是否有误
  2. 验证格式
  3. 验证大小
  4. 验证是否是http上传
  5. 上传实现

例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
<?php
    
    function checkErr($file) {
    
    
        $error = $file['error'];
        // 1.验证错误
        if ($error != 0) {
    
    
            switch ($error) {
    
    
                case 1:
                    return '文件大小超过了php.ini允许的最大值'.ini_get('upload_max_filesize');
                case 2:
                    return '文件大小超过了表单允许的最大值';
                case 3:
                    return '只有部分文件上传';
                case 4:
                    return '没有文件上传';
                case 6:
                    return '找不到临时文件';
                case 7:
                    return '文件写入失效';
                default:
                    return '未知错误';
            }
        }
        // 2.验证格式
        $info=finfo_open(FILEINFO_MIME_TYPE);
        $mime=finfo_file($info,$file['tmp_name']);
        $arr=array('image/jpeg','image/png','image/gif');
        if (!in_array($mime,$arr)) {
    
    
            return '只能上传'.implode(',',$arr);
        }
        // 3.验证大小
        $size=1024000;
        if ($file['size']>$size) {
    
    
            return '文件大小不能超过'.number_format($size/1024,1).'kb';
        }
        // 4.验证是否是http上传
        if (!is_uploaded_file($file['tmp_name'])) {
    
    
            return '文件不是HTTP POST 上传的<br/>';
        }
        return null;
    }
    if (!empty($_POST)) {
    
    
        if ($err = checkErr($_FILES['languages'])) {
    
    
            echo $err;
        }
        else {
    
    
            // 5.文件上传
            //$folder=date('Y-m-d H:i:s') // 将当前的时间转成 年-月-日 小时:分钟:秒数
            echo $folder=date('Y-m-d'); // 文件夹名称
            $path="./uploads/${folder}"; // 文件夹路径
            if (!is_dir($path)) {
    
    
                mkdir($path);
            }
            else {
    
    
                $filename=uniqid('',true).strrchr($_FILES['languages']['name'], '.'); // 文件名
                $filepath="$path/$filename"; // 文件路径
                if (move_uploaded_file($_FILES['languages']['tmp_name'], $filepath)) {
    
    
                    echo "上传成功,路径是:${filepath}";
                }
                else {
    
    
                    echo '失败<br/>';
                }
            }
            
        }
    }
?>
    <form action="" method="post" enctype="multipart/form-data">
        <input type="file" name="languages">
        <button type="submit" name="button">上传</button>
    </form>
</body>
</html>

效果:
在这里插入图片描述
在这里插入图片描述
可以看到按照预期的上传成功了。

在学习的php的路上,如果你觉得本文对你有所帮助的话,那就请关注点赞评论三连吧,谢谢,你的肯定是我写博的另一个支持。

猜你喜欢

转载自blog.csdn.net/weixin_44103733/article/details/106651382