设为首页收藏本站 |天气与日历| 2025-07-02 星期三 05:34:00 乙巳(蛇)年 六月初八 卯时
     
切换到窄版

私人站点

 找回密码
 立即注册
搜索
查看: 129|回复: 0

文件上传

[复制链接]

954

主题

954

帖子

3879

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3879
发表于 2022-6-8 22:55:11 | 显示全部楼层 |阅读模式
客户端上传文件
[PHP] 纯文本查看 复制代码
<input type="file" name="image">

表单的enctype属性
​        默认情况下,表单传递是字符流,不能传递二进制流,通过设置表单的enctype属性传递复合数据。
enctype属性的值有:
  • application/x-www-form-urlencoded:【默认】,表示传递的是带格式的文本数据。
  • multipart/form-data:复合的表单数据(字符串,文件),文件上传必须设置此值
  • text/plain:用于向服务器传递无格式的文本数据,主要用户电子邮件

multipart:复合

form-data:表单数组



服务器接受文件


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


1、$_FILES[][‘name’]:上传的文件名


2、$_FILES[][‘type]:上传的类型,这个类型是MIME类型(image/jpeg、image/gif、image/png)


3、$_FILES[][‘size’]:文件的大小,以字节为单位


4、$_FILES[][‘tmp_name’]:文件上传时的临时文件


5、$_FILES[][‘error’]:错误编码(值有0、1、2、3、4、6、7)0表示正确


  • 错误描述
  • 0
  • 正确
  • 1
  • 文件大小超过了php.ini中允许的最大值    upload_max_filesize = 2M
  • 2
  • 文件大小超过了表单允许的最大值
  • 3
  • 只有部分文件上传
  • 4
  • 没有文件上传
  • 6
  • 找不到临时文件
  • 7
  • 文件写入失败


注意:MAX_FILE_SIZE必须在文件域的上面。
只要掌握的错误号:0和4


将上传文件移动到指定位置
[PHP] 纯文本查看 复制代码
<body>
<?php
if(!empty($_POST)) {
	if($_FILES['face']['error']==0){  //上传正确
        //文件上传
		move_uploaded_file($_FILES['face']['tmp_name'],'./'.$_FILES['face']['name']);
	}else{
		echo '上传有误';
		echo '错误码:'.$_FILES['face']['error'];
	}
}
?>
<form method="post" action="" enctype='multipart/form-data'>
	<input type="file" name="face">
	<input type="submit" name="button" value="上传">
</form>
</body>







与文件上传有关的配置
post_max_size = 8M:表单允许的最大值
upload_max_filesize = 2M:允许上传的文件大小
upload_tmp_dir =F:\wamp\tmp:指定临时文件地址,如果不知道操作系统指定
file_uploads = On:是否允许文件上传
max_file_uploads = 20:允许同时上传20个文件


优化文件上传更改文件名方法一:通过时间戳做文件名
[PHP] 纯文本查看 复制代码
<?php
$path='face.stu.jpg';
//echo strrchr($path,'.');	//从最后一个点开始截取,一直截取到最后
echo time().rand(100,999).strrchr($path,'.');   



方法二:通过uniqid()实现
[PHP] 纯文本查看 复制代码
$path='face.stu.jpg';
echo uniqid().strrchr($path,'.'),'<br>';   //生成唯一的ID
echo uniqid('goods_').strrchr($path,'.'),'<br>';   //带有前缀
echo uniqid('goods_',true).strrchr($path,'.'),'<br>';  //唯一ID+随机数





验证文件格式
方法一:判断文件的扩展名(不能识别文件伪装)
操作思路:将文件的后缀和允许的后缀对比
[PHP] 纯文本查看 复制代码
<body>
<?php
if(!empty($_POST)) {
	$allow=array('.jpg','.png','.gif');	//允许的扩展名
	$ext=strrchr($_FILES['face']['name'],'.');  //上传文件扩展名
	if(in_array($ext,$allow))
		echo '允许上传';
	else
		echo '文件不合法';
}
?>
<form method="post" action="" enctype='multipart/form-data'>
	<input type="file" name="face">
	<input type="submit" name="button" value="上传">
</form>
</body>

注意:比较扩展名不能防止文件伪装。
方法二:通过$_FIELS[]['type']类型(不能识别文件伪装)


[PHP] 纯文本查看 复制代码
<body>
<?php
if(!empty($_POST)) {
	$allow=array('image/jpeg','image/png','image/gif');	//允许的类别
	$mime=$_FILES['face']['type'];  //上传文件类型
	if(in_array($mime,$allow))
		echo '允许上传';
	else
		echo '文件不合法';
}
?>
<form method="post" action="" enctype='multipart/form-data'>
	<input type="file" name="face">
	<input type="submit" name="button" value="上传">
</form>
</body>

注意:比较$_FIELS[]['type']不能防止文件伪装。




方法三:php_fileinfo扩展(可以防止文件伪装)
​        在php.ini中开启fileinfo扩展
[PHP] 纯文本查看 复制代码
extension=php_fileinfo.dll
注意:开启fileinfo扩展以后,就可以使用finfo_*的函数了
[PHP] 纯文本查看 复制代码
<body>
<?php
if(!empty($_POST)) {
	//第一步:创建finfo资源
	$info=finfo_open(FILEINFO_MIME_TYPE);
	//var_dump($info);		//resource(2) of type (file_info) 
	//第二步:将finfo资源和文件做比较
	$mime=finfo_file($info,$_FILES['face']['tmp_name']);
	//第三步,比较是否合法
	$allow=array('image/jpeg','image/png','image/gif');	//允许的类别
	echo in_array($mime,$allow)?'合法':'不合法';
}
?>
<form method="post" action="" enctype='multipart/form-data'>
	<input type="file" name="face">
	<input type="submit" name="button" value="上传">
</form>
</body>
小结:验证文件格式有三种方法
1、可以验证扩展名(不可以防止文件伪装)
2、通过$_FILES[]['type']验证(不可以防止文件伪装)
3、通过file_info扩展(可以防止文件伪装)





优化文件上传例题
步骤
第一步:验证是否有误
第二步:验证格式
第三步:验证大小
第四步:验证是否是http上传
第五步:上传实现
[PHP] 纯文本查看 复制代码
<body>
<?php
/**
*验证错误
*如果有错,就返回错误,如果没错,就返回null
*/
function check($file) {
	//1:验证是否有误
	if($file['error']!=0){
		switch($file['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']);
	$allow=array('image/jpeg','image/png','image/gif');	//允许的类别
	if(!in_array($mime,$allow)){
		return '只能上传'.implode(',',$allow).'格式';
	}
	//3、验证大小
	$size=123456789;
	if($file['size']>$size){
		return '文件大小不能超过'.number_format($size/1024,1).'K';
	}
	//4、验证是否是http上传
	if(!is_uploaded_file($file['tmp_name']))
		return '文件不是HTTP POST上传的<br>';

	return null;  //没有错误
}

//表单提交
if(!empty($_POST)) {
	//上传文件过程中有错误就显示错误
	if($error=check($_FILES['face'])){
		echo $error;
	}else{
		//文件上传,上传的文件保存到当天的文件夹中
		$foldername=date('Y-m-d');		//文件夹名称
		$folderpath="./uploads/{$foldername}";	//文件夹路径
		if(!is_dir($folderpath))
			mkdir($folderpath);
		$filename=uniqid('',true).strrchr($_FILES['face']['name'],'.');	//文件名
		$filepath="$folderpath/$filename";	//文件路径
		if(move_uploaded_file($_FILES['face']['tmp_name'],$filepath))
			echo "上传成功,路径是:{$foldername}/{$filename}";
		else
			echo '上传失败<br>';
	}

}
?>
<form method="post" action="" enctype='multipart/form-data'>
	<input type="file" name="face">
	<input type="submit" name="button" value="上传">
</form>
</body>





















回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|编程站点 ( 冀ICP备2023028127号-2 )|友链申请|

GMT+8, 2025-7-2 05:34 , Processed in 0.093401 second(s), 22 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表