获取文件上传进度的方法很多,该文介绍的是使用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使用一些插件上传文件,就可以获取上传进度,不用这么麻烦,例如 Webuploader。