PHP进阶——表单传值和文件上传

1、表单传值

表单传值就是浏览器通过表单元素,将数据传给后台服务器语言

1.1表单传值方式
1)GET传值
2)POST传值
  • post表单方式的基本设定
    < form method=“POST”>表单元素< /form>
3)post方式跟get方式的区别
  1. GET传输的数据主要用来获取数据,不改变服务器上资源:get只是用来获取内容
  2. Post传输的数据主要用来增加数据,改变服务器上资源:POST会改变服务器上数据内容
  3. 传输方式上post必须使用form表单,而get可以使用form表单和URL
  4. get传输数据可以在URL中对外可见,而post不可见:GET传值最终会在浏览器的地址栏中全部显示:?数据名=数据值&数据名2=数据值2…
  5. get和post能传输的数据大小不同,get为2K,post理论无限制(事实上,GET和POST本身没有数据长度限制,但是浏览器厂家做了一些限制)
  6. get和post能够传输的数据格式有区别:get传输简单数据(数值/字符串),post可以提交复杂数据(二进制等)
1.2、PHP接收数据的三种方式

$_GET方式:接收GET方式提交的数据
$_POST方式:接收POST方式提交的数据
$_REQUEST方式:接收POST或者GET提交的所有数据
这三个变量的本质是数组,接受的时候,表单必须有下标"name",如< a name=“XX”>,而value的值就是数组的元素值

1) $ _REQUEST所存储数据的内容:将 $ _POST和 $ _ GET合并存储到一个数组
2) $ _REQUEST和 $ _POST与 $ _GET的联系:如果GET和POST中有同名数组元素(下标),POST会覆盖GET(PHP中数组元素下标具有唯一性),这个可以在php.ini中进行配置

<?php 
    echo'<pre>';

    var_dump($_GET);

    echo '<hr>';
    var_dump($_POST);

    echo '<hr>';
    var_dump($_REQUEST);

    echo '<hr>';
    
 ?>

在浏览器中输入http://localhost/shuju.php?data=php 会有以下结果, 其中shuju.php是PHP文件,把data作为下标,php作为值传值到PHP文件
在这里插入图片描述
但是,在真正应用上不要同时存在 $ _GET、$ _POST和$ _REQUEST

1.3、简单的综合训练

表单传值,就必须要有表单< form>,而且表单必须有方法 method=“方法” ,有action=“PHP文件”,然后在< form>里面写input框,input必须有类型,名字,最后,必须有一个提交框,类型为submit
shuju.php:

<?php 
    header('Content-type:text/html;charset=utf-8');//解决不能输出中文的bug

    echo'<pre>';
    
    echo '<hr>';
    var_dump($_REQUEST);
 ?>

shuju.html:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <form method="POST"
    action="shuju.php">
        <!-- 创建3个框 -->
        <input type="text" name="username" value="账号">
        <input type="text" name="password" value="密码">
        <input type="submit" name="sub" value="提交">
    </form>
</body>
</html>

在网站中输入http://localhost/shuju.html
在这里插入图片描述
点击提交:
在这里插入图片描述
由此可以看出,html中的name,就是PHP文件数据中的下标,而value就是值

2、PHP处理复选框数据

2.1基本处理

复选框,就是在这里插入图片描述这个亚子

有两种解决方法,一种是每个框的name都是不一样的,还有另外一种是所有框的name都是一样的(归组),请看以下方法:

刚才的综合训练可以得知,每个下标只能有一个值,但是如果3个复选框都是hobby字节,那么最终传值的话只能一个传值,另外两个被覆盖掉了,这时候就可以使用 [ ] 来处理复选框

解决方案:浏览器不识别[](浏览器不认为有特殊性),但是PHP认为[]有特殊性:系统自动认为该符号是数组的形式,所以PHP就会自动的将同名的但是带有[]的元素组合到一起形成一个数组

复选框一定要加 [ ] !!!

shuju.php:

<?php 
    header('Content-type:text/html;charset=utf-8');//解决不能输出中文的bug

    echo'<pre>';
    
    echo '<hr>';
    print_r($_REQUEST);
 ?>

shuju.html:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <form method="POST"
    action="shuju.php">
        <input type="checkbox" name="hobby[]" value=""><input type="checkbox" name="hobby[]" value=""><input type="checkbox" name="hobby[]" value="rap">rap
        <input type="submit" name="btn" value="提交">
    </form>
</body>
</html>

在这里插入图片描述
在这里插入图片描述

如果把PHP文件中改一下变成这样:

<?php 
    header('Content-type:text/html;charset=utf-8');//解决不能输出中文的bug

    echo'<pre>';
    
    //print_r($_REQUEST);
    $hobby=$_REQUEST['hobby'];//假设我们的出来的结果只要hobby这个数组,不要btn,那么可以直接用['hobby']即可
    print_r($hobby);
 ?>

在这里插入图片描述

2.2、多选按钮的数据处理

1、 表单中name属性使用数组格式:名字 [ ](一类复选框数据使用一个)
2、 后台接收到数据之后,是一个数组(数组不能存储到数据库)
3、 PHP需要将数组转换成指定格式的字符串:使用分隔符分隔每一个元素并且形成字符串:implode(’分隔符’ ,数组)
4、 PHP组织SQL直接存储到数据库
shuju.html:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <form method="POST"
    action="shuju.php">
        <input type="checkbox" name="hobby[]" value=""><input type="checkbox" name="hobby[]" value=""><input type="checkbox" name="hobby[]" value="rap">rap
        <input type="submit" name="btn" value="提交">
    </form>
</body>
</html>

shuju.php:

<?php 
    header('Content-type:text/html;charset=utf-8');//解决不能输出中文的bug

    echo'<pre>';
    
    //print_r($_REQUEST);
    $hobby=$_REQUEST['hobby'];
    $hobby_string=implode($hobby, '、');//用、来分割
    echo $hobby_string;
 ?>

在这里插入图片描述
在这里插入图片描述
反之,如果想把一个字符串分割开来,可以用explode(分隔符,字符串)来分割

2.3、其他常规同名表单项的数据处理

除开radio button单选框和checkbox复选框,很少会出现同名的表单项。如果非要使用同名的来进行管理,那么可以采用checkbox方式进行操作
1、 表单中同名增加[]
2、 PHP接收时数组处理
3、 PHP转换成有格式的字符串
4、 数据库字符串存储

2.4、复选框细节

如果复选框没有选中,那么浏览器就不会提交。因此在PHP接收使用复选框(单选框)数据的时候,应该先判断是否存在该数据
如果复选框一个也没选中,就会报错
在这里插入图片描述
在这里插入图片描述
应该这样修改

<?php 
    header('Content-type:text/html;charset=utf-8');//解决不能输出中文的bug

    echo'<pre>';
    
    //print_r($_REQUEST);
    //$hobby=$_REQUEST['hobby'];
    $hobby=isset($_POST['hobby'])? $_POST['hoby']:array();

    $hobby_string=implode($hobby, '、');
    echo $hobby_string;
 ?>

在这里插入图片描述
也没报错,证明成功
在这里插入图片描述

3、文件上传

3.1、文件上传的表单写法

概念:类似于上面的表单传值,只不过上面的传值是传字符串等数据,而文件上传表单写法就是上传文件而已,概念是一样的,也是要用一个值来接受图片–$_FILES,复选框就等于多文件上传一样的概念,都是把字符串换成了文件而已
1)method属性:表单提交方式必须为POST
2)enctype属性:form表单属性,主要是规范表单数据的编码方式
3)上传表单:file表单
在这里插入图片描述
file.html:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <!-- 文件上传类型必须为POST,而且必须要加enctype="multipart/form-data"  -->
    <form method="POST" enctype="multipart/form-data" action="file.php">
    <!-- input类型为file,也必须有名字,也必须有提交框 -->
        <input type="file" name="img">
        <input type="submit" name="btn" value="上传文件">
    </form>
</body>
</html>

file.php:

<?php 
    header('Content-type:text/html;charset=utf-8');//解决不能输出中文的bug

    echo '<pre>';

    var_dump($_POST);//接受POST
    var_dump($_FILES);//接受图片
 ?>

在这里插入图片描述我是已近选择了图片了

在这里插入图片描述
可以看出,第一个array(1)是$_POST,只有一个btn,第二个是 $_FILES,具有图片的很多信息

3.2、$_FILES变量详解

1)name:文件在用户(浏览器端)电脑上实际存在的名字(实际用来保留后缀)
2)tmp_name:文件上传到服务器后操作系统保存的临时路径(实际用来给PHP后期使用)
3)type:MIME(多功能互联网邮件扩展)类型,用来在计算机中客户端识别文件类型(确定软件)
4)size:文件大小(PHP根据实际需求来确定是否该保留)
5)error:文件上传的代号,用来告知应用软件(PHP)文件接收过程中出现了什么问题(PHP后期根据代码进行文件判断)
在这里插入图片描述

3.3、移动临时文件到目标位置

文件上传之后会保存到 $_FILES中,那么访问文件信息的形式就是 $_FILES[‘表单name属性值 ’ ] [‘元素信息’],如访问图片文件 $_FILES[‘img’][‘tmp_name’]

  • 第一步:先判断是否为上传的文件:is_uploaded_file()
    在这里插入图片描述
<?php 
    header('Content-type:text/html;charset=utf-8');//解决不能输出中文的bug

    //1、取得文件信息
    $file=$_FILES['img'];

    //2判断是否为上传文件
    //$file['tmp_name']就是取得临时文件
    if(is_uploaded_file($file['tmp_name'])){
        //为上传文件,  代码未完
    }
    else{
        //不是上传的文件
        echo'文件上传失败';
    }
 ?>
  • 第二步:移动文件:move_uploaded_file()
    在这里插入图片描述
<?php 
    header('Content-type:text/html;charset=utf-8');//解决不能输出中文的bug

    //1、取得文件信息
    $file=$_FILES['img'];

    //2判断是否为上传文件
    //$file['tmp_name']就是取得临时文件
    if(is_uploaded_file($file['tmp_name'])){
        // 前面的为要移动的文件,后面为文件新位置,而且必须为文件全名如 img/图片名.jpg,用 . 是字符串连接
        if(move_uploaded_file($file['tmp_name'], 'img/'.$file['name'])){
            echo'文件保存成功';
        }
        else{
            echo '文件保存失败';
        }
    }
    else{
        //不是上传的文件
        echo'文件上传失败';
    }
 ?>

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.4、多文件上传

类似复选框,也是两种解决方法,一种是每个图片的input–name不一样,第二种是input–name 加 [ ] 。

  • 加 [ ]
    file.php:
<?php 
    header('Content-type:text/html;charset=utf-8');//解决不能输出中文的bug

    echo '<pre>';

    print_r($_FILES);
 ?>

file.html:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <!-- 文件上传类型必须为POST,而且必须要加enctype="multipart/form-data"  -->
    <form method="POST" enctype="multipart/form-data" action="file.php">
    <!-- input类型为file,也必须有名字,也必须有提交框 -->
        <input type="file" name="img[]">
        <input type="file" name="img[]">
        <input type="file" name="img[]">
        <input type="submit" name="btn" value="批量上传">
    </form>
</body>
</html>

在这里插入图片描述
在这里插入图片描述

  • 改成不同名上传
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <!-- 文件上传类型必须为POST,而且必须要加enctype="multipart/form-data"  -->
    <form method="POST" enctype="multipart/form-data" action="file.php">
    <!-- input类型为file,也必须有名字,也必须有提交框 -->
        <input type="file" name="img1">
        <input type="file" name="img2">
        <input type="file" name="img3">
        <input type="submit" name="btn" value="批量上传">
    </form>
</body>
</html>

在这里插入图片描述

3.5、对多文件信息的遍历读取和处理
  • 1)不同名多文件上传处理方式:
    当不知道有多少张图片时,可以采用foreach来遍历函数 foreach(数组 as 分成每个数组的名字)
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <!-- 文件上传类型必须为POST,而且必须要加enctype="multipart/form-data"  -->
    <form method="POST" enctype="multipart/form-data" action="file.php">
    <!-- input类型为file,也必须有名字,也必须有提交框 -->
        <input type="file" name="img1">
        <input type="file" name="img2">
        <input type="file" name="img3">
        <input type="submit" name="btn" value="批量上传">
    </form>
</body>
</html>
<?php 
    header('Content-type:text/html;charset=utf-8');//解决不能输出中文的bug

    //相当于每个都分成$file=$_FILES['img'];
    foreach ($_FILES as  $file) {
        if(is_uploaded_file($file['tmp_name'])){
            if(move_uploaded_file($file['tmp_name'], 'img/'.$file['name'])){
                echo'文件保存成功';
            }
            else{
                echo '文件保存失败';
            }
        }
        else{
            echo'文件上传失败';
        }
    }

 ?>

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 2)同名多文件上传(好鸡巴难)
    因为同名多文件上传之后是这样得
    在这里插入图片描述
    每一个都是合起来的,那么我们要先得到一个文件对应的5个元素。把$_FILES中对应的name/type/tmp_name/error/size都挨个取出来放到不同的数组中,即变成上面的不同名多文件上传格式
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <!-- 文件上传类型必须为POST,而且必须要加enctype="multipart/form-data"  -->
    <form method="POST" enctype="multipart/form-data" action="file.php">
    <!-- input类型为file,也必须有名字,也必须有提交框 -->
        <input type="file" name="img[]">
        <input type="file" name="img[]">
        <input type="file" name="img[]">
        <input type="submit" name="btn" value="批量上传">
    </form>
</body>
</html>
<?php 
    header('Content-type:text/html;charset=utf-8');//解决不能输出中文的bug
    echo '<pre>';
    //第一步,把同名转换成不同命的格式

    //首先遍历$_FILES是没有用的,因为只有一个元素数组img,应该遍历$_FILES['img']['任意一个元素']
    //判断元素存在而且是数组,name有的话代表是文件,name元素有多个(数组)代表是同名批量上传
    if(isset($_FILES['img']['name'])&& is_array($_FILES['img']['name'])){
        //先弄个一个空数组出来
        $img=array();
        //把各个属性都弄在一个数组里面
        foreach ($_FILES['img']['name'] as $key => $file) {
            //注意这里用的是img[],就是说这是个二维数组,分别存放第1、2、3张图片的所有信息,分别为img[1]、img[2]、img[3]
            $img[]=array(
                'name' =>$file,//因为$_FILEES['img']['name']下标对应的值为$file,所以这里'name'=>$_FILES['img']['name'][$key]
                'tmp_name'=>$_FILES['img']['tmp_name'][$key],
                'type'=>$_FILES['img']['type'][$key],
                'error'=>$_FILES['img']['error'][$key],
                'size'=>$_FILES['img']['size'][$key]
                );
        }
    }

    print_r($img);

    //第二步,转化为不同命的格式后,对其进行遍历

    foreach ($img as $value) {
        //判断是否为上传文件
        if(is_uploaded_file($value['tmp_name'])){
            if(move_uploaded_file($value['tmp_name'], 'img/'.$value['name'])){
                echo'文件保存成功';
            }
            else{
                echo '文件保存失败';
            }
        }
        else{
            echo'文件上传失败';
        }
    }



 ?>

在这里插入图片描述
在这里插入图片描述

4、做一个PHP文件上传功能封装函数!!!!(综合训练)

  • 目标:实现上传功能代码的重复利用:封装文件上传函数
  • 功能:上传文件
  • 条件:条件判断
    1. 文件类型是否合适?外部指定MIME类型(MIME类型为支持HTML上传的类型)
    2. 文件存储到什么位置?外部指定
    3. 文件格式限制(文件后缀)?外部限定
    4. 文件大小限制?外部指定
4.1、封装出一个函数

先写出注释和函数的类型需求等

<?php 
    header('Content-type:text/html;charset=utf-8');

    /*
    * array $file ,需要上传的文件的5元素(name,tmp_name,type,error,size)
    * array $allow_type,允许上传的MIME类型
    * string $path ,文件存储路径
    * string &$error,错误类型,错误方式以中文方式输出
    * array $allow_format=array(),允许文件上传的格式
    * int $max_sizee,允许上传的最大字节
    */

    function upload_file_single($file,$allow_type,$path,&$error,$allow_format = array(),$max_size){

    }

 ?>
4.2、判断文件是否有效

is_array(参数),判断参数是不是一个数组
isset(变量名),判断该变量名是否存在

//判断文件是否有效
        if(!is_array($file)||!isset($file['error'])){
            //文件无效
            $error='此文件无效';
            return false;
        }
4.3、判断保存路径是否存在

is_dir()
在这里插入图片描述

        //判断路径是否有效
        if(!is_dir($path)){
            $error='保存路径无效';
            return false;
        }
4.4、判断文件上传本身是否有错误:file [ ’ error ’ ]
        //判断文件上传本身是否有错误:file [ ' error ' ]
        switch ($file['error']) {
            case 1:
            case 2:
                $error='文件大小超过限制大小';
                return false;//这里也不用break;了,因为都返回错误了,剩下代码都不执行了
            case 3:
                $error='只有部分文件被上传';
                return false;
            case 4:
                $error='文件没有被上传';
                return false;
                //我也不知道5的错误是什么官方也没说
            case 6:
            case 7:
                $error='文件保存失败';
        }
4.5、判断是否为MIME类型

(MIME类型为支持HTML上传的类型)

        //判断MIME类型
        if(!in_array($file['type'],$allow_type)){
            $error='当前文件类型不允许上传';
            return false;
        }
4.6、判断后缀是否允许

strrchr:
在这里插入图片描述
ltrim
在这里插入图片描述
in_array
在这里插入图片描述

        //判断后缀名是否允许
        //去除后缀给$ext
        //就是使用strrchr从.开始取出后缀为.png,然后再用ltrim去除. 得到png
        $ext=ltrim(strrchr($file['name'],'.'),'.');
        if(!in_array($ext, $allow_format)&&!empty($allow_format)){
        //首先判断allow_format是否为空,然后判断后缀名$ext是否在$allow_format数组中
            $error='当前文件类型不允许上传';
            return false;
        }
4.7、判断大小是否满足
        //判断大小是否满足
        if($file['size']>$max_size){
            $error='当前文件过大,已超出'.$max_size.'字节';
            return false;
        }
4.8、构造文件名字以免重复

在这里插入图片描述
chr(ASCII):生成对应的ASCII码
产生随机数字:mt_rand(min,max)

        //构造文件名字$fullname以免重复:年月日+随机字符串.后缀
        $fullname=date('YYYmmdd');//先产生日期
        //随机产生数字
        for ($i=0,$j=4; $i <$j ; $i++) { 
            $fullname=$fullname.chr(mt_rand(65,90));
        }
        $fullname=$fullname.'.'.$ext;
4.9、移动到指定目录下
        //移动到指定目录下
        //判断是否为上传文件
        if(!is_uploaded_file($file['tmp_name'])){
            $error='不是上传的文件';
            return false;
        }
        //左边为上传文件,右边为指定目录+上传后的文件名
        if(move_uploaded_file($file['tmp_name'], $path.'/'.$fullname)){
            return $fullname;
        }
        else{
            $error='文件上传失败';
            return false;
        }

4.10、总代码和总的结果

file_function.html

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <!-- 文件上传类型必须为POST,而且必须要加enctype="multipart/form-data"  -->
    <form method="POST" enctype="multipart/form-data" action="file_function.php">
    <!-- input类型为file,也必须有名字,也必须有提交框 -->
        <input type="file" name="img">
        <input type="submit" name="btn" value="上传文件">
    </form>
</body>
</html>

file_function.php

<?php 
    header('Content-type:text/html;charset=utf-8');

    /*
    * array $file ,需要上传的文件的5元素(name,tmp_name,type,error,size)
    * array $allow_type,允许上传的MIME类型
    * string $path ,文件存储路径
    * string &$error,错误类型,错误方式以中文方式输出
    * array $allow_format=array(),允许文件上传的格式
    * int $max_sizee,允许上传的最大字节
    */

    function upload_file_single($file,$allow_type,$path,&$error,$allow_format = array(),$max_size){

        //判断文件是否有效
        if(!is_array($file)||!isset($file['error'])){
            //文件无效
            $error='此文件无效';
            return false;
        }

        //判断路径是否有效
        if(!is_dir($path)){
            $error='保存路径无效';
            return false;
        }

        //判断文件上传本身是否有错误:file [ ' error ' ]
        switch ($file['error']) {
            case 1:
            case 2:
                $error='文件大小超过限制大小';
                return false;//这里也不用break;了,因为都返回错误了,剩下代码都不执行了
            case 3:
                $error='只有部分文件被上传';
                return false;
            case 4:
                $error='文件没有被上传';
                return false;
            case 6:
            case 7:
                $error='文件保存失败';
        }

        //判断MIME类型
        if(!in_array($file['type'],$allow_type)){
            $error='当前文件类型不允许上传(MIME错误)';
            return false;
        }

        //判断后缀名是否允许
        //去除后缀给$ext
        //就是使用strrchr从.开始取出后缀为.png,然后再用ltrim去除. 得到png
        $ext=ltrim(strrchr($file['name'],'.'),'.');
        if(!in_array($ext, $allow_format)&&!empty($allow_format)){
        //首先判断allow_format是否为空,然后判断后缀名$ext是否在$allow_format数组中
            $error='当前文件类型不允许上传';
            return false;
        }

        //判断大小是否满足
        if($file['size']>$max_size){
            $error='当前文件过大,已超出'.$max_size.'字节';
            return false;
        }

        //构造文件名字$fullname以免重复:年月日+随机字符串.后缀
        $fullname=date('YYYmmdd');//先产生日期
        //随机产生数字
        for ($i=0,$j=4; $i <$j ; $i++) { 
            $fullname=$fullname.chr(mt_rand(65,90));
        }
        $fullname=$fullname.'.'.$ext;

        //移动到指定目录下
        //判断是否为上传文件
        if(!is_uploaded_file($file['tmp_name'])){
            $error='不是上传的文件';
            return false;
        }
        //左边为上传文件,右边为指定目录+上传后的文件名
        if(move_uploaded_file($file['tmp_name'], $path.'/'.$fullname)){
            return $fullname;
        }
        else{
            $error='文件上传失败';
            return false;
        }
    }

    //提供数据
    $file = $_FILES['img'];
    $path = 'img';
    $allow_type = array('image/jpg','image/jpeg','image/gif','image/pjpeg','image/png');
    $allow_format = array('jpg','gif','jpeg','png');
    $max_size = 8000000;

    if($filename = upload_file_single($file,$allow_type,$path,$error,$allow_format,$max_size)){
        echo '文件上传成功,图片名为'.$filename;
    }else{
        echo $error;
    }
 ?>

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值