PHP-文件上传优化

  • 2020 年 3 月 26 日
  • 笔记

1.7 优化文件上传

1.7.1 更改文件名

方法一:通过时间戳做文件名

<?php  $path='face.stu.jpg';  //echo strrchr($path,'.');	//从最后一个点开始截取,一直截取到最后  echo time().rand(100,999).strrchr($path,'.');   

方法二:通过uniqid()实现

$path='face.stu.jpg';  echo uniqid().strrchr($path,'.'),'<br>';   //生成唯一的ID  echo uniqid('goods_').strrchr($path,'.'),'<br>';   //带有前缀  echo uniqid('goods_',true).strrchr($path,'.'),'<br>';  //唯一ID+随机数

1.7.2 验证文件格式

方法一:判断文件的扩展名(不能识别文件伪装)

操作思路:将文件的后缀和允许的后缀对比

<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']类型(不能识别文件伪装)

<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扩展

extension=php_fileinfo.dll

注意:开启fileinfo扩展以后,就可以使用finfo_*的函数了

<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扩展(可以防止文件伪装)

1.7.3 优化文件上传例题

步骤

第一步:验证是否有误

第二步:验证格式

第三步:验证大小

第四步:验证是否是http上传

第五步:上传实现

<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>

运行结果

小结:

1、将时间戳转换格式

echo date('Y-m-d H:i:s',1231346),'<br>';		//将时间戳转成年-月-日 小时:分钟:秒  echo date('Y-m-d H:i:s'),'<br>';	//将当前的时间转成年-月-日 小时:分钟:秒

2、设置时区(php.ini)

PRC:中华人民共和国

3、PHP的执行可以不需要Apache的参与