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的參與