PHP核心编程(表单传值)
表单传值的方式
表单传值的方式有两种:get、post
从地址栏外观上来说
- 带有问号是get【默认】
- 不带有问号的是post
脚下留心:如果表单不指定传递方法,默认是get提交
从提交的数据大小来说
- 提交少量数据,不同的浏览器最大值不一样,IE是2K
- 提交大量数据,可以在php.ini中post_max_size来更改传递数据的最大值
从安全性来说
- get安全性低
- post安全性高
从提交的原理上来说
- get提交的数据和数据之间是独立的
- post提交的数据转成XML格式一起提交,将所有的数据作为一个整体。
灵活性
- get提交很灵活,只要有页面的跳转就可以传递数据
- post数据不灵活,必须要有表单的参与【ajax中post提交除外】
脚下留心:在项目中,get提交使用的频率高,因为get很灵活。
接受数据的三种方式
1、$_GET:数组,保存get提交的数据
2、$_POST:数组,保存post提交的数据
3、$_REQUEST:数组,保存get和post提交的数据
传递复选框数据
文件上传
文件上传在项目中用的很多,比如上传照片,视频,音频等等。
表单的enctype属性
- application/x-www-form-urlencoded:这是一个默认值,主要用于文本数据的传递,用来向服务器发送文本。
- multipart/form-data:告知浏览器表单中有复合的数据(字符串,二进制)。
- text/plain:用来向服务器发送大量文本,该方式主要应用于做电子邮件。
脚下留心:要传递数据,表单的enctype属性必须选择multipart/form-data
文件域
$_FILES
超全局变量$_FILES是一个二维数组,该数组用来保存上传到服务器的文件,行是文件域的名称,列有5个。
1、$_FILES[][‘name’]:文件名称
2、$_FILES[][‘type]:文件的类型,MIME类型
3、$_FILES[][‘tmp_name]:文件上传的临时文件
4、$_FILES[][‘error]:上传的错误号,0表示没有错误
5、$_FILES[][‘size’]:文件大小,单位是字节
详解$_FILES[][‘type]
$_FILES[][‘type]返回的是MIME类型的格式,这种格式的组成是“类别/格式”比如“image/png”,“text/html”。
application/msword:.doc文件
application/vnd.openxmlformats-officedocument.wordprocessingml.document:docx后缀
text/plain:记事本
详解$_FILES[][‘tmp_name]
文件在上传的时候临时文件地址
可以在php.ini中通过upload_tmp_dir指定临时目录的地址
如果不指定,临时地址由操作系统决定
与上传有关的配置
- upload_tmp_dir:文件上传的临时地址
- post_max_size=8M:post提交的最大值,默认是8M
- upload_max_filesize=2M:上传文件的最大值是2M
- file_uploads=on:是否允许文件上传
- max_file_uploads=20:最多可以上传的文件个数
详解$_FILES[][‘error’]
$_FILES[][‘error’]表示文件上传的错误代码,取值有0,1,2,3,4,6,7,非零表示有错误。
0:正确
1:文件大小超出了php.ini中upload_max_filesize允许的最大值。
2:文件大小超出了表单允许的最大值
3:只有部分文件上传
4:没有文件上传,上传的文件为空
6:找不到临时文件
7:文件写入失败(从临时目录向目标目录移动的时候失败了)
补充:隐藏域
语法:<input type=”hidden” value=”” />
隐藏域也是表单元素的一种,在浏览器上不会显示,
应用:用来向服务器提交数据,并且此数据不需要显示在浏览器上。
move_uploaded_file
例题
<?php
if(!empty($_POST)){
if($_FILES[‘img’][‘error’]==0){
$tmp=$_FILES[‘img’][‘tmp_name’]; //文件临时地址
$dest=’./Uploads/’.iconv(‘utf-8′,’gb2312’,$_FILES[‘img’][‘name’]); //目标地址
if(move_uploaded_file($tmp,$dest)) //文件上传
echo ‘成功’;
else
echo ‘失败’;
}else{
echo $_FILES[‘img’][‘error’];
echo ‘文件上传失败’;
}
}
?>
<form action=”” method=”post” enctype=”multipart/form-data”>
<input type=”file” name=”img” />
<input type=”submit” name=”btn” value=”上传” />
</form>
多学一招:iconv()函数用于字符编码的转换。
验证文件的类型
方法一:通过文件的MIME类型验证
<?php
if(isset($_POST[‘btn’])) {
//只有jpg,gif,png可以上传 image/jpeg,image/gif,image/png
$allow=array(‘image/jpeg’,’image/png’,’image/gif’);//mime类型
if(in_array($_FILES[‘img’][‘type’],$allow)){
$tmp=$_FILES[‘img’][‘tmp_name’]; //临时文件路径
$dst=’./Uploads/’.$_FILES[‘img’][‘name’];//目标地址
echo move_uploaded_file($tmp,$dst)?’上传成功’:’上传失败’;
}else{
echo $_FILES[‘img’][‘type’].’为非法类型’;
}
}
?>
<form action=”” method=”post” enctype=”multipart/form-data”>
<input type=”file” name=”img” />
<input type=”submit” name=”btn” value=”上传” />
</form>
方法二:通过验证文件的后缀来判断文件
<?php
//$path=’aa.bb.cc.JPG’; //文件名
//echo strrchr($path,’.’); //获取文件扩展名
if(isset($_POST[‘btn’])) {
$allow=array(‘.jpg’,’.jpeg’,’.gif’,’.png’); //允许的文件扩展名
$ext=strtolower(strrchr($_FILES[‘img’][‘name’],’.’)); //上传文件小写扩展名
if(in_array($ext,$allow))
echo ‘合法’;
else
echo ‘非法’;
}
?>
脚下留心:方法一和方法二不能识别文件伪装。
方法三:通过php_fileinfo扩展来验证文件类型,此方法做严格检查。
fileinfo扩展可以防止文件伪装
要使用fileinfo扩展必须在php.ini中开启此扩展
重启服务器。
例题
完整例题
if(isset($_POST[‘btn’])) {
//第一步:创建fileinfo资源
$finfo=finfo_open(FILEINFO_MIME); //创建了一个资源
//第二步:将上传的文件与创建的资源做比较
$info=finfo_file($finfo,$_FILES[‘img’][‘tmp_name’]); //返回文件信息
//第三步:分析返回的结果
$allow=array(‘image/jpeg’,’image/png’,’image/gif’);//允许mime类型
$array=explode(‘;’,$info);
echo in_array($array[0],$allow)?’合法’:’非法’;
}
生成唯一文件名
在文件上传的过程中,后面的文件将前面的同名文件覆盖。解决方案给每个文件取一个唯一的文件名。
方法一:用时间戳做文件名
时间戳:从1970年1月1日0时0分0秒到现在的秒数(或毫秒数)
例题
方法二:通过uniqid()函数 — 生成一个唯一ID
例题
优化文件上传例题
<?php
if(isset($_POST[‘btn’])) {
$error=$_FILES[‘img’][‘error’]; //获取上传错误码
//文件上传有误
if($error!==0){
switch($error) {
case 1:
echo ‘上传文件超出了PHP允许的最大值’;
break;
case 2:
echo ‘上传文件超出了表单允许的最大值’;
break;
case 3:
echo ‘只有部分文件上传’;
break;
case 4:
echo ‘上传文件为空’;
break;
case 6:
echo ‘找不到临时文件’;
break;
case 7:
echo ‘文件写入失败’;
break;
default:
echo ‘未知错误’;
}
exit;
}
//验证格式
$allow=array(‘image/jpeg’,’image/png’,’image/gif’); //允许文件类型
$finfo=finfo_open(FILEINFO_MIME); //创建了一个资源
$info=finfo_file($finfo,$_FILES[‘img’][‘tmp_name’]);//返回文件信息
$array=explode(‘;’,$info);
if(!in_array($array[0],$allow))
die(‘文件非法,只允许’.implode(‘,’,$allow));
//验证文件大小
if($_FILES[‘img’][‘size’]>1024*1024){
die(‘文件不能大于1M’);
}
//验证上传文件是否是http上传
if(!is_uploaded_file($_FILES[‘img’][‘tmp_name’])){ //判断文件是否是通过 HTTP POST 上传的
die(‘文件必须是http文件上传’);
}
//文件上传
$dest=’./uploads/’.uniqid(”,true).strrchr($_FILES[‘img’][‘name’],’.’);
echo move_uploaded_file($_FILES[‘img’][‘tmp_name’],$dest)?’上传成功’:’上传失败’;
}
?>
<form action=”” method=”post” enctype=”multipart/form-data”>
<input type=”file” name=”img” />
<input type=”submit” name=”btn” value=”上传” />
</form>
多文件上传
例题
<?php
if(isset($_POST[‘btn’])) {
//var_dump($_FILES); //三维数组
foreach($_FILES[‘img’][‘name’] as $k=>$v) {
$dest=’./Uploads/’.uniqid(”,true).strrchr($v,’.’); //目标文件
echo move_uploaded_file($_FILES[‘img’][‘tmp_name’][$k],$dest)?’成功’:’失败’;
}
}
?>
<form action=”” method=”post” enctype=”multipart/form-data”>
<input type=”file” name=”img[]” /><br>
<input type=”file” name=”img[]” /><br>
<input type=”file” name=”img[]” /><br>
<input type=”submit” name=”btn” value=”上传” />
</form>