获取文件上传进度的方法很多,该文介绍的是使用session.upload_progress,基于PHP 5.4以上版本的方法。
【1】文件php.ini 配置
根据实际情况进行设置
session.upload_progress.enabled[=1] : 是否启用上传进度报告(默认开启)
session.upload_progress.cleanup[=1] : 是否在上传完成后及时删除进度数据(默认开启, 推荐开启).
session.upload_progress.prefix[=upload_progress_] : 进度数据将存储在_SESSION[session.upload_progress.prefix . _POST[session.upload_progress.name]]
session.upload_progress.name[=PHP_SESSION_UPLOAD_PROGRESS] : 如果_POST[session.upload_progress.name]没有被设置, 则不会报告进度.
session.upload_progress.freq[=1%] : 更新进度的频率(已经处理的字节数), 也支持百分比表示’%’.
session.upload_progress.min_freq[=1.0] : 更新进度的时间间隔(秒级)
;允许客户端单个POST请求发送的最大数据 M
post_max_size=2048M
;接受所有数据到开始执行脚本的最大时间 S
max_input_time=60
;脚本的最大执行时间 S
max_execution_time=0
;是否开启文件上传功能
file_uploads = On
;文件上传的临时目录
upload_tmp_dir="C:\xampp\tmp"
;允许单个请求上传的最大文件大小 M
upload_max_filesize = 2048M
;允许单个POST请求同时上传的最大文件数量
max_file_uploads = 20
【2】 _FILES变量简介
- $_FILES["file"]["name"] - 被上传文件的名称
- $_FILES["file"]["type"] - 被上传文件的类型
- $_FILES["file"]["size"] - 被上传文件的大小,以字节计
- $_FILES["file"]["tmp_name"] - 存储在服务器的文件的临时副本的名称
- $_FILES["file"]["error"] - 由文件上传导致的错误代码
文件上传表单
设置session.upload_progress.name key的值
- <?php
- if (version_compare(phpversion(), '5.4.0', '<'))
- exit('ERROR: Your PHP version is ' . phpversion() . ' but this script requires PHP 5.4.0 or higher.');
- if (!intval(ini_get('session.upload_progress.enabled')))
- exit('session.upload_progress.enabled is not enabled, please activate it in your PHP config file to use this script.');
- require_once ("upload.class.php");
- ?>
- <!doctype html>
- <html>
- <head>
- <meta charset="utf-8">
- </head>
- <body>
- <form id="upload-form" action="upload.php" method="POST" enctype="multipart/form-data">
- <!--设置session.upload_progress.name Key的值-->
- <input type="hidden"
- name="<?php echo ini_get("session.upload_progress.name"); ?>" value="<?php echo CUpload::UPLOAD_PROGRESS_PREFIX; ?>" />
- <table>
- <tr>
- <td><input name="file1[]" type="file" align="right"/></td>
- <td><input type="submit" name="Submit" value="上传"/></td>
- </tr>
- </table>
- </form>
- </body>
- </html>
文件上传处理类
- <?php
- class CUpload
- {
- const UPLOAD_PROGRESS_PREFIX = 'progress_bar';
- private $_sMsg, $_sUploadDir, $_sProgressKey;
- // The short array syntax (only for PHP 5.4.0 and higher)
- private $_aErrFile = [
- UPLOAD_ERR_OK => 'There is no error, the file uploaded with success.',
- UPLOAD_ERR_INI_SIZE => 'The uploaded file exceeds the upload_max_filesize directive in php.ini.',
- UPLOAD_ERR_FORM_SIZE => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.',
- UPLOAD_ERR_PARTIAL => 'The uploaded file was only partially uploaded.',
- UPLOAD_ERR_NO_FILE => 'No file was uploaded.',
- UPLOAD_ERR_NO_TMP_DIR => 'Missing a temporary folder.',
- UPLOAD_ERR_CANT_WRITE => 'Failed to write file to disk.',
- UPLOAD_ERR_EXTENSION => 'A PHP extension stopped the file upload.'
- ];
- public function __construct()
- {
- // Session initialization
- if ('' === session_id()) session_start();
- $this->_sUploadDir = 'uploads/';
- $this->_sProgressKey = strtolower(ini_get('session.upload_progress.prefix') . static::UPLOAD_PROGRESS_PREFIX);
- }
- public function __destruct()
- {
- if ('' !== session_id())
- {
- $_SESSION = array();
- session_destroy();
- }
- }
- /**
- * @return object this
- */
- public function addFile()
- {
- if(!empty($_FILES))
- {
- $this->_sMsg = '';
- foreach($_FILES as $sKey => $aFiles)
- {
- for($i = 0, $iNumFiles = count($aFiles['tmp_name']); $i < $iNumFiles; $i++)
- {
- /**
- * 获取上传文件的参数
- */
- $iErrCode = $aFiles['error'][$i];
- $iSize = $aFiles['size'][$i];
- $sFileName = $aFiles['name'][$i];
- $sTmpFile = $aFiles['tmp_name'][$i];
- $sFileDest = $this->_sUploadDir . $sFileName;
- $sTypeFile = $aFiles['type'][$i];
- /**
- * 检测文件类型
- */
- //$bIsImgExt = (strtolower(substr(strrchr($sFileName, '.'), 1))); // Get the file extension
- //if(($bIsImgExt == 'jpeg' || $bIsImgExt == 'jpg' || $bIsImgExt == 'png' || $bIsImgExt == 'gif') && (strstr($sTypeFile, '/', true) === 'image'))
- {
- if($iErrCode == UPLOAD_ERR_OK)
- {
- move_uploaded_file($sTmpFile, $sFileDest);
- $this->_sMsg .= '<p style="color:green; font-weight:bold; text-align:center">Successful "' . $sFileName . '" file upload!</p>';
- $this->_sMsg .= '<p style="text-align:center">Image type: ' . str_replace('image/', '', $sTypeFile) . '<br />';
- $this->_sMsg .= 'Size: ' . round($iSize / 1024) . ' KB<br />';
- $this->_sMsg .= '<a href="' . $sFileDest . '" title="Click here to see the original file" target="_blank"><img src="' . $sFileDest . '" alt="' . $sFileName . '" width="300" height="250" style="border:1.5px solid #ccc; border-radius:5px" /></a></p>';
- }
- else
- {
- $this->_sMsg .= '<p style="color:red; font-weight:bold; text-align:center">Error while downloading the file "' . $sFileName . '"<br />';
- $this->_sMsg .= 'Error code: "' . $iErrCode . '"<br />';
- $this->_sMsg .= 'Error message: "' . $this->_aErrFile[$iErrCode] . '"</p>';
- }
- }
- //else
- {
- // $this->_sMsg .= '<p style="color:red; font-weight:bold; text-align:center">File type incompatible. Please save the image in .jpg, .jpeg, .png or .gif</p>';
- }
- }
- }
- }
- else
- {
- $this->_sMsg = '<p style="color:red; font-weight:bold; text-align:center">You must select at least one file before submitting the form.</p>';
- }
- return $this;
- }
- /**
- * 中断文件上传
- *
- * @return object this
- */
- public function cancel()
- {
- if (!empty($_SESSION[$this->_sProgressKey]))
- $_SESSION[$this->_sProgressKey]['cancel_upload'] = true;
- return $this;
- }
- /**
- * @return 上传进度
- */
- public function progress()
- {
- if(!empty($_SESSION[$this->_sProgressKey]))
- {
- $aData = $_SESSION[$this->_sProgressKey];
- $iProcessed = $aData['bytes_processed'];
- $iLength = $aData['content_length'];
- $iProgress = ceil(100*$iProcessed / $iLength);
- }
- else
- {
- $iProgress = 100;
- }
- return $iProgress;
- }
- /**
- * @return object this
- */
- public function show()
- {
- ob_start();
- echo '<p><strong>$_FILES Result:</strong></p><pre>';
- var_dump($_FILES);
- echo '</pre>';
- echo '<p><strong>$_SESSION Result:</strong></p><pre>';
- var_dump($_SESSION);
- echo '</pre>';
- $this->_sMsg = ob_get_clean();
- return $this;
- }
- /**
- * Get the JSON informational message.
- *
- * @param integer $iStatus, 1 = success, 0 = error
- * @param string $sTxt
- * @return string JSON Format.
- */
- public static function jsonMsg($iStatus, $sTxt)
- {
- return '{"status":' . $iStatus . ',"txt":"' . $sTxt . '"}';
- }
- /**
- * Get the informational message.
- *
- * @return string
- */
- public function __toString()
- {
- return $this->_sMsg;
- }
- }
执行文件上传操作
- <?php
- require_once ("upload.class.php");
- $upload = new CUpload;
- $upload->addFile();
- echo $upload;
- /*$_SESSION["upload_progress_testUpload"] = array(
- "start_time" => 1234567890, // 请求时间
- "content_length" => 57343257, // 上传文件总大小
- "bytes_processed" => 453489, // 已经处理的大小
- "done" => false, // 当所有上传处理完成后为TRUE
- "files" => array(
- 0 => array(
- "field_name" => "file1", // 表单中上传框的名字
- // The following 3 elements equals those in $_FILES
- "name" => "foo.avi",
- "tmp_name" => "/tmp/phpxxxxxx",
- "error" => 0,
- "done" => true, // 当这个文件处理完成后会变成TRUE
- "start_time" => 1234567890, // 这个文件开始处理时间
- "bytes_processed" => 57343250, // 这个文件已经处理的大小
- ),
- // An other file, not finished uploading, in the same request
- 1 => array(
- "field_name" => "file2",
- "name" => "bar.avi",
- "tmp_name" => NULL,
- "error" => 0,
- "done" => false,
- "start_time" => 1234567899,
- "bytes_processed" => 54554,
- ),
- )
- );*/
- ?>
- <?php
- session_start();
- require_once ("upload.class.php");
- echo (new CUpload())->progress();
- ?>
UI使用一些插件上传文件,就可以获取上传进度,不用这么麻烦