これはphpのsession.upload-progressのサンプルです。
# .htaccess
# テストで1GBぐらいまでOKにする。
php_value post_max_size 1024M
php_value upload_max_filesize 1024M
# アップロードが終わっても情報を残す。
php_value session.upload_progress.cleanup Off
<?php
/**
* アップロードのサンプル
*
* php5.3以上
*/
function return_bytes($val)
{
$val = trim($val);
$last = strtolower($val[strlen($val)-1]);
switch($last)
{
// 'G' は PHP 5.1.0 以降で使用可能です
case 'g':
$val *= 1024;
case 'm':
$val *= 1024;
case 'k':
$val *= 1024;
}
return $val;
}
function MAIN()
{
session_start();
$fileName = basename(__FILE__);
$uploadProgressName = "001";
$uploadProgressId = ini_get("session.upload_progress.prefix") . $uploadProgressName;
$uploadFile = "/tmp/abc.txt";
$allowExt = array(
"maxFileSize" => return_bytes(ini_get("upload_max_filesize")),
"uploadProgressNameKey" => ini_get("session.upload_progress.name"),
"uploadProgressNameValue" => $uploadProgressName,
"allowExt" => array("jpg", "png", "gif", "iso"),
);
$action = isset($_REQUEST["action"]) ? $_REQUEST["action"] : "default";
switch ($action)
{
case "uploadResult":
print `ls -l --time-style="+%Y-%m-%d %H:%M:%S" {$uploadFile} && md5sum {$uploadFile}`;
exit;
case "getConfig":
print json_encode($allowExt);
exit;
case "status":
printf("%d", 100 * $_SESSION[$uploadProgressId]["bytes_processed"] / $_SESSION[$uploadProgressId]["content_length"]);
exit;
case "upload":
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadFile))
{
echo "File is valid, and was successfully uploaded.\n";
}
else
{
echo "Possible file upload attack!\n";
}
exit;
case "default":
break;
default:
trigger_error("unknown action={$action}.", E_USER_ERROR);
}
return array($fileName, $uploadProgressId, $uploadFile);
}
list($fileName, $uploadProgressId, $uploadFile) = MAIN();
?>
<html>
<head>
<meta content='IE=100' http-equiv='X-UA-Compatible'/>
<meta content='text/css' http-equiv='Content-Style-Type'/>
<meta content='text/javascript' http-equiv='Content-Script-Type'/>
<meta content='text/html; charset=UTF-8' http-equiv='Content-Type'/>
<title></title>
<script src="/js/jquery-1.8.3.min.js"></script>
<script>
(function(){
$(document).ready(function(){
var waitTime = 500;
var minWaitTime = 250;
var fileName = function(){
var url = window.location.pathname;
return url.substring(url.lastIndexOf('/')+1);
}();
$.ajaxSetup({cache:false});
$("form[id^=uploadProgress]").each(function(){
var formId = $(this).attr("id");
var formElem = $("#" + formId);
var buttonElem = $("#" + formId + "Button");
var inputFileElem = $("#" + formId + "InputFile");
var barElem = $("#" + formId + "Bar");
var messageElem = $("#" + formId + "Message");
var config;
var setButtonElem = function(){
setTimeout(function(){
if (config)
{
buttonElem.click(function(){
inputFileElem.click().focus();
});
var inputHiddenElem = $(document.createElement("input")).attr("type", "hidden");
formElem.prepend(inputHiddenElem.clone().
attr("name", config.uploadProgressNameKey).
attr("value", config.uploadProgressNameValue));
formElem.prepend(inputHiddenElem.clone().attr("name", "MAX_FILE_SIZE").attr("value", config.maxFileSize));
}
else
{
setButtonElem();
}
}, 1000);
};
$.getJSON(fileName, {action:"getConfig"}, function(json){
config = json;
messageElem.text("拡張子: " + config.allowExt.join(", "));
});
setButtonElem();
inputFileElem.change(function(){
var startPercent = 0;
var reloadStatus = function(){
setTimeout(function(){
$.get(
fileName, {action:"status"},
function(data, status, XHR)
{
var dataInt = parseInt(data, 10);
var endPercent = dataInt;
if (startPercent !== 0)
{
if ((endPercent - startPercent) > 5)
{
waitTime = Math.max(parseInt(waitTime / 2, 10), minWaitTime);
}
else
{
waitTime = waitTime * 2;
}
}
startPercent = endPercent;
if (!isNaN(dataInt))
{
barElem.html(String(dataInt) + "%");
if (dataInt >= 0 && dataInt < 100)
{
reloadStatus();
}
else if (dataInt == 100)
{
$.get(fileName, {action:"uploadResult"},
function(data, status, XHR)
{
messageElem.text("アップロード完了: \n" + String(data)).css("white-space", "pre");
});
}
}
}
);
}, waitTime);
};
if (-1 == $.inArray($(this).attr("value").replace(/^.*\.([^.]+)$/, "$1").toLowerCase(), config.allowExt))
{
messageElem.text("拡張子エラー: " + $(this).attr("value"));
return;
}
buttonElem.css("display", "none");
formElem.submit();
barElem.html("0%");
reloadStatus();
});
});
});
})();
</script>
</head>
<body>
<a href="<?=$fileName?>" target="">Reload</a>
<form enctype="multipart/form-data" action="<?=$fileName?>" method="POST" id="uploadProgress001" target="uploadProgress001Result">
<hr />
<input type="hidden" name="action" value="upload" />
<iframe name="uploadProgress001Result" style="display:none;"></iframe>
<input id="uploadProgress001InputFile" style="display:none;" name="userfile" type="file" />
<span id="uploadProgress001Button" style="cursor:pointer;color:blue;text-decoration:underline;">アップロード</span>
<span id="uploadProgress001Bar" style="display: block;font-family: monospace;text-align: right;width: 2em;"></span>
<span id="uploadProgress001Message"></span>
<hr />
</form>
<?=htmlspecialchars(`ls -l --time-style="+%Y-%m-%d %H:%M:%S" $uploadFile`)?>
<pre><?=htmlspecialchars(var_export($_SESSION[$uploadProgressId], true))?></pre>
</body>
</html>