php上传文件问题汇总
1.先做个最简单的上传文件
<html> <head> <metahttp-equiv="Content-Type"content="text/html;charset=utf-8"> </head> <body> <formaction="upload_file.php"method="post" enctype="multipart/form-data"> <labelfor="file">Filename:</label> <inputtype="file"name="file"id="file"/> <br/> <inputtype="submit"name="submit"value="Submit"/> </form> </body> </html>
<?php if(($_FILES["file"]["size"]<20000) { if($_FILES["file"]["error"]>0) { echo"ReturnCode:".$_FILES["file"]["error"]."<br/>"; } else { echo"Upload:".$_FILES["file"]["name"]."<br/>"; echo"Type:".$_FILES["file"]["type"]."<br/>"; echo"Size:".($_FILES["file"]["size"]/1024)."Kb<br/>"; echo"Tempfile:".$_FILES["file"]["tmp_name"]."<br/>"; if(file_exists("upload/".$_FILES["file"]["name"])) { echo$_FILES["file"]["name"]."alreadyexists."; } else { move_uploaded_file($_FILES["file"]["tmp_name"], "upload/".$_FILES["file"]["name"]); echo"Storedin:"."upload/".$_FILES["file"]["name"]; } } } else { echo"Invalidfile"; } ?>
2.然后了解超级全局变量$_FILES的值
$_FILES['userfile']['name'] $_FILES['userfile']['type'] $_FILES['userfile']['size'] $_FILES['userfile']['tmp_name'] $_FILES['userfile']['error']
其中,$_FILES['userfile']['error']的所有值:
UPLOAD_ERR_OK其值为0,没有错误发生,文件上传成功。
UPLOAD_ERR_INI_SIZE其值为1,上传的文件超过了php.ini中upload_max_filesize选项限制的值。
UPLOAD_ERR_FORM_SIZE其值为2,上传文件的大小超过了HTML表单中MAX_FILE_SIZE选项指定的值。
UPLOAD_ERR_PARTIAL其值为3,文件只有部分被上传。
UPLOAD_ERR_NO_FILE其值为4,没有文件被上传。
UPLOAD_ERR_NO_TMP_DIR其值为6,找不到临时文件夹。PHP4.3.10和PHP5.0.3引进。
UPLOAD_ERR_CANT_WRITE其值为7,文件写入失败。PHP5.1.0引进。
3.很多情况:需要严格判断上传文件类型
我们知道使用$_FILES['userfile']['type']判断上传文件类型是一个很不明智的做法,因为该判断依据是文件的后缀名,任何人都可以将一个mp3文件的后缀改成jpg从而伪装成图片进行上传,因此php官方建议使用php的扩展php_fileinfo来判断文件的mime,开启拓展的方法百度一下有很多,win和linux略有不同。
4.情景一:上传文件重名后自动重命名
if(file_exists("./upload/".$_FILES["file"]["name"])) { do{ $suffix=""; $suffix_length=4; $str="0123456789abcdefghijklmnopqrstuvwxyz"; $len=strlen($str)-1; //文件名后追加4个随机字符 for($i=0;$i<$suffix_length;$i++){ $suffix.=$str[rand(0,$len)]; } $upload_filename=$_FILES['file']['name']; $filename=substr($upload_filename,0,strrpos($upload_filename,".")).$suffix.".".substr($upload_filename,strrpos($_FILES["file"]["name"],".")+1); }while(file_exists("./upload/".$filename)); move_uploaded_file($_FILES["file"]["tmp_name"],"./upload/".$filename); }else{ move_uploaded_file($_FILES["file"]["tmp_name"],"upload/".$_FILES["file"]["name"]); }
5.情景二:根据日期分目录上传文件
$structure='./'.date("Y").'/'.date("m").'/'.date("d").'/'; if(!mkdir($structure,0777,true)){ die('Failedtocreatefolders...'); } move_uploaded_file($_FILES["file"]["tmp_name"],$structure.$_FILES["file"]["name"]);
6.情景三:多文件上传
<formaction=""method="post"enctype="multipart/form-data"> <p>Pictures: <inputtype="file"name="pictures[]"/> <inputtype="file"name="pictures[]"/> <inputtype="file"name="pictures[]"/> <inputtype="submit"value="Send"/> </p> </form>
<?php foreach($_FILES["pictures"]["error"]as$key=>$error){ if($error==UPLOAD_ERR_OK){ $tmp_name=$_FILES["pictures"]["tmp_name"][$key]; $name=$_FILES["pictures"]["name"][$key]; move_uploaded_file($tmp_name,"data/$name"); } } ?>
有的情况下多文件的这种变量结构并不好用:
array(1){ ["upload"]=>array(2){ ["name"]=>array(2){ [0]=>string(9)"file0.txt" [1]=>string(9)"file1.txt" } ["type"]=>array(2){ [0]=>string(10)"text/plain" [1]=>string(10)"text/html" } } }
很多情况下我们需要的是类似这样的结构
array(1){ ["upload"]=>array(2){ [0]=>array(2){ ["name"]=>string(9)"file0.txt" ["type"]=>string(10)"text/plain" }, [1]=>array(2){ ["name"]=>string(9)"file1.txt" ["type"]=>string(10)"text/html" } } }
使用下面的函数就能轻松转化结构
functiondiverse_array($vector){ $result=array(); foreach($vectoras$key1=>$value1) foreach($value1as$key2=>$value2) $result[$key2][$key1]=$value2; return$result; } $upload=diverse_array($_FILES["upload"]);
7.有的时候:需要配置服务器修改最大上传文件大小
首先,在表单上
<inputtype="hidden"name="MAX_FILE_SIZE"value="字节"/>
可以限制上传文件大小(可以被绕过)。
然后在服务器上也需要调整一下配置
php.ini:
max_execution_time=30每个脚本运行的最长时间,单位秒 max_input_time=60,每个脚本可以消耗的时间,单位也是秒 memory_limit=128M,这个是脚本运行最大消耗的内存 post_max_size=8M,表单提交最大数据为8M,此项不是限制上传单个文件的大小,而是针对整个表单的提交数据进行限制的。 upload_max_filesize=2M,上载文件的最大许可大小
nginx:
location/{ root html; index index.htmlindex.htm; client_max_body_size 1000m; }
暂时先总结这些吧,希望小伙伴们能够喜欢。