php文件上传

文件上传是通过html表单来上传,表单的格式如下:
<code lang="html">
<form method="post" action="upload.php" enctype="multipart/form-data">
    <input type="file" name="upfiles"/><br/>
    文件名:<input type="text" /><br/>
    <input type="submit" value="上传文件"/>
</form>
</code>
其中,表单的方法只能用post去上传,而不能用get方法,其次,在发送到服务器之前不能对表单内容进行编码,所以要加入enctype,并且赋值为multipart/form-data。
然后,加入上传文件的输入框和提交按钮,最简单的上传文件表单就做好了,接下来便是对上传文件的响应操作了。
上传文件时,要分这么几步去走:
1.判断是否有错误码。文件能否上传成功和很多因素有关,而我们可以根据系统返回的错误码来进行相应的操作。
2.判断文件大小是否超出范围。php.ini会规定文件默认的上传最大值,而我们可以自己去设置它,这个最大值是我们的业务最大值。
3.判断后缀名是否与mime类型符合,有时候我们会要指定的类型的文件,比如如果我们要上传图片的话,我们就需要.jpg\.png等格式,而如果不是这个格式的文件,上传的文件就没有意义。
4.生成文件名。文件上传成功后,有时候我们不想文件名与原来相同,我们可以去设置它的文件名。比如我们一般用时间加上一些文件主要信息去命名文件,所以我们可以使用date()函数去获取时间,或者我们也可以生成随机文件,比如用mt_rand()函数或者unique()函数。
5.判断是否是上传文件,文件上传成功后,系统会将上传的临时文件上传到系统的临时目录中。产生一个临时文件,而我们要将临时文件移动到我们想要的地方以便我们去操作它,而在一个目录下,有很多文件,如何判断文件是不是我们想进行操作的文件呢??这个时候就需要用到is_upload_file()函数,来判断是否是上传文件。
6.移动临时文件到指定位置,当判断好一切错误后,便可以将临时文件移动到指定位置了。移动文件的函数是move_uploaded_file()函数。
下面是移动文件的代码:
<code lang="php">
$upfiles = $_FILES["upfiles"];
$name = $upfiles["name"];
$tmp_name = $upfiles["tmp_name"]; //文件暂时存放路径
echo $tmp_name;
move_uploaded_file($tmp_name,"F:\\$name");//将文件从暂时存放路径移动至想要移动到的路径。
</code>
其中$_FILES是一个环境变量,当客户端提交之后,会获得一个$_FILES数组,数组里面默认有一下几个值,
array(1) {
 ["upfiles"]=> array(5) {
     ["name"]=> string(0) ""
     ["type"]=> string(0) "" 
     ["tmp_name"]=> string(0) "" 
     ["error"]=> int(4) 
     ["size"]=> int(0) 
    } 
},其中由于文件有多个,所以在输入框里的name,便是上传文件。而文件名则是["upfiles"]["name"],依次类推。
然后是多文件的上传了,多文件上传和单文件没有太大差别,以下是代码。
<code lang="html">
<form action="upload.php" enctype="multipart/form-data" method="post" name="uploadfile">
    上传文件:<input type="file" name="upfile[]" /><br>
    上传文件:<input type="file" name="upfile[]" /><br>
    上传文件:<input type="file" name="upfile[]" /><br>
    上传文件:<input type="file" name="upfile[]" /><br>
    <input type="submit" value="上传" /></form>
</code>
可以看出,和单文件上传比,name后面多了一个[],这就是多文件的上传了,然后通过$_FILES打印出来后,是如下的数组
array(1) {
 ["upfile"]=> array(5) {
     ["name"]=> array(4) {
         [0]=> string(14) "th95MGJ3E9.jpg"
         [1]=> string(8) "timg.jpg" 
         [2]=> string(13) "waterfall.jpg" 
         [3]=> string(6) "th.jpg" 
     } 
     ["type"]=> array(4) {
         [0]=> string(10) "image/jpeg" 
         [1]=> string(10) "image/jpeg" 
         [2]=> string(10) "image/jpeg" 
         [3]=> string(10) "image/jpeg" 
     } 
     ["tmp_name"]=> array(4) { 
         [0]=> string(25) "C:\wamp64\tmp\php70B4.tmp" 
         [1]=> string(25) "C:\wamp64\tmp\php70C5.tmp" 
         [2]=> string(25) "C:\wamp64\tmp\php70D5.tmp" 
         [3]=> string(25) "C:\wamp64\tmp\php70E6.tmp" 
     }
     ["error"]=> array(4) { 
         [0]=> int(0) 
         [1]=> int(0) 
         [2]=> int(0) 
         [3]=> int(0) 
      } 
      ["size"]=> array(4) { 
         [0]=> int(19625)  
         [1]=> int(150629) 
         [2]=> int(273504) 
         [3]=> int(17631) 
      }
   }
 } 
由上可知,每一个文件都被存进了数组里,所以需要用一个循环来读取文件信息。如下所示:
<code lang="php">
$upfile= $_FILES["upfile"];
 //var_dump($upfile);
 for($i=0;$i<count($upfile["name"]);$i++){
     $name = $upfile["name"][$i];
     $tmp_name = $upfile["tmp_name"][$i]; //文件暂时存放路径
     echo $tmp_name.'<br/>'.$name;
     move_uploaded_file($tmp_name,"F:\\$name");//将文件从暂时存放路径移动至想要移动到的路径。
 }
</code>
由上可知,用count()函数获取到文件数量,然后用一个for循环将文件移动便可以了,由于是最简单的移动方法,所以没有考虑到一些错误情况。
最后是文件的上传进度处理,这个需要session基础,js基础,ajax基础...
首先,是修改php配置文件,使其可以显示上传进度,这时需要用到session监控文件上传进度,在php.ini里,找到
1.session.upload_progress.enabled,这是是否启用上传进度报告的开关,默认是开启的,但是还是要确认一下
2.session.upload_progress.cleanup,是否在上传文件之后即使删除进度数据,默认也是开启的 
3.session.upload_progress.prefix="upload_progress_",进度数据将存储在_SESSION[session.upload_progress.prefix._POST[session.upload_progress.name]]里面
4.session.upload_progress.name=""PHP_SESSION_UPLOAD_PROGRESS",如果_POST[session.upload_progress.name]没有被设置,就不会报告进度
5.session.upload_progress.freq = "1%",更新的频率,可以用字节数,也可以用百分比来显示。
6.session.upload_progress.min_freq = "1.0",更新进度的时间间隔(秒级)
思路就是获取已上传大小和文件总大小,然后就可以获取百分比了,而且要用定时器,每隔一段时间刷新进度条。php部分代码如下:
<code lang="PHP">
<?php
/**
 * Created by PhpStorm.
 * User: lgr
 * Date: 2018/7/11
 * Time: 19:58
 */
/*以下是文件进度处理的代码*/
session_start();
$i = ini_get('session.upload_progress.name');

//ajax中我们使用的是get方法,变量名称为ini文件中定义的前缀 拼接 传过来的参数
$key = ini_get("session.upload_progress.prefix") . $_GET[$i];
//判断 SESSION 中是否有上传文件的信息
if (!empty($_SESSION[$key])) {
    //已上传大小
    $current = $_SESSION[$key]["bytes_processed"];
    //文件总大小
    $total = $_SESSION[$key]["content_length"];

    //向 ajax 返回当前的上传进度百分比。
    echo $current < $total ? ceil($current / $total * 100) : 100;
}else{
    echo 100;
}
var_dump($_SESSION);
/*以下是多文件上传的代码*/
$upfile= $_FILES["upfile"];
echo '<br><br><br><br><br>';
for($i=0;$i<count($upfile["name"]);$i++){
     $name = $upfile["name"][$i];
     $tmp_name = $upfile["tmp_name"][$i]; //文件暂时存放路径
     //echo $tmp_name.'<br/>'.$name;
     move_uploaded_file($tmp_name,"F:\\$name");//将文件从暂时存放路径移动至想要移动到的路径。
 };
</code>