php檔案上傳之多檔案上傳

傑楓Jeff發表於2015-07-24

   在胡說之前,首先宣告,本文是建立在掌握php單檔案上傳的基礎上,所以這裡就不贅述檔案上傳伺服器配置,表單設定該注意的地方了。

   話不多少,直入主題,在請求頁面方面有兩種寫法(只呈現表單部分,以上傳三個檔案為例。)

    

<form action="doAction.php" method="post" enctype="multipart/form-data">
        請選擇我的上傳檔案
        <input type="file" name="myfile[]"/>
        <input type="file" name="myfile[]" />
        <input type="file" name="myfile[]" />
        <input type="submit" value="上傳" />
</form>
<form action="doAction.php" method="post" enctype="multipart/form-data">
        請選擇我的上傳檔案
        <input type="file" name="myfil1"/>
        <input type="file" name="myfil2"/>
        <input type="file" name="myfil3"/>
        <input type="submit" value="上傳" />
    </form>

  兩個對比,發現僅僅是name的不同,第一個將name設定成陣列的形式,而第二個則是我們通常設定也很容易想到的一種方法。

  雖然表面上顯示的僅僅有一點點不同,但真正提交到doAction.php頁面的$_FILES則有很大不同。

  第一種的$_FILES是一個三維陣列,而第二種是二維陣列,如下:

  

    

  

顯然我們處理第二種格式的$_FILES更加方便。當然我們也可以想辦法將第一種格式的$_FILES轉化為第二種形式,如下:\

function getFiles(){


    foreach($_FILES as $file){
        $fileNum=count($file['name']);
        if ($fileNum==1) {

            $files=$file;
        }else{
            
            for ($i=0; $i < $fileNum; $i++) { 
                $files[$i]['name']=$file['name'][$i];
                $files[$i]['type']=$file['type'][$i];
                $files[$i]['tmp_name']=$file['tmp_name'][$i];
                $files[$i]['error']=$file['error'][$i];
                $files[$i]['size']=$file['size'][$i];
            }
        }

        
    }
    return $files;
}

 

      通過這個函式,將$_FILES轉化為下面格式:

  

  此刻,兩種上傳方式已經處在同一起跑線了,下面的工作便是編寫uploadFile()函式對每個檔案進行上傳,這也是本文的重點。

  檔案上傳函式:

function uploadFile($file,$path='./uploads',$max_size,$allowExt){
  $filename=$file['name'];
    $type=$file['type'];
    $temp_name=$file['tmp_name'];
    $error=$file['error'];
    $size=$file['size'];


    if ($error==UPLOAD_ERR_OK) {
        if ($size>$max_size) {
            $res['mes']=$filename."檔案超過規定上傳大小";
        }
        $ext=getExt($filename);
        if (!in_array($ext, $allowExt)) {
            $res['mes']=$filename.'檔名不合乎規範';
        }
        if (!is_uploaded_file($temp_name)) {
            $res['mes']=$filename."檔案不是通過HTTP POST 方法上傳上傳過來的";
        }


        if (@$res) {
            return  $res;
        }


        if (!file_exists($path)) {
            mkdir($path,0777,true);
      chmod($path, 0777);
        }
        $fname=getUniName();


        $destination=$path.'/'.$fname.'.'.$ext;
        if (move_uploaded_file($temp_name, $destination)) {
            $res['mes']=$filename.'上傳成功';
            $res['dest']=$destination;
        }else{
            $res['mes']=$filename."檔案上傳失敗";
        }
    }else{
        switch ($error) {
            case '1':
            $res['mes']="超過了配置檔案上傳檔案的大小";
            break;
            case '2':
            $res['mes']="超過表單設定上傳檔案檔案的大小";
            break;
            case '3':
            $res['mes']="檔案部分被上傳";
            break;
            case '4':
            $res['mes']="沒有檔案被上傳";

            break;
            case '6':
            $res['mes']="沒有找到臨時目錄";
            break;
            case '7':
            $res['mes']="檔案不可寫";

            break;
            default:
            $res['mes']="上傳檔案失敗";
            break;
        }
    }

    return $res;

}

其中還涉及了兩個小函式:

/**
 * 獲得副檔名
 * @param  string $filename 上傳檔名
 * @return string           返回副檔名
 */
function getExt($filename){
    $arr=explode('.', basename($filename));

    return end($arr);
}
/**
 * 獲得檔案唯一副檔名
 * @return string 經過md5後生成32位唯一的上傳檔名
 */
function getUniName(){

    return md5(uniqid(microtime(true),true)); 
}

 

感受:

  很久前接觸過php檔案上傳,當時感覺一團亂麻。現在看來只要掌握$_FILES裡面包含什麼資訊,利用自己寫過的知識處理一些小技巧,系統有邏輯的加以考慮,適時地封裝函式,以後檔案上傳就可以很快地展開。這次我展現的程式碼必然不是能滿足任何需要,所以可以適當改造,成為自己的程式碼。比如如果要求上傳檔案是圖片內容的話,單靠副檔名是絕對不能判斷的,還需要利用圖片的特性加以驗證。

 

  

 

相關文章