1、表单传值
表单传值就是浏览器通过表单元素,将数据传给后台服务器语言
1.1表单传值方式
1)GET传值
- form表单
< form method=“GET” >表单元素 < / form > - a标签
< a href=“www.itcast.cn/index.php?学科=PHP” >//这样就把“学科”字符串传值给PHP文件了 - location对象的href属性
< script>location.href=“www.itcast.cn/index.php?data=PHP”< / script> - location对象的assign()方法
< script>location.assign(“www.itcast.cn/index.php?data=PHP”)< /script>
2)POST传值
- post表单方式的基本设定
< form method=“POST”>表单元素< /form>
3)post方式跟get方式的区别
- GET传输的数据主要用来获取数据,不改变服务器上资源:get只是用来获取内容
- Post传输的数据主要用来增加数据,改变服务器上资源:POST会改变服务器上数据内容
- 传输方式上post必须使用form表单,而get可以使用form表单和URL
- get传输数据可以在URL中对外可见,而post不可见:GET传值最终会在浏览器的地址栏中全部显示:?数据名=数据值&数据名2=数据值2…
- get和post能传输的数据大小不同,get为2K,post理论无限制(事实上,GET和POST本身没有数据长度限制,但是浏览器厂家做了一些限制)
- 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文件上传功能封装函数!!!!(综合训练)
- 目标:实现上传功能代码的重复利用:封装文件上传函数
- 功能:上传文件
- 条件:条件判断
- 文件类型是否合适?外部指定MIME类型(MIME类型为支持HTML上传的类型)
- 文件存储到什么位置?外部指定
- 文件格式限制(文件后缀)?外部限定
- 文件大小限制?外部指定
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;
}
?>