Interesting ajax/php uploader
I created an ajax/php uploader that I wanted to share as it may be usefull for others. It is a bit slow just using hex but it picks up on where it leaves off. It show progress and multiple files.
Code:
<?php
$MAXPOSTSIZE=50000;
$name="";
$mtime="";
$size="";
$blob="";
$start=0;
$end=$MAXPOSTSIZE;
if(sizeof($argv)==2)
{$arguments=explode("&",$argv[1]);
foreach($arguments as $argument)
{$key_value=explode("=",$argument);
if(sizeof($key_value!=1))
{$_REQUEST[$key_value[0]]=$key_value[1];
}
else
{$_REQUEST[$key_value[0]]="";
}}}
foreach($_REQUEST as $key=>$value)
{if($key=="name"){$name=$value;}
if($key=="mtime"){$mtime=$value;}
if($key=="size"){$size=$value;}
if($key=="mtime"){$mtime=$value;}
if($key=="start"){$start=$value;}
if($key=="end"){$end=$value;}
if($key=="blob"){$blob=$value;}
}
if($name!="")
{
$tempfile="/tmp/".$name."-".$mtime."-".$size.".tmp";
$constructfile="/tmp/".$name."-".$mtime."-".$size.".part";
$writeblob=false;
if(file_exists($tempfile))
{list($pstart,$pend)=explode(":",file_get_contents($tempfile));
}
else
{$pstart=0;
$pend=$MAXPOSTSIZE;
if($pend>$size){$pend=$size;}
}
if($pstart==$start&&$pend==$end)
{$writeblob=true;
}
else
{$start=$pstart;
$end=$pend;
}
if($writeblob)
{for($x=0;$x<strlen($blob);$x+=2)
{$byte=chr(intval($blob[$x].$blob[$x+1],16));
file_put_contents($constructfile,$byte,FILE_APPEND | LOCK_EX);
}
if($end==$size)
{unlink($tempfile);
rename($constructfile,"/tmp/".$name);
$start=$end;
}
else
{$start+=$MAXPOSTSIZE;
$end=$start+$MAXPOSTSIZE;
if($end>$size){$end=$size;}
file_put_contents($tempfile,$start.":".$end);
}}
header ("content-type: text/xml");
print "<data>\n";
print "<name>".$name."</name>\n";
print "<mtime>".$mtime."</mtime>\n";
print "<size>".$size."</size>\n";
print "<start>".$start."</start>\n";
print "<end>".$end."</end>\n";
print "</data>\n";
}
else
{
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript">
var files;
function pad(hexnum)
{if(hexnum.length<2){return "0"+hexnum;}
return hexnum
}
function toHex(str)
{var hex = '';
var myreplace='';
for(var i=0;i<str.length;i++)
{hex += pad(''+str.charCodeAt(i).toString(16));
}
return hex;
}
function readBlob(file,start,stop)
{var reader = new FileReader();
// If we use onloadend, we need to check the readyState.
reader.onloadend = function(evt)
{if (evt.target.readyState == FileReader.DONE)
{// DONE == 2
var data="name="+file.name+"&mtime="+file.lastModifiedDate.valueOf()+"&size="+file.size+"&start="+start+"&end="+stop+"&blob="+toHex(evt.target.result);
ajax(next,"",data);
}};
var blob = file.slice(start, stop);
reader.readAsBinaryString(blob);
}
function start_upload(file)
{var data="name="+file.name+"&mtime="+file.lastModifiedDate.valueOf()+"&size="+file.size+"&start=0&end=0";
ajax(next,"",data);
}
function getfileindex(name)
{for (var i = 0 ; i< files.length; i++)
{if(files[i].name==name)
{return i;
}}
return -1;
}
function next(xmlhttp)
{var xmldata=xmlhttp.responseXML;
var start=xmldata.getElementsByTagName("start")[0].childNodes[0].nodeValue;
var end=xmldata.getElementsByTagName("end")[0].childNodes[0].nodeValue;
var file=getfileindex(xmldata.getElementsByTagName("name")[0].childNodes[0].nodeValue);
if(start!=end)
{document.getElementById("complete"+file).innerHTML=files[file].name+" "+end+" of "+files[file].size;
readBlob(files[file],start,end)
}
else
{//done
document.getElementById("complete"+file).innerHTML=files[file].name+" finnished";
}}
function ajax(afunction,url,data)
{var xmlhttp = false;
if(window.XMLHttpRequest)
{// Mozilla, Safari, Chrome,...
xmlhttp = new XMLHttpRequest();
// set type accordingly to anticipated content type
//xmlhttp.overrideMimeType('text/xml');
if (xmlhttp.overrideMimeType)
{xmlhttp.overrideMimeType('text/xml');
}}
else if(window.ActiveXObject)
{// IE
try
{xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e)
{try
{xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e)
{
}}}
if(!xmlhttp){alert('Cannot create XMLHTTP instance');return false;}
xmlhttp.open('POST',url, false);
xmlhttp.onreadystatechange=function()
{if (xmlhttp.readyState==4)
{afunction(xmlhttp);
}};
xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlhttp.send(data);
}
function start_uploading()
{files=document.getElementById("files").files;
var html="";
for(var i=0;i<files.length;i++)
{html+='<div id="complete'+i+'"></div>';
}
document.getElementById("complete").innerHTML=html;
for(var i=0;i<files.length;i++)
{start_upload(files[i]);
}}
</script>
</head>
<body>
<input type="file" id="files" name="files[]" multiple />
<button onclick="start_uploading()">start upload</button>
<div id="complete"></div>
</body>
</html>
<?php
}
?>