27岁,山西运城人,职业电商经理人,前端开发工作者,从事过网站建设、网络推广、SEO、SEM、信息流推广、二类电商、网络运维、软件开发,等相关电商工作,经验较为丰富,小米技术社区致力于为广大从事Web前端开发的人员提供一些力所能及的引导和帮助 ...[更多]
E-mail:mzze@163.com
Q Q:32362389
W X:xiaomi168527
27岁,山西运城人,职业电商经理人,网络工程师兼运维,从事过运营商网络建设,企业网络建设、优化。数据中心网络维护等通过,经验丰富,座右铭:当自己休息的时候,别忘了别人还在奔跑。 ...[更多]
大于花一样的年龄,河南郑州是我家,2010年在北京接触团购网,2011年进入天猫淘宝一待就是四年,如今已经将设计走向国际化(ps:误打误撞开始进入阿里巴巴国际站的设计,嘿嘿)五年电商设计,丰富经验,从事过天猫淘宝阿里各项设计,店铺运营,产品拍摄;我将我的经历与您分享是我的快乐!座右铭:越努力越幸运! ...[更多]
E-mail:97157726@qq.com
Q Q:97157726
开发中需要上传图片、音乐、视频等等,这种上传传递是二进制数据。
HTML文件域
<input type="file" name="image" enctype="multipart/form-data"> //enctype="multipart/form-data" 必须设置
默认情况下,表单传递是字符流,不能传递二进制流,通过设置表单的enctype属性传递复合数据。
enctype属性的值有:
1. application/x-www-form-urlencoded:【默认】,表示传递的是带格式的文本数据。
2. multipart/form-data:复合的表单数据(字符串,文件),文件上传必须设置此值
3. text/plain:用于向服务器传递无格式的文本数据,主要用户电子邮件
相关单词
multipart:复合
form-data:表单数组
服务器文件的接收需要写了解$_FILES超全局变量
超全局变量$_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表示正确
$_FILES[][error]的详解:
注意:没有5
值 | 错误描述 |
0 | 正确 |
1 | 文件大小超过了php.ini中允许的最大值 upload_max_filesize = 2M |
2 | 文件大小超过了表单允许的最大值 |
3 | 只有部分文件上传 |
4 | 没有文件上传 |
6 | 找不到临时文件 |
7 | 文件写入失败 |
重点掌握的错误号:0和4
注意:值2的意思是下图;MAX_FILE_SIZE必须在文件域的上面。
move_uploaded_file(临时地址,目标地址)
注意:上传的同名的文件会覆盖
<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>
与文件上传有关的php.ini配置
post_max_size = 8M:表单允许的最大值 upload_max_filesize = 2M:允许上传的文件大小 upload_tmp_dir =F:\wamp\tmp:指定临时文件地址,如果不知道操作系统指定 file_uploads = On:是否允许文件上传 max_file_uploads = 20:允许同时上传20个文件
方法一:通过时间戳做文件名
<?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+随机数
方法一:判断文件的扩展名(但是不能识别文件伪装)
操作思路:将文件的后缀和允许的后缀对比
<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扩展(可以防止文件伪装,推荐)
优化文件上传
步骤
第一步:验证是否有误
第二步:验证格式
第三步:验证大小
第四步:验证是否是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、使用date需要在php.ini设置时区;默认是东1区,设置成为PRC,即为东八区
3、PHP的执行可以不需要Apache的参与
本站内容均为小米原创,转载请注明出处:小米技术社区>> PHP文件编程--文件的上传和服务器的接收