表单传值
表单传值意义【掌握】
1.表单传值的意义:表单传值能够帮助网站收集用户数据,实现用户与网站后台的数据交互。
2.表单传值方式:表单传值就是利用HTML的一组特点标签,然后通过浏览器解析后,给用户提供一种数据录入的入口,并且允许用户在数据录入后,实现数据提交。
表单传值方式【掌握】
1.简单介绍HTTP协议的传输规则
- HEAD:通过发送HTTP请求来从服务器获取数据(不带任何数据,很少使用)
- GET:与HEAD一样,但是GET通常是通过自身携带数据来获取服务器数据
- PUT:指定服务器端存储位置来提交数据(HTML不支持)
- POST:直接提交数据给服务器
- DELETE:通过指定数据来删除服务器的数据(很少使用)
- OPTIONS:获取URL所支持的方法(极少使用)
2.表单传值方式:表单传值为了方便开发人员开发,通常只使用GET和POST两种方式来实现数据的提交
- GET:显示的提交用户数据,通常开发人员认定此数据不会对后台数据产生改变,只会通过提交的数据来确定服务器要返回的数据
- POST:隐式的提交用户数据,通常该类数据都是用来存储到后台数据库的
GET和POST传值实现【掌握】
1.GET传值:GET传值是一种比较显性的数据传输方式,会在提交传输过程中,直接将数据添加到用户可见的URL之后。GET传值的方式有以下几种:
- a标签传输:直接在a标签中对应的href属性对应的链接中添加数据,数据的添加格式就是使用?将URL主体和数据分离,数据的绑定方式属于键值对,即:名字=值,如果是多个数据使用&符号分离
<html>
<head></head>
<body>
<a href="http://www.taobao.com/index.php?keywords=笔记本&type=超极本">淘宝.笔记本.超极本</a>
<!--其中http://是协议,www.taobao.com属于主机地址,/index.php是URI,而?之后都是对应的数据:keywords和type都属于数据的名字,笔记本和超极本属于数据值,&符号代表多个数据的分隔符号-->
</body>
</html>
a标签的传输方式是GET方式传输的一种典型代表,几乎所有的GET方式传值都采用a标签方式。a标签的数据并非用户提交,而是由后台开发人员根据用户的需求,提前准备好
- form标签:form标签是HTML中专门针对用户数据提交的一种表单,该表单允许会由开发人员提前准备好。form标签本身不做任何数据传输,而是靠form表单内部的其他数据表单来绑定数据,form表单可以批量进行数据传输
<html>
<head></head>
<body>
<form action="请求脚本文件地址" method="GET">
<input type="text" name="keywords" value=""/>
<input type="text" name="type" value=""/>
<input type="submit" value="检索"/>
<!--
form中action代表的本次提交的目标属性,即后台某个能够处理当前请求的PHP脚本;
method是form的可改变属性,如果为GET那么意味着提交方式为GET传值,如果是POST那么就是POST传值;
input为表单框,type确定表单元素的操作属性,text表明是文本输入,submit为提交动作,name作为提交的必须属性代表提交给后台数据对应的数据名字,value代表数据值,用户输入的那么可以为空,由用户输入数据
-->
</form>
</body>
</html>
form表单是一种标准数据提交方式,可选GET方式还是POST方式,由开发人员根据当前数据的类型和数据的安全性来确定。通常如果是需要用户进行数据写入的时候就会使用到form表单,form表单不限定数据数量
- location对象的href属性:location是window对象的一个属性,是用来包含当前窗口对应的url信息,但是同时该属性本身还有一个href属性,可以用来动态的改变窗口对应的url,这个时候需要利用事件
<html>
<head></head>
<body>
<input type="button" value="获取当前URL" οnclick="alert(window.location)"/>
<!--window.location会得到当前的URL-->
<input type="button" value="改变当前URL" onClick="window.location.href='http://www.baidu.com/index.php?search=电脑'"/>
<!--window.location.href会在触发后进入到指定的url地址-->
</body>
</html>
window.location.href这个在实际开发中会更多应用于事件操作。即用户在做某些指定操作的时候,可以进行页面的跳转
- location对象的assign()方法:assign()方法与href属性相似,都是需要通过事件操作来设定某些触发点,然后用户触发后执行对应的窗口跳转
<html>
<head></head>
<body>
<input type="button" value="改变当前URL" onClick="window.location.assign('http://www.baidu.com/index.php?search=电脑')"/>
<!--window.location.href会在触发后进入到指定的url地址-->
</body>
</html>
window.location.assign()的本质与href属性一样,就是改变当前窗口的URL,其操作方式也是通过事件触发
2.POST传值:POST传值是一种比较隐性的传值方式,一般用户无法直观的看到传输的数据,POST传值方式比较单一,就是通过Form表单进行传值,同时在method属性中使用POST方式即可
<html>
<head></head>
<body>
<form action="请求脚本文件地址" method="POST">
<input type="text" name="keywords" value=""/>
<input type="text" name="type" value=""/>
<input type="submit" value="检索"/>
</form>
</body>
</html>
3.GET与POST的区别:GET和POST没有本质的区别,都可以实现数据从浏览器端传输到服务器端
- 目标用途区别:GET主要用来获取服务器数据,提供的是一些数据信息片段,服务器通过数据片段获取数据;POST主要用来提交数据,即数据最终会实现数据库的数据变更
- 实现方式区别:GET可以使用URL、form表单和window.location来实现(本质还是URL),而POST只能通过form表单实现
- 执行效果区别:GET传值在提交时数据通常会在浏览器地址栏中显示,而POST不会显示(所以POST安全性比GET高)
- 传输大小区别:理论上来讲GET和POST没有区别(HTTP协议没有规定),但是浏览器通常在GET上做了限制,不同浏览器限制的大小不一样,IE为2K,而POST依然没有限制
PHP接收数据【掌握】
1.在PHP中,为开发者提供了三种数据接收的方式,分别是:
- $_GET:接收用户GET方式提交的数据
- $_POST:接收用户POST方式提交的数据
- $_REQUEST:接收用户GET和POST提交的数据
2.$_GET:专用于接收GET方式提交的数据,是一个超全局预定义数组,表单名字作为数组下标,表单值作为数组元素值
用户提交数据的HTML文件
<html>
<head></head>
<body>
<a href="http://www.taobao.com/index.php?keywords=笔记本&type=超极本">淘宝.笔记本.超极本</a>
</body>
</html>
服务器接收数据的index.php文件
<?php
//输出关键字和类型
echo $_GET['keywords']; //笔记本
echo $_GET['type']; //超极本
?>
3. P O S T : 专 用 于 接 收 P O S T 方 式 提 交 的 数 据 , 与 _POST:专用于接收POST方式提交的数据,与 POST:专用于接收POST方式提交的数据,与_GET形式一样
用户提交数据的HTML文件:用户输入笔记本和超极本数据提交
<html>
<head></head>
<body>
<form action="index.php" method="POST">
<input type="text" name="keywords" value=""/>
<input type="text" name="type" value=""/>
<input type="submit" value="检索"/>
</form>
</body>
</html>
服务器接收数据的index.php文件
<?php
//输出数据
echo $_POST['keywords']; //笔记本
echo $_GET['type']; //超极本
?>
4. R E Q U E S T : 接 收 用 户 使 用 G E T 和 P O S T 方 式 提 交 的 数 据 , 但 是 因 为 P H P 数 组 下 标 具 有 唯 一 性 , 如 果 G E T 和 P O S T 方 式 各 有 一 个 同 名 数 据 , 那 么 默 认 P O S T 会 覆 盖 G E T ( 通 常 不 会 同 时 出 现 G E T 和 P O S T ) , 也 正 是 因 为 会 存 在 数 据 覆 盖 的 情 况 , 所 以 开 发 人 员 通 常 会 明 确 到 底 是 G E T 还 是 P O S T , 只 是 在 有 的 数 据 来 源 可 能 有 多 方 面 的 时 候 会 使 用 _REQUEST:接收用户使用GET和POST方式提交的数据,但是因为PHP数组下标具有唯一性,如果GET和POST方式各有一个同名数据,那么默认POST会覆盖GET(通常不会同时出现GET和POST),也正是因为会存在数据覆盖的情况,所以开发人员通常会明确到底是GET还是POST,只是在有的数据来源可能有多方面的时候会使用 REQUEST:接收用户使用GET和POST方式提交的数据,但是因为PHP数组下标具有唯一性,如果GET和POST方式各有一个同名数据,那么默认POST会覆盖GET(通常不会同时出现GET和POST),也正是因为会存在数据覆盖的情况,所以开发人员通常会明确到底是GET还是POST,只是在有的数据来源可能有多方面的时候会使用_REQUEST
用户提交数据的HTML文件:用户输入笔记本和超极本数据提交
<html>
<head></head>
<body>
<form action="index.php?keywords=娃娃" method="POST">
<input type="text" name="keywords" value=""/>
<input type="text" name="type" value=""/>
<input type="submit" value="检索"/>
</form>
</body>
</html>
服务器接收数据的index.php文件
<?php
//输出数据:POST
echo $_POST['keywords']; //笔记本
echo $_POST['type']; //超极本
//输出数据:GET
echo $_GET['keywords']; //娃娃
echo $_GET['type']; //错误:没有该元素
//输出数据:REQUEST
echo $_REQUEST['keywords']; //笔记本
echo $_REQUEST['type']; //超极本
?>
5.练习:制作一个验证用户登录的简易表单,然后在后台实现数据的接收与验证(后台固定用户名和密码:密码MD5加密)
复合表单提交【掌握】
1.单选框操作:单选框即给用户提供多个选择,但是用户只能选择一个结果。即用户表单有多个,但是最终提交给服务器的永远只有一个。这类表单的处理方式比较简单:表单多个,但是名字一致,后台只需要接收一个结果。
单选框表单:一个名字,多个单选框表单
<html>
<head></head>
<body>
<form action="index.php" method="POST">
<input type="radio" name="gender" value="男"/>
<input type="radio" name="gender" value="女"/>
<input type="radio" name="gender" value="保密"/>
<input type="submit" value="提交"/>
</form>
</body>
</html>
服务器接收数据的index.php文件
<?php
//输出接收结果
echo $_POST['gender']; //用户选中的一个具体值
?>
2.复选框操作:复选框同样也是给定用户多个选中,而且用户也可以选中多个结果。这个时候就比较麻烦了,因为如果同名,PHP接收的时候会覆盖同名表单,那么最终后台只能保留一个用户选择。为了解决这个矛盾,就要利用HTML表单不识别[]而PHP会自动识别[]为数组的特性。
复选框表单:一个名字+[],多个复选框表单
<html>
<head></head>
<body>
<form action="index.php" method="POST">
<input type="checkbox" name="hobby[]" value="篮球"/>
<input type="checkbox" name="hobby[]" value="足球"/>
<input type="checkbox" name="hobby[]" value="台球"/>
<input type="checkbox" name="hobby[]" value="乒乓球"/>
<input type="checkbox" name="hobby[]" value="羽毛球"/>
<input type="checkbox" name="hobby[]" value="排球"/>
<input type="submit" value="提交"/>
</form>
</body>
</html>
服务器接收数据的index.php文件
<?php
//输出接收结果:$_POST接收到hobby[]变成$_POST[hobby[]],从而最终转变成$_POST[hobby][]
var_dump($_POST['hobby']); //array+具体元素个数
?>
3.数据回显:很多时候,会涉及到数据编辑,这个时候就需要将用户原来保存的数据在用户进行编辑前显示给用户。显示的方式通常也是以对应的复合表单方式显示。其实复合表单回显就是被选中,在HTML中提供了对应选中属性:checked=“checked”
<?php
//获取用户原来的数据:假定从数据库获取
$gender = '男';
$hobby = ['篮球','乒乓球','羽毛球'];
?>
<!--HTML中显示数据-->
<html>
<head></head>
<body>
<form action="index.php" method="POST">
<!--单选框后台只保留一个值,所以直接比较即可:成功后输出checked="checked"-->
<input type="radio" name="gender" <?php echo $gender == '男' ? 'checked="checked"' : '';?> value="男"/>
<input type="radio" name="gender" <?php echo $gender == '女' ? 'checked="checked"' : '';?> value="女"/>
<input type="radio" name="gender" <?php echo $gender == '保密' ? 'checked="checked"' : '';?> value="保密"/>
<!--复选框后台保留的是数组,所以要采用存在判定-->
<input type="checkbox" name="hobby[]" <?php echo in_array('篮球',$hobby) ? 'checked="checked"' : '';?> value="篮球"/>
<input type="checkbox" name="hobby[]" <?php echo in_array('篮球',$hobby) ? 'checked="checked"' : '';?> value="足球"/>
<input type="checkbox" name="hobby[]" <?php echo in_array('篮球',$hobby) ? 'checked="checked"' : '';?> value="台球"/>
<input type="checkbox" name="hobby[]" <?php echo in_array('篮球',$hobby) ? 'checked="checked"' : '';?> value="乒乓球"/>
<input type="checkbox" name="hobby[]" <?php echo in_array('篮球',$hobby) ? 'checked="checked"' : '';?> value="羽毛球"/>
<input type="checkbox" name="hobby[]" <?php echo in_array('篮球',$hobby) ? 'checked="checked"' : '';?> value="排球"/>
<input type="submit" value="提交修改"/>
</form>
</body>
</html>
4.练习:同时使用单选框和复选框制作一个用户基本信息收集表单,然后在后台接收数据并进行展示
文件上传操作【掌握】
1.制作文件上传表单:文件上传表单理论上只需要借助于input标签中的file类型来实现,且表单必须为post方式上传(文件通常比较大)。但是还有一个特殊问题,就是文件是二进制的不是普通字符流,所以需要明确告知HTTP协议使用到了文件上传,这时需要在表单form中使用属性enctype,enctype是关于表单内容处理的属性:
- enctype=‘application/x-www-form-urlencoded’,默认属性值,表示在发送前对所有特殊字符进行编码(对应ASCII)
- enctype=‘multipart/form-data’,表示不对数据进行编码(二进制不用编码)
- enctype=“text/plain”,只对空格进行转换,变成“+”,其他不编码
<html>
<head></head>
<body>
<form action="处理文件上传的PHP文件" method="POST" enctype="multipart/form-data">
<input type="file" name="file" value=""/>
<!--name属性为后台接收名字,value可以为空-->
<input type="submit" name="submit" value="上传"/>
</form>
</body>
</html>
2.PHP接收:默认的如果不使用enctype属性,那么文件上传是伪成功的:即PHP可以使用 P O S T 接 收 到 该 表 单 , 但 是 仅 仅 是 表 单 的 名 字 和 文 件 的 名 字 而 已 , 不 是 真 正 的 文 件 上 传 。 一 旦 加 上 e n c t y p e 属 性 , 可 以 使 用 _POST接收到该表单,但是仅仅是表单的名字和文件的名字而已,不是真正的文件上传。一旦加上enctype属性,可以使用 POST接收到该表单,但是仅仅是表单的名字和文件的名字而已,不是真正的文件上传。一旦加上enctype属性,可以使用_FILES来接收文件
<?php
//取出文件
$file = $_FILES['file']; //file下标为表单中name属性的值
?>
3.文件上传后,在PHP端会保存文件的5个信息
- name:文件在客户端本地的文件名字
- type:文件的类型(MIME类型:多功能互联网邮件扩展)
- tmp_name:文件在服务器端操作系统接收后保存的临时文件名字:默认是操作系统的临时文件存储目录(可以通过PHP配置文件修改)
- error:错误代码
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qNu2JGzx-1645578586617)(效果图/PHP文件上传错误代码描述.png “”)] - size:文件大小(字节)
4.文件是操作系统临时接收的,保存在临时文件中。PHP如果不处理,那么操作系统就会认为数据没有意义,自动清除。因此PHP需要将临时文件进行目标转移,转移到指定位置,使用函数:move_uploaded_file(临时文件路径,目标存储位置),目标存储位置需要重命名(默认临时文件名字为tmp)
<?php
//取出文件
$file = $_FILES['file'];
//简单判定
if($file['error'] == 0){
//移动文件
move_uploaded_file($file['tmp_name'],'目标位置目标文件');
}
?>
5.文件是一种外部来源数据,PHP要不信任任何外来数据。因此PHP在进行文件操作的时候一定要进行安全判定。而文件上传通常是一种比较统一形式的方式,因此可以采用封装函数来实现文件上传。
<?php
//封装上传文件的函数
//1.明确上传函数可能变换的内容:文件来源,文件保存位置,文件大小(业务规范),文件类型(MIME类型:后缀名可以改)。明确后作为参数传入
//2.明确要返回的结果:出错返回false,成功返回路径(错误信息通过参数外传)
function uploadFile($file,$save_path,&$error,$type = array(),$max = 2000000){
//默认类型不限定,默认大小为2M
//3.判定文件本身的错误信息
if(isset($file['error'])){
//确保是有效文件上传
switch($file['error']){
case 1:
$error = '文件超过服务器允许大小!';
return false; //直接使用return结束函数
case 2:
$error = '文件超过表单允许大小!';
return false;
case 3:
$error = '文件只上传一部分!';
return false;
case 4:
$error = '没有选中要上传的文件!';
return false;
case 6:
case 7:
//case 6没有内容,表明继续执行case 7代码
$error = '服务器操作失败!';
return false;
}
}
//4.判断文件业务需求:类型匹配
if(!empty($type) && !in_array($file['type'],$type)){
//类型需求不为空且当前文档类型不在需求中:不满足条件
$error = '当前文件的类型不匹配';
return false;
}
//5.判断文件业务需求:大小匹配(当前业务文件大小)
if($file['size'] > $max){
$error = '当前文件过大!';
return false;
}
//6.没有问题上传文件:保存判定(权限问题)
if(move_uploaded_file($file['tmp_name'],$save_path . '/' . $file['name'])){
//保存成功:返回最终名字
return $file['name'];
}else{
//保存失败
$error = '文件保存失败!';
return false;
}
}
?>
6.练习:封装文件上传函数,然后利用文件上传函数实现文件上传
多文件上传【掌握】
1.多文件上传根据上传文件的方式有两种分别:
- 有多处需要文件上传,而每个文件之间没有什么关联,这类的本质依然单文件上传
<html>
<head></head>
<body>
<form action="处理文件上传的PHP文件" method="POST" enctype="multipart/form-data">
头像:<input type="file" name="head_img" value=""/>
身份证正面照:<input type="file" name="id_img1" value=""/>
身份证反面照:<input type="file" name="id_img2" value=""/>
<input type="submit" name="submit" value="上传"/>
</form>
</body>
</html>
- 在同一个地方需要有多个文件上传,多个文件属于同一类文件,需要共同管理:这类表单利用的与复选框命名方式类似
<html>
<head></head>
<body>
<form action="处理文件上传的PHP文件" method="POST" enctype="multipart/form-data">
个人相册:
<input type="file" name="photo[]" value=""/>
<input type="file" name="photo[]" value=""/>
<input type="file" name="photo[]" value=""/>
<input type="submit" name="submit" value="上传"/>
</form>
</body>
</html>
2.多文件后台PHP处理
- 对于多个单文件上传,后台可以直接利用已经封装好的文件上传函数多次调用即可
<?php
//循环调用函数:因为一个文件就会在$_FILES中形成一个元素
foreach($_FILES as $file){
//$file就是每一个元素:对应一个上传文件的5要素
$res = uploadFile($file,'文件保存路径',$error);
if($res === false){
//上传失败
exit($error);
}
//提升上传成功
echo "文件:" . $file['name'] . ' 上传成功!';
}
?>
- 对于同名多文件上传,那么$_FILES接收的数据是生成5个元素的二维数组,因此需要将每个文件的5个要素取出来独立成一个文件信息,然后使用单文件上传即可。
<?php
//通过任意一个要素长度来进行循环
for($i = 0,$len = count($_FILES['photo']['error']);$i < $len;$i++){
//因为同名元素长传,导致的结果是error\name\size\tmp_name\type都各自形成一个索引数组
//构造每个文件信息:关联数组
$file = array(
'name' => $_FILES['photo']['name'][$i],
'type' => $_FILES['photo']['type'][$i],
'tmp_name' => $_FILES['photo']['tmp_name'][$i],
'error' => $_FILES['photo']['error'][$i],
'size' => $_FILES['photo']['size'][$i]
);
//调用文件上传
uploadFile($file,'文件上传路径',$error);
}
?>
3.练习:制作一个单文件上传函数,也制作一个多文件上传函数,使用多文件上传函数调用单文件函数上传,最终实现多文件上传。