天天看點

PHP的多檔案上傳類

送出表單的頁面 

upload.php

<!doctype html>
<html >
<head>
    <meta charset="UTF-8">
    <title>檔案上傳</title>
</head>
<body>
    <form action="doAction.php" method="post" enctype="multipart/form-data">
        請選擇您要上傳的檔案:<input type="file" name="myFile[]"/><br/>
        請選擇您要上傳的檔案:<input type="file" name="myFile[]"/><br/>
        請選擇您要上傳的檔案:<input type="file" name="myFile[]"/><br/>
        請選擇您要上傳的檔案:<input type="file" name="myFile[]"/><br/>
        請選擇您要上傳的檔案:<input type="file" name="myFile[]"/><br/>
        請選擇您要上傳的檔案:<input type="file" name="myFile[]"/><br/>
        <input type="submit" value="上傳檔案"/>
    </form>
</body>
</html>
           

多檔案上傳類

Upload2.class.php

<?php
/**
 * Created by PhpStorm.
 * User: DreamBoy
 * Date: 2016/4/9
 * Time: 9:24
 */
error_reporting(0);
class Upload2 {
    protected $fileName; //POST請求時檔案的name值
    protected $maxSize; //檔案上傳的最大大小
    protected $allowMime; //允許上傳的檔案類型
    protected $allowExt; //允許上傳的檔案類型
    protected $uploadPath; //檔案上傳的路徑
    protected $imgFlag; //标志是否要求上傳的檔案為真實圖檔

    protected $fileInfos; //所有檔案資訊
    protected $uploadRes; //上傳檔案的結果

    protected $error; //記錄系統錯誤号
    protected $err = array( //錯誤号及錯誤類型
        '000' => '檔案上傳成功',
        '001' => '超過了PHP配置檔案中upload_max_filesize選項值',
        '002' => '超過了表單中MAX_FILE_SIZE設定的值',
        '003' => '檔案部分被上傳',
        '004' => '沒有選擇上傳檔案',
        '005' => '沒有找到臨時目錄',
        '006' => '檔案不可寫',
        '007' => '由于PHP的擴充程式中斷檔案上傳',
        '008' => '上傳檔案過大',
        '009' => '不允許的檔案類型',
        '010' => '不允許的檔案MIME類型',
        '011' => '檔案不是真實圖檔',
        '012' => '檔案不是通過HTTP POST方式上傳上來的',
        '013' => '檔案移動失敗',
        '014' => '系統錯誤:檔案上傳出錯',
        );

    /**
     * Upload2 constructor.
     * @param string $fileName
     * @param string $uploadPath
     * @param bool $imgFlag
     * @param int $maxSize
     * @param array $allowExt
     * @param array $allowMime
     */
    public function __construct($fileName='myFile',$uploadPath='./uploads',$imgFlag=true,$maxSize=5242880,
                                $allowExt=array('jpeg','jpg','png','gif'),
                                $allowMime=array('image/jpeg','image/png','image/gif')) {

        $this->fileName = $fileName;
        $this->maxSize = $maxSize;
        $this->allowMime = $allowMime;
        $this->allowExt = $allowExt;
        $this->uploadPath = $uploadPath;
        $this->imgFlag = $imgFlag;
        $this->fileInfos = $this->getFileInfos();
    }

    /**
     * 擷取上傳的檔案資訊,并判斷上傳的檔案是單檔案還是多檔案,設定上傳檔案的模式
     * @return mixed
     */
    protected function getFileInfos() {
        if(isset($_FILES[$this->fileName])) {
            $file = $_FILES[$this->fileName];
        } else {
            $this->error = '014';
            $this->showError();
        }

        $i = 0;
        //單檔案或者多個單檔案上傳
        if(is_string($file['name'])) {
            $files[$i] = $file;
        } //多檔案上傳
        elseif(is_array($file['name'])) {
            foreach($file['name'] as $key=>$val) {
                $files[$i]['name'] = $file['name'][$key];
                $files[$i]['type'] = $file['type'][$key];
                $files[$i]['tmp_name'] = $file['tmp_name'][$key];
                $files[$i]['error'] = $file['error'][$key];
                $files[$i]['size'] = $file['size'][$key];
                $i++;
            }
        }
        return $files;
    }

    /**
     * 顯示錯誤
     */
    protected function showError() {
        $e = $this->err[$this->error];
        exit('<span style="color:red">' . $e . '</span>');
    }

    /**
     * 為序号為$cur的檔案設定上傳結果資訊
     * @param $cur
     * @param string $errno
     */
    protected function setError($cur, $errno='000') {
        $this->uploadRes[$cur]['errno'] = $errno;
        $this->uploadRes[$cur]['error'] = $this->err[$errno];
        $this->uploadRes[$cur]['dest'] = '';
    }

    /**
     * 檢測上傳檔案是否出錯
     * @param int $cur
     * @return bool
     */
    protected function checkError($cur=0) {
        if(is_null($this->fileInfos[$cur])) { //檔案擷取失敗
            $this->error = '014';
            $this->showError();
            return false;
        }

        if($this->fileInfos[$cur]['error']>0) {
            switch($this->fileInfos[$cur]['error']) {
                case 1:
                    $curErr = '001';
                    break;
                case 2:
                    $curErr = '002';
                    break;
                case 3:
                    $curErr = '003';
                    break;
                case 4:
                    $curErr = '004';
                    break;
                case 6:
                    $curErr = '005';
                    break;
                case 7:
                    $curErr = '006';
                    break;
                case 8:
                    $curErr = '007';
                    break;
            }

            $this->setError($cur, $curErr);
            return false;
        }
        return true;
    }

    /**
     * 檢測上傳檔案的大小
     * @param int $cur
     * @return bool
     */
    protected function checkSize($cur=0) {
        if($this->fileInfos[$cur]['size'] > $this->maxSize) {
            $this->setError($cur, '008');
            return false;
        }
        return true;
    }

    /**
     * 擷取序号為$cur檔案的擴充名
     * @param int $cur
     * @return string
     */
    protected function getCurExt($cur=0) {
        return strtolower(pathinfo($this->fileInfos[$cur]['name'], PATHINFO_EXTENSION));
    }

    /**
     * 檢測檔案擴充名
     * @param int $cur
     * @return bool
     */
    protected function checkExt($cur=0) {
        $ext = $this->getCurExt($cur);
        if(!in_array($ext, $this->allowExt)) {
            $this->setError($cur, '009');
            return false;
        }
        return true;
    }

    /**
     * 檢測檔案的MIME類型
     * @param int $cur
     * @return bool
     */
    protected function checkMime($cur=0) {
        if(!in_array($this->fileInfos[$cur]['type'],$this->allowMime)) {
            $this->setError($cur, '010');
            return false;
        }
        return true;
    }

    /**
     * 檢測檔案是否為真實圖檔
     * @param int $cur
     * @return bool
     */
    protected function checkTrueImg($cur=0) {
        if($this->imgFlag) {
            if([email protected]($this->fileInfos[$cur]['tmp_name'])) {
                $this->setError($cur, '011');
                return false;
            }
        }
        return true;
    }

    /**
     * 檢測是否通過HTTP Post方式上傳過來的
     * @param int $cur
     * @return bool
     */
    protected function checkHTTPPost($cur=0) {
        if(!is_uploaded_file($this->fileInfos[$cur]['tmp_name'])) {
            $this->error = '012';
            return false;
        }
        return true;
    }

    /**
     * 檢測目錄是否存在,如果不存在則進行建立
     */
    protected function checkUploadPath() {
        if(!file_exists($this->uploadPath)) {
            mkdir($this->uploadPath, 0777, true);
        }
    }

    /**
     * 産生唯一字元串
     * @return string
     */
    protected function getUniName() {
        return md5(uniqid(microtime(true),true));
    }

    /**
     * 上傳檔案
     * @return string
     */
    public function uploadFile() {
        foreach ($this->fileInfos as $key => $value) {
            if($this->checkError($key) && $this->checkSize($key)
                && $this->checkExt($key) && $this->checkMime($key)
                && $this->checkTrueImg($key) && $this->checkHTTPPost($key)) {

                $this->checkUploadPath();

                $uniName = $this->getUniName();
                $ext = $this->getCurExt($key);

                $destination = $this->uploadPath . '/' . $uniName . '.' . $ext;
                if(@move_uploaded_file($this->fileInfos[$key]['tmp_name'], $destination)) {
                    $this->setError($key);
                    $this->uploadRes[$key]['dest'] = $destination;
                } else {
                    $this->setError($key, '013');
                }
            }
        }

        return $this->uploadRes;
    }
}
           

送出檔案上傳的頁面

doAction.php

<?php
/**
 * Created by PhpStorm.
 * User: DreamBoy
 * Date: 2016/4/9
 * Time: 10:31
 */
header('content-type:text/html;charset=utf-8');
require_once 'Upload2.class.php';

function dump($arr) {
    echo '<pre>';
    print_r($arr);
    echo '</pre>';
}

//$upload = new Upload();
//$upload = new Upload('myFile2');
$upload = new Upload2('myFile');
$res = $upload->uploadFile();
dump($res);
           

運作:

PHP的多檔案上傳類

選擇檔案:

PHP的多檔案上傳類

跳轉結果:

PHP的多檔案上傳類

跳轉後顯示的結果資訊提示,與我們送出的檔案應提示的資訊一緻。

從中我們也可以看到隻有兩個檔案上傳成功。如下:

PHP的多檔案上傳類

修改-》 在Upload2.class.php類中增加 一些傳回資訊:如檔案名稱,檔案類型。提供是否保留檔案原名的設定。

<?php
/**
 * Created by PhpStorm.
 * User: DreamBoy
 * Date: 2016/4/9
 * Time: 9:24
 */
error_reporting(0);
class Upload {
    protected $fileName; //POST請求時檔案的name值
    protected $maxSize; //檔案上傳的最大大小
    protected $allowMime; //允許上傳的檔案類型
    protected $allowExt; //允許上傳的檔案類型
    protected $uploadPath; //檔案上傳的路徑
    protected $imgFlag; //标志是否要求上傳的檔案為真實圖檔
    protected $isOldName; //标志是否要求上傳的檔案保留原名

    protected $fileInfos; //所有檔案資訊
    protected $uploadRes; //上傳檔案的結果

    protected $error; //記錄系統錯誤号
    protected $err = array( //錯誤号及錯誤類型
        '000' => '檔案上傳成功',
        '001' => '超過了PHP配置檔案中upload_max_filesize選項值',
        '002' => '超過了表單中MAX_FILE_SIZE設定的值',
        '003' => '檔案部分被上傳',
        '004' => '沒有選擇上傳檔案',
        '005' => '沒有找到臨時目錄',
        '006' => '檔案不可寫',
        '007' => '由于PHP的擴充程式中斷檔案上傳',
        '008' => '上傳檔案過大',
        '009' => '不允許的檔案類型',
        '010' => '不允許的檔案MIME類型',
        '011' => '檔案不是真實圖檔',
        '012' => '檔案不是通過HTTP POST方式上傳上來的',
        '013' => '檔案移動失敗',
        '014' => '系統錯誤:檔案上傳出錯',
        );

    /**
     * Upload2 constructor.
     * @param string $fileName
     * @param string $uploadPath
     * @param bool $isOldName
     * @param bool $imgFlag
     * @param int $maxSize
     * @param array $allowExt
     * @param array $allowMime
     */
    public function __construct($fileName='myFile',$uploadPath='./uploads',$isOldName=false,$imgFlag=true,
        $maxSize=5242880,$allowExt=array('jpeg','jpg','png','gif'),
        $allowMime=array('image/jpeg','image/png','image/gif')) {

        $this->fileName = $fileName;
        $this->maxSize = $maxSize;
        $this->allowMime = $allowMime;
        $this->allowExt = $allowExt;
        $this->uploadPath = $uploadPath;
        $this->imgFlag = $imgFlag;
        $this->isOldName = $isOldName;
        $this->fileInfos = $this->getFileInfos();
    }

    /**
     * 擷取上傳的檔案資訊,并判斷上傳的檔案是單檔案還是多檔案,設定上傳檔案的模式
     * @return mixed
     */
    protected function getFileInfos() {
        if(isset($_FILES[$this->fileName])) {
            $file = $_FILES[$this->fileName];
        } else {
            $this->error = '014';
            $this->showError();
        }

        $i = 0;
        //單檔案或者多個單檔案上傳
        if(is_string($file['name'])) {
            $files[$i] = $file;
        } //多檔案上傳
        elseif(is_array($file['name'])) {
            foreach($file['name'] as $key=>$val) {
                $files[$i]['name'] = $file['name'][$key];
                $files[$i]['type'] = $file['type'][$key];
                $files[$i]['tmp_name'] = $file['tmp_name'][$key];
                $files[$i]['error'] = $file['error'][$key];
                $files[$i]['size'] = $file['size'][$key];
                $i++;
            }
        }
        return $files;
    }

    /**
     * 顯示錯誤
     */
    protected function showError() {
        $e = $this->err[$this->error];
        exit('<span style="color:red">' . $e . '</span>');
    }

    /**
     * 為序号為$cur的檔案設定上傳結果資訊
     * @param $cur
     * @param string $errno
     */
    protected function setError($cur, $errno='000') {
        $this->uploadRes[$cur]['errno'] = $errno;
        $this->uploadRes[$cur]['error'] = $this->err[$errno];
        $this->uploadRes[$cur]['name'] = '';
        $this->uploadRes[$cur]['dest'] = '';
        $this->uploadRes[$cur]['type'] = '';
    }

    /**
     * 檢測上傳檔案是否出錯
     * @param int $cur
     * @return bool
     */
    protected function checkError($cur=0) {
        if(is_null($this->fileInfos[$cur])) { //檔案擷取失敗
            $this->error = '014';
            $this->showError();
            return false;
        }

        if($this->fileInfos[$cur]['error']>0) {
            switch($this->fileInfos[$cur]['error']) {
                case 1:
                    $curErr = '001';
                    break;
                case 2:
                    $curErr = '002';
                    break;
                case 3:
                    $curErr = '003';
                    break;
                case 4:
                    $curErr = '004';
                    break;
                case 6:
                    $curErr = '005';
                    break;
                case 7:
                    $curErr = '006';
                    break;
                case 8:
                    $curErr = '007';
                    break;
            }

            $this->setError($cur, $curErr);
            return false;
        }
        return true;
    }

    /**
     * 檢測上傳檔案的大小
     * @param int $cur
     * @return bool
     */
    protected function checkSize($cur=0) {
        if($this->fileInfos[$cur]['size'] > $this->maxSize) {
            $this->setError($cur, '008');
            return false;
        }
        return true;
    }

    /**
     * 擷取序号為$cur檔案的擴充名
     * @param int $cur
     * @return string
     */
    protected function getCurExt($cur=0) {
        return strtolower(pathinfo($this->fileInfos[$cur]['name'], PATHINFO_EXTENSION));
    }

    /**
     * 檢測檔案擴充名
     * @param int $cur
     * @return bool
     */
    protected function checkExt($cur=0) {
        $ext = $this->getCurExt($cur);
        if(!in_array($ext, $this->allowExt)) {
            $this->setError($cur, '009');
            return false;
        }
        return true;
    }

    /**
     * 檢測檔案的MIME類型
     * @param int $cur
     * @return bool
     */
    protected function checkMime($cur=0) {
        if(!in_array($this->fileInfos[$cur]['type'],$this->allowMime)) {
            $this->setError($cur, '010');
            return false;
        }
        return true;
    }

    /**
     * 檢測檔案是否為真實圖檔
     * @param int $cur
     * @return bool
     */
    protected function checkTrueImg($cur=0) {
        if($this->imgFlag) {
            if([email protected]($this->fileInfos[$cur]['tmp_name'])) {
                $this->setError($cur, '011');
                return false;
            }
        }
        return true;
    }

    /**
     * 檢測是否通過HTTP Post方式上傳過來的
     * @param int $cur
     * @return bool
     */
    protected function checkHTTPPost($cur=0) {
        if(!is_uploaded_file($this->fileInfos[$cur]['tmp_name'])) {
            $this->error = '012';
            return false;
        }
        return true;
    }

    /**
     * 檢測目錄是否存在,如果不存在則進行建立
     */
    protected function checkUploadPath() {
        if(!file_exists($this->uploadPath)) {
            mkdir($this->uploadPath, 0777, true);
        }
    }

    /**
     * 産生唯一字元串
     * @return string
     */
    protected function getUniName() {
        return md5(uniqid(microtime(true),true));
    }

    /**
     * 上傳檔案
     * @return string
     */
    public function uploadFile() {
        foreach ($this->fileInfos as $key => $value) {
            if($this->checkError($key) && $this->checkSize($key)
                && $this->checkExt($key) && $this->checkMime($key)
                && $this->checkTrueImg($key) && $this->checkHTTPPost($key)) {

                $this->checkUploadPath();

                if($this->isOldName) {
                    $name = $this->fileInfos[$key]['name'];
                    $destination = $this->uploadPath . '/' . $name;
                } else {
                    $name = $this->getUniName();
                    $ext = $this->getCurExt($key);
                    $destination = $this->uploadPath . '/' . $name . '.' . $ext;
                }
                
                if(@move_uploaded_file($this->fileInfos[$key]['tmp_name'], $destination)) {
                    $this->setError($key);
                    $this->uploadRes[$key]['name'] = $name;
                    $this->uploadRes[$key]['dest'] = $destination;
                    $this->uploadRes[$key]['type'] = $this->fileInfos[$key]['type'];
                } else {
                    $this->setError($key, '013');
                }
            }
        }

        return $this->uploadRes;
    }
}