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的参与
