Skip to main content
 首页 » 编程设计

jQuery在PHP_APC+Ajax实现的监视进度条的文件上传

2022年07月16日25zhenyulu
// load.js: 
ADS.addEvent(window, 'load', function (event) { 
    var fileList = ADS.$('fileList'); 
    // 按照需要修改uoloadForm 
    addProgressBar('uploadForm', function (response) { 
        var files = response.filesProcessed; 
        for (var i in files) { 
            // 跳过空文件 
            if (files[i] === null) { 
                continue; 
            } 
 
            // 创建一个新的文件列表元素 
            var li = document.createElement('li'); 
            var a = document.createElement('a'); 
            a.setAttribute('href', 'uploads/' + files[i]); 
            a.appendChild(document.createTextNode(files[i])); 
            li.appendChild(a); 
            fileList.appendChild(li); 
        } 
        // 更新文件计数器 
        var countContainer = ADS.$('fileCount'); 
        ADS.removeChildren(countContainer); 
        var numFiles = fileList.getElementsByTagName('li').length; 
        countContainer.appendChild(document.createTextNode(numFiles)); 
    }); 
}); 
 
 
 
// uploader.js: 
/** 
 * User: lindongpeng 
 * Date: 13-2-19 
 */ 
 
function verifyFileType(fileInput) { 
    if (!fileInput.value || !fileInput.accept) { 
        return true; 
    } 
    var extension = fileInput.value.split('.').pop().toLowerCase(), 
        mimetypes = fileInput.accept.toLowerCase().split(','), 
        type; 
    for (var i = 0, len = mimetypes.length; i < len; i++) { 
        type = mimetypes[i].split('/')[1]; 
        if (type === extension || (type === 'jpeg' && extension === 'jpg')) { 
            return true; 
        } 
    } 
    return false; 
} 
 
var addProgressBar = function (form, modificationHander) { 
 
    // 检查表单是否存在 
    if (!(form = ADS.$(form))) { 
        return false; 
    } 
 
    // 查找所有文件输入元素 
    var allInputs = form.getElementsByTagName('input'); 
    var input; 
    var fileInputs = []; 
    for (var i = 0; (input = allInputs[i]); i++) { 
        if (input.getAttribute('type') === 'file') { 
            fileInputs.push(input); 
        } 
    } 
 
    // 如果没有文件输入元素则停止脚本 
    if (!fileInputs.length) { 
        return false; 
    } 
 
    // 添加change事件以基于MIME类型验证扩展名 
    for (var j = 0, len = fileInputs[i]; i < len; j++) { 
        // 使用change事件侦听器进行文件类型检查 
        ADS.addEvent(fileInputs[i], 'change', function (event) { 
            var ok = verifyFileType(this); 
            if (!ok) { 
                if (!ADS.hasClassName(this, 'error')) { 
                    ADS.addClassName(this, 'error'); 
                } 
                alert('Sorru, that file type is not allowed.Please select one of:' + this.accept.toLowerCase()); 
            } else { 
                ADS.removeClassName(this, 'error'); 
            } 
        }); 
    } 
 
    // 为上传而附加iframe元素 
    // 在IE中,不能像下面这样通过DOM设置name属性,例如: 
    // var uploadTargetFrame = document.createElement('iframe'); 
    // uploadTargetFrame.setAttribute('id', 'uploadTargetFrame'); 
    // uploadTargetFrame.setAttribute('name', 'uploadTargetFrame'); 
    // 为解决这个问题,需要创建一个div并使用其innerHTML属性 
    // 从而确保在IE和其他浏览器中都能正确的设置name属性 
    var uploadTargetFrame = document.createElement('div'); 
    uploadTargetFrame.innerHTML = '<iframe name="uploadTargetFrame" id="uploadTargetFrame"></iframe>'; 
    ADS.setStyleById(uploadTargetFrame, { 
        'width': 0, 
        'height': 0, 
        'border': 0, 
        'visibility': 'hidden', 
        'z-index': -1 
    }); 
    document.body.appendChild(uploadTargetFrame); 
 
    // 将表单的target属性修改为新iframe元素 
    // 这样可以避免页面重载 
    form.setAttribute('target', 'uploadTargetFrame'); 
 
    // 创建一个唯一的ID以跟踪上传进度 
    var uniqueID = 'A' + Math.floor(Math.random() * 1000000000000000); 
 
    // 为APC_UPLOAD_PROGRESS键添加这个唯一ID 
    // 这个字段必须添加到文件输入字段之前,以便 
    // 服务器首先取得改键并触发存储进度信息的操作 
    var uniqueIDField = document.createElement('input'); 
    uniqueIDField.setAttribute('type', 'hidden'); 
    uniqueIDField.setAttribute('value', uniqueID); 
    uniqueIDField.setAttribute('name', 'APC_UPLOAD_PROGRESS'); 
    form.insertBefore(uniqueIDField, form.firstChild); 
 
    // 创建进度条的不同部分 
 
    // 进度条 
    var progressBar = document.createElement('div'); 
    progressBar.className = 'progressBar'; 
 
    // 内部的背景容器 
    var progressBackground = document.createElement('div'); 
    progressBackground.className = 'progressBackground'; 
    ADS.setStyle(progressBackground, { 
        'height': '10px' 
    }); 
    progressBackground.appendChild(progressBar); 
 
    // 检查已有的定位点 
    // 必须是带有progressContainer类的span元素 
    var progressContainer = ADS.getElementsByClassName( 
        'progressContainer', 
        'div' 
    )[0]; 
 
    // 如果该定位点不存在则创建一个并将其添加到表单中 
    if (!progressContainer) { 
        progressContainer = document.createElement('div'); 
        progressContainer.className = 'progressContainer'; 
        form.appendChild(progressContainer); 
    } 
 
    // 添加进度条的其余部分 
    progressContainer.appendChild(progressBackground); 
 
    // 同时也添加一个进度信息显示区域 
    var progressMessage = document.createElement('div'); 
    progressMessage.className = 'progressMessage'; 
    progressContainer.appendChild(progressMessage); 
 
    // 创建一个将由后面的进度监视方法使用 
    // 的私有方法,以方便更新进度条和相应信息 
    function updateProgressBar(percent, message, satus) { 
        progressMessage.innerHTML = message; 
        ADS.removeClassName(progressMessage, 'error complete waiting uploading'); 
        ADS.addClassName(progressMessage, satus); 
 
        // CSS样式和className将负责指示状态 
        ADS.setStyle(progressBar, { 
            'width': percent 
        }); 
    } 
 
    // 从0%和waiting开始初始化进度条 
    updateProgressBar('0%', 'Waiting for upload', 'waiting'); 
 
    // 为表单添加提交事件侦听器,用于 
    // 验证表单信息和更新进度条 
    ADS.addEvent(form, 'submit', function (event) { 
        // 再次检查输入以确保 
        // 其包含正确的扩展名 
        var ok = true; 
        var hasFiles = false; 
        for (var i = 0, fileInput; (fileInput = fileInputs[i]); i++) { 
            if (fileInput.value) { 
                hasFiles = true; 
            } 
            if (!verifyFileType(fileInput)) { 
                // 突出显示出错的文件输入元素 
                if (!ADS.hasClassName(fileInput, 'error')) { 
                    ADS.addClassName(fileInput, 'error'); 
                } 
                ok = false; 
            } 
        } 
 
        if (!ok || !hasFiles) { 
            // 如果检查为通过则提示用户解决问题 
            ADS.preventDefault(event); 
            alert('Please select some valid files'); 
            return false; 
        } 
 
        // 通过发出警告信息来禁用表单元素 
        function warning(event) { 
            ADS.preventDefault(event); 
            alert('There is an upload in progress. Please wait.'); 
        } 
 
        for (var i = 0, input; (input = allInputs[i]); i++) { 
            // input.setAttribute('disabled', 'disabled'); 
            ADS.addEvent(input, 'mousedown', warning); 
        } 
 
        // 创建一个函数以便在上传完成后重启表单 
        // 该函数将在ajax事件侦听器内部被调用 
        function clearWarnings() { 
            // 从表单元素移除警告侦听器 
            for (var i = 0, input; (input = allInputs[i]); i++) { 
                ADS.removeEvent(input, 'mousedown', warning); 
            } 
 
            // 以新ID数值更新原ID和表单 
            // 以确保下次上传不影响本次上传 
            uniqueID = Math.floor(Math.random() * 100000000000000); 
            uniqueIDFiled.setAttribute('value', uniqueID); 
        } 
 
        // 更新进度条 
        updateProgressBar('0%', 'Waiting for upload', 'waiting'); 
 
        // 为模拟脚本设置计数器 
        var counter = 0; 
 
        // 创建一个新方法以触发一次新的进度请求 
        var progressWatcher = function () { 
            // 使用唯一键来请求进度信息 
            ADS.ajaxRequest(form.action + (form.action.indexOf('?') === -1 ? '?' : '&') + 'key=' + uniqueID + '&sim=' + (++counter), { 
                // 服务器端脚本将返回适当的头部信息 
                // 因此我们可以使用JSON侦听器 
                jsonResponseListener: function (response) { 
                    // 检测响应以确认服务器端 
                    // 脚本中是否存在错误 
 
                    if (!response) { 
                        // 没有有效的响应 
                        updateProgressBar( 
                            '0%', 
                            'Invalid response from progress watcher', 
                            'error' 
                        ); 
                        // 请求完成故清除警告提示 
                        clearWarnings(); 
                    } else if (response.error) { 
                        // 服务器端报告了错误 
                        updateProgressBar('0%', response.error, 'error'); 
                        // 请求完成故清除警告提示 
                        clearWarnings(); 
                    } else if (response.done === 1) { 
                        // POST请求已经完成 
                        updateProgressBar('100%', 'Upload complete', 'complete'); 
                        // 请求完成故清除警告提示 
                        clearWarnings(); 
                        // 为提供更改处理程序的 
                        // 用户传递新信息 
                        if (modificationHander.constructor === Function) { 
                            modificationHander(response); 
                        } 
                    } else { 
                        // 更新进度条并返回结果 
                        // 由于结果是null, 所以 
                        // 返回会简单地停止执行 
                        // 方法中其余的代码 
                        updateProgressBar( 
                            Math.round(response.current / response.total * 100) + '&', 
                            response.current + 'of' 
                                + response.total + '. Uploading file: ' 
                                + response.currentFileName, 
                            'uploading' 
                        ); 
 
                        // 再次执行进度监视程序 
                        setTimeout(progressWatcher, 1000); 
                    } 
                }, 
                errorListener: function () { 
                    // ajax请求发生了错误 
                    // 因此需要让用户知道 
                    updateProgressBar('0%', this.status, 'error'); 
 
                    // 并清除警告提示 
                    clearWarnings(); 
                } 
            }); 
        }; 
 
        // 开始监视 
        setTimeout(progressWatcher, 1000); 
 
    }); 
}; 
 
 
 
 
  
// 主页 
index.php: 
 
 <?php 
 
// 循环遍历uploads文件夹 
// 以便取得已经上传的文件 
$uploads = new DirectoryIterator('./uploads'); 
$files=array(); 
foreach($uploads as $file) { 
    // 跳过,并。。。 
    if(!$file->isDot() && $file->isFile()) { 
        // 添加到数组,。稍后,该数组 
        // 将在HTML中被连接起来 
        $files[]=sprintf( 
            '<li><a href="uploads/%s">%s</a> <em>%skb</em></li>', 
            $file->getFilename(), 
            $file->getFilename(), 
            round($file->getSize()/1024) 
        ); 
    } 
} 
 
// 输出页面 
?> 
<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <title>Image Uploader with Progress (php5-APC)</title> 
 
    <!-- Inclue some CSS style sheet to make 
    everything look a little nicer --> 
    <link rel="stylesheet" 
          href="http://www.cnblogs.com/../shared/source.css" /> 
    <link rel="stylesheet" 
          href="http://www.cnblogs.com/chapter.css" /> 
    <link rel="stylesheet" href="style.css" /> 
 
    <!-- Your ADS library with the common JavaScript objects --> 
    <script src="http://www.cnblogs.com/../ADS.js"></script> 
 
    <!-- Progress bar script --> 
    <script src="uploader.js"></script> 
 
    <!-- load script --> 
    <script src="load.js"></script> 
 
</head> 
<body> 
<h1>Image Uploader with Progress (php5-APC)</h1> 
<div id="content"> 
    <form action="actions/" enctype="multipart/form-data" 
          method="post" id="uploadForm"> 
 
        <fieldset> 
            <legend>Upload a new image</legend> 
            <p>Only jpg/gif/png files less than 100kb allowed.</p> 
            <div class="fileSelector"> 
                <label for="newFile1">File 1</label> 
                <input type="file" id="newFile1" name="newFile1" 
                       accept="image/jpeg,image/gif,image/png"/> 
            </div> 
            <div class="fileSelector"> 
                <label for="newFile2">File 2</label> 
                <input type="file" id="newFile2" name="newFile2" 
                       accept="image/jpeg,image/gif,image/png"/> 
            </div> 
            <div class="fileSelector"> 
                <label for="newFile3">File 3</label> 
                <input type="file" id="newFile3" name="newFile3" 
                       accept="image/jpeg,image/gif,image/png"/> 
            </div> 
            <input id="submitUpload" name="submitUpload" 
                   type="submit" value="Upload Files" /> 
        </fieldset> 
 
    </form> 
 
    <div id="browserPane"> 
        <h2> 
                <span id="fileCount"> 
                    <?php echo count($files); ?> 
                </span> 
            Existing Files in <em>uploads/</em> 
        </h2> 
        <ul id="fileList"> 
            <?php echo join($files,"\n\t\t\t\t"); ?> 
        </ul> 
    </div> 
</div> 
 
<div id="where-from"> 
    From <a href="http://advanceddomscripting.com" title="AdvancED DOM Scripting">AdvancED DOM Scripting</a> 
    | <a href="http://www.amazon.com/exec/obidos/ASIN/1590598563/jeffreysamb05-20" title="Buy it on Amazon">Paperback</a> 
</div> 
</body> 
 
</html> 
 
 
// 表单action指向的php文件 
action/index.php:  
 <?php 
 
//check if the request is using the ADS.ajaxRequest() method. 
if($_SERVER['HTTP_X_ADS_AJAX_REQUEST']) { 
     
    // Return the progress information as a JSON string 
     
    // Send some headers to prevent caching of the progress request 
    header('Expires: Fri, 13 Dec 1901 20:45:54 GMT') ; 
    header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT') ; 
    header('Cache-Control: no-store, no-cache, must-revalidate') ; 
    header('Cache-Control: post-check=0, pre-check=0', false) ; 
    header('Pragma: no-cache') ; 
     
    // This will be a JavaScript JSON response 
    header('Content-Type:application/json; charset=utf-8' ) ; 
 
    // Retrieve the status using the getStatus() function below     
    echo json_encode(getStatusAPC($_GET['key'])); 
     
    die(); 
}  
 
// Process any files in the PHP $_FILES[] array and return to the 
// main script if everything went well. Otherwise we'll display a 
// error page. 
 
$allowedExtensions = array('jpg','jpeg','gif','png'); 
$errorMessage = null ; 
$storedFiles = array(); 
 
 
if(count($_FILES) > 0) { 
     
    try { 
         
        // Process each file 
        foreach($_FILES as $key=>$info) { 
            if($_FILES[$key]['name']) { 
                // storeFile() throws exceptions 
                $file = storeFile($key,'../uploads/',$allowedExtensions); 
            } else { 
                $file = null; 
            } 
 
            // Keep track of stored files incase you need to 
            // remove them. 
            $storedFiles[$key] = $file['basename']; 
        } 
 
        if($_POST['APC_UPLOAD_PROGRESS'] && function_exists('apc_store')) { 
         
            // Store the file information so it can be  
            // retrieved in the progress watcher             
            apc_store('upload_finished_'.$_POST['APC_UPLOAD_PROGRESS'],$storedFiles); 
 
            // Die. This message will display in the iframe                 
            die('Upload complete.'); 
             
        } 
         
        // Everything was successful so redirect back  
        // to the main index page 
        header('Location: ../'); 
        die(); 
         
    } catch (Exception $e) { 
        // There was an error so remove any files that were uploaded 
        foreach($storedFiles as $file) { 
            if(is_file($file)) unlink('uploads/'.$file); 
        } 
        $storedFiles = array(); 
 
 
 
        if($_POST['APC_UPLOAD_PROGRESS'] && function_exists('apc_store')) { 
             
            // Store the error message so it can be  
            // retrieved in the progress watcher 
            apc_store( 
                'upload_error_'.$_POST['APC_UPLOAD_PROGRESS'], 
                $e->getMessage() 
            ); 
             
            // Die. This message will display in the iframe 
            die('There was an error'); 
         
        } else { 
         
            // Get the error message 
            $errorMessage = sprintf( 
                '<p>%s failed: %s</p>',  
                $key,  
                $e->getMessage() 
            ); 
             
            // Display a simple error page with a  
            // link back to the main index file 
            echo  
<<<XHTML 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
    <title>Oops!</title> 
</head> 
<body> 
    <h1>Error</h1> 
    <p>The system reported an error with the 
    file(s) you were trying to upload:</p> 
    {$errorMessage} 
    <p><a href="../">Return to the upload page</a></p> 
 
<div id="where-from"> 
    From <a href="http://advanceddomscripting.com" title="AdvancED DOM Scripting">AdvancED DOM Scripting</a>  
    | <a href="http://www.amazon.com/exec/obidos/ASIN/1590598563/jeffreysamb05-20" title="Buy it on Amazon">Paperback</a> 
</div> 
</body> 
 
</html> 
XHTML; 
        } 
    }     
} 
 
 
/** 
 * Store a file uploaded through HTTP on the server 
 * 
 * This function will access the global $_FILES array to retrieve the  
 * information: 
 * 
 * The original name of the file on the client machine. 
 * $_FILES['userfile']['name'] 
 * 
 * The mime type of the file, if the browser provided this information. 
 * An example would be 'image/gif'. This mime type is however not checked 
 * on the PHP side and therefore don't take its value for granted. 
 * $_FILES['userfile']['type'] 
 * 
 * The size, in bytes, of the uploaded file. 
 * $_FILES['userfile']['size'] 
 * 
 * The temporary filename of the file in which the uploaded file was stored on the server. 
 * $_FILES['userfile']['tmp_name'] 
 * 
 * The error code  associated with this file upload. 
 * This element was added in PHP 4.2.0 
 * $_FILES['userfile']['error'] 
 * 
 * @param string $key The key in $_FILES that represents the file you wish to  
 * store. This is generally the name attribute from the form. 
 * @param string $where The directory on the server where you wish to store  
 * the file. This can be absolute or relative to the location of execution. 
 * @param array $extensions An array of acceptable extensions. (white list) 
 * @param int $maxBytes The maximum number of bytes 
 * @return array 
 */ 
function storeFile($key,$where,$extensions,$maxBytes=null) { 
 
    try { 
         
        // Check for the file 
        if(!$_FILES[$key]) { 
            throw new Exception('The specified key does not exist in the $_FILES array'); 
        } 
 
        // Check the uplod location  
        if(!$where) { 
            throw new Exception('Upload location not specified. If the current directory is desired, use "."'); 
        } elseif ($where[strlen($where)-1] != DIRECTORY_SEPARATOR) { 
            $where .= DIRECTORY_SEPARATOR; 
        } 
         
        // Check for permissions 
        if(!is_writeable($where)) { 
            throw new Exception('This page can not access the specified upload directory.'); 
        } 
 
        // convert the extensions to an array 
        // (if a single extension as a string was supplied) 
        settype($extensions,'array'); 
         
        //check for extensions 
        if(count($extensions) == 0) { 
            throw new Exception('No valid extensions were specified.'); 
        } 
         
 
        // Convert ini to bytes and store in maxBytes if required 
        $maxBytes = ($maxBytes ? $maxBytes  : preg_replace_callback( 
        '/([0-9]+)([gmk])/i', 
        'toBytes', 
        ini_get('upload_max_filesize') 
        )); 
 
        // check PHP upload errors         
        switch ($_FILES[$key]['error']) { 
            case UPLOAD_ERR_OK: 
                // everything was fine. Proceed 
                break; 
            case UPLOAD_ERR_INI_SIZE: 
                throw new Exception('The uploaded file exceeds the upload_max_filesize directive ('.ini_get('upload_max_filesize').') in php.ini.'); 
                break; 
            case UPLOAD_ERR_FORM_SIZE: 
                throw new Exception('The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.'); 
                break; 
            case UPLOAD_ERR_PARTIAL: 
                throw new Exception('The uploaded file was only partially uploaded.'); 
                break; 
            case UPLOAD_ERR_NO_FILE: 
                throw new Exception('No file was uploaded.'); 
                break; 
            case UPLOAD_ERR_NO_TMP_DIR: 
                throw new Exception('Missing a temporary folder.'); 
                break; 
            case UPLOAD_ERR_CANT_WRITE: 
                throw new Exception('Failed to write file to disk'); 
                break; 
            default: 
                throw new Exception('Unknown PHP File Error'); 
        } 
 
        // Check if the files size is greater than the  
        // file size in the arguments 
        if($_FILES['userfile']['size'] > $maxBytes) { 
            throw new Exception('The uploaded file exceeds the maximum size specified in the application.'); 
        } 
 
        // Sanitize the file name 
        $cleanName = str_replace(' ','-',$_FILES[$key]['name']); 
        $cleanName = preg_replace('/-+/','-',$cleanName); 
        $cleanName = preg_replace('/[^a-z0-9_.\/-]/i','',$cleanName); 
        $fileNameParts = pathinfo($cleanName); 
 
        // Verify the sanitized name is good 
        $fileNameParts['filename'] = str_replace('.','_',$fileNameParts['filename']); 
        if(!$fileNameParts['filename']) { 
            throw new Exception('The desired file name contains no valid characters.'); 
        } 
 
        // Verify the extension is valid 
        $fileNameParts['extension'] = strtolower($fileNameParts['extension']); 
        if(!in_array($fileNameParts['extension'], $extensions)) { 
            throw new Exception('The file extension is not one of: '.join($extensions,', ')); 
        } 
 
        // Postfix the file with a counter to avoid duplicates 
        $count = 0; 
        $postfix = ''; 
        while(file_exists($uploadLocation = $where.$fileNameParts['filename'].$postfix.'.'.$fileNameParts['extension'])) { 
            $postfix = '-'.++$count; 
        } 
 
        // Move the upload into place 
        if(!move_uploaded_file($_FILES[$key]['tmp_name'], $uploadLocation)) { 
            throw new Exception('Failed to move uploaded tmp file.'); 
        } 
 
    } catch (Exception $e) { 
        // Catch exceptions for garbage collection and error storage 
 
        // Remove the temp file 
        if($_FILES[$key] && is_uploaded_file($_FILES[$key]['tmp_name']))  { 
            @unlink($_FILES[$key]['tmp_name']); 
        } 
 
        // Throw the exception again for developers to catch 
        throw $e; 
    } 
 
    // Return the information about the new file using pathinfo 
    $return = pathinfo($uploadLocation); 
    $return['rawname'] = basename($_FILES[$key]['name']); 
    return $return; 
} 
 
function toBytes($matches) { 
    switch(strtolower($matches[2])) { 
        case "k": return $matches[1] * 1024; break; 
        case "m": return $matches[1] * 1048576; break; 
        case "g": return $matches[1] * 1073741824; break; 
    } 
} 
 
 
/** 
 * PHP 5.2 has a new set of hooks for checking the progress of a file upload 
 * with APC 3.5 
 * 
 * http://viewcvs.php.net/viewvc.cgi/pecl/apc/INSTALL?revision=3.53&view=markup 
 *  
 * apc.rfc1867 
 * RFC1867 File Upload Progress hook handler is only available 
 * if you compiled APC against PHP 5.2.0 or later.  When enabled 
 * any file uploads which includes a field called 
 * APC_UPLOAD_PROGRESS before the file field in an upload form 
 * will cause APC to automatically create an upload_ 
 * user cache entry where  is the value of the 
 * APC_UPLOAD_PROGRESS form entry. 
 * (Default: 0) 
 *  
 */ 
function getStatusAPC($key) { 
     
    $response = false; 
     
    // will return false if not found 
    if($status = apc_fetch('upload_'.$_GET['key'])) { 
        /* 
        status { 
        "total":2676099, 
        "current":102685, 
        "filename":"test_large.jpg", 
        "name":"test_file", 
        "done":0 
        } 
        */ 
         
        $response = array( 
        'total' => $status['total'], 
        'current' => $status['current'], 
        'currentFileName' => $status['filename'], 
        'currentFieldName' => $status['name'], 
        'filesProcessed' => null, 
        'error' => null, 
        'done' => $status['done'], 
        'debug'=>null 
        ); 
 
        if($message = apc_fetch('upload_error_'.$_GET['key'])) { 
 
            $response['error'] = $message; 
            $response['debug'] = 'There was an error'; 
 
        } else if ($status['done']==1 && ($filesProcessed = apc_fetch('upload_finished_'.$_GET['key']))) { 
            //wait until the last file processed matches the one in status 
            $response['debug'] = 'Files were processed '; 
            if(($last = array_pop(array_keys(((array)$filesProcessed)))) == $status['name']) { 
                $response['filesProcessed'] = $filesProcessed; 
                $response['debug'] .= ' - all'; 
            } else { 
                // Override the done state because the upload  
                // has finished but the server is still processing 
                // the files 
                $response['done']= 0; 
                $response['debug'] .= " - \"$last\" != \"{$status['name']}\""; 
            } 
        } 
 
    } 
 
    return $response;     
} 
 
?>

本文参考链接:https://www.cnblogs.com/webFrontDev/archive/2013/02/24/2926138.html