We successfully set up image uploading on our server with nginx. Everything gets posted to /upload and then redirects to /file for processing. The file gets uploaded and stored, but there are headers at the top of the file.
------WebKitFormBoundaryqUwBABts5uiLHgDN
Content-Disposition: form-data; name="picture"; filename="coldplay.jpg"
Content-Type: image/jpeg
What am I to do with this? Do I strip these headers out with PHP and then save the file again?
Is uploading files with these headers expected behavior?
Here is the form:
<form action="/upload/" id="upload3" method="post">
<input type="file" id="file" name="picture" value=""/>
<input type="submit" onclick="return uploadFiles(this.form);">
</form>
and js:
<script type="text/javascript">
function uploadFiles(form) {
var formData = new FormData(form);
var url = "/upload/";
var xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.onload = function(e) {
if (this.status == 200) {
console.log(this.responseText);
}
};
xhr.send(formData); // multipart/form-data
return false;
}
</script>
I'm using these lines of code to strip the first four lines from our uploaded image files. I found it somewhere on SO and it works great -- unfortunately I don't know where it was.
$line_to_strip = 4;
$new_file = new SplFileObject($file_full_new, 'w');
foreach (new LimitIterator(new SplFileObject($file_full), $line_to_strip) as $line)
$new_file->fwrite($line);
I don't know if this is our permanent solution, however.
Related
I am learning ajax and I have followed a tutorial to post some data to a text file via a php script but I can't get it to work. Is there something I have missed.
the following is the ajax.html page which is a input text with a button to post the data via ajax
<form name="testform">
Off Min:<input name="setOffMin" type="text" id="setOffMin" maxlength="2" size="1"/></br>
<button type="button" onclick="postStuff();">Submit</button>
</form>
<div id="status"></div>
<script type="text/javascript">
function postStuff(){
var hr = new XMLHttpRequest();
var url = "update.php";
var offM = document.getElementById("setOffMin").value;
hr.open("POST", url, true);
hr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
hr.onreadystatechange = function(){
if (hr.readyState == 4 && hr.status == 200){
var return_data = hr.responseText;
document.getElementById("status").innerHTML = return_data;
}
}
hr.send(offM);
document.getElementById("status").innerHTML = "processing...";
}
</script>
this is the update.php file
<?php
$setOffMin = $_POST["offM"];
$f = fopen("test.txt", "w");
fwrite($f, $setOffMin);
fclose($f);
?>
I have been looking over this code all last night and cannot work out why it is not writing the data to the text file.
I have run the php script editing out the $_POST and putting in a variable and it does write to the text file. So the php should work and the text file permission is correct. I expect this is the ajax that I have done wrong.
any help will be great
You need to send offM as urlencoded like this:
var offM = 'offM='+document.getElementById("setOffMin").value;
Now when you click on Submit you call update.php?offM=YourText and PHP recieve var $_POST['offM'] with value YourText
I need help with creating a progress bar for my php upload site. I've got the upload and exctract part sorted but i need help with the progress bar. I'm not sure how to do it. Also, is there a maximum file size for the upload?
HTML
<?php if($message) echo "<p>$message</p>"; ?>
<form enctype="multipart/form-data" method="post" action="">
<label>Choose file (.zip): <input type="file" name="zip_file" /></label>
<br />
<input type="submit" value="Upload" name="submit" value="Upload" />
</form>
PHP
<?php
if($_FILES["zip_file"]["name"]) {
$filename = $_FILES["zip_file"]["name"];
$source = $_FILES["zip_file"]["tmp_name"];
$type = $_FILES["zip_file"]["type"];
$name = explode(".", $filename);
$accepted_types = array(
'application/zip',
'application/x-zip-compressed',
'multipart/x-zip',
'application/x-compressed');
foreach($accepted_types as $mime_type) {
if($mime_type == $type) {
$okay = true;
break;
}
}
$continue = strtolower($name[1]) == 'zip' ? true : false;
if(!$continue) {
$message = "[...] not a .zip file. Please try again.";
}
$target_path = "./".$filename;
if(move_uploaded_file($source, $target_path)) {
$zip = new ZipArchive();
$x = $zip->open($target_path);
if ($x === true) {
$zip->extractTo("./");
$zip->close();
unlink($target_path);
}
$message = "Your .zip file was uploaded and unpacked.";
} else {
$message = "There was a problem with the upload. Please try again.";
}
}
?>
You can make some changes to fit but this works rather well if you want a progress bar. You can add more eventlisteners and make it how you want. I hope this is a good starting point for you.
function uploadFile(){
var file = document.getElementById("zip_file").files[0];
var formdata = new FormData();
formdata.append("zip_file", file);
var ajax = new XMLHttpRequest();
ajax.upload.addEventListener("progress", function(event) { runprogress(event); } , false);
ajax.addEventListener("load", function(event) {uploadcomplete(event); }, false);
//Target your php file.
ajax.open("POST", "upload.php");
ajax.send(formdata);
}
function runprogress(event){
//The progress %, you might want to Math.round(percent)
var percent = (event.loaded / event.total) * 100;
}
function uploadcomplete(event){
//This will = to your php reply.
var AjaxReply=event.target.responseText;
}
As far as I know you would have to use JavaScript to do this. Post your data through an AJAX call and initialize the progress bar. Over time animating it so that the bar "fills up".
Eventually the AJAX call will complete and will send a response back, upon the completion of the call you can finish the animation. This is how I would assume most progress bars work as they typically go up then stop around 99% until the post returns it's "complete status".
In any case, you would have a progress bar, represented by a <div> for example, with a width that would increase as time goes on, or a number would go up etc... and you would animate this using JavaScript and/or jQuery. Hopefully this will get you started in the right direction.
EDIT
Here's a link to a tutorial describing the steps necessary to upload files to the server using AJAX: Uploading Files with AJAX
I'm using lighttpd + PHP 5.4 running with FastCGI on buildroot embedded linux.
I have written some time ago a modified version of PHP file upload progress script using following tutorial: http://phpmaster.com/tracking-upload-progress-with-php-and-javascript/
I was previously working on Slackware Apache with mod_php and everything worked fine.
Unfortunately, the script is not working. I have made sure that in php.ini session.upload_progress = On and sessions are enabled. I have verified that sessions are working in general by using two simple php files as in 4. post here http://quirm.net/forum/topic.php?id=3950.
The script is supposed to show loading screen and percentage of file upload. It is achieved by sending progress.php requests every 0.2 second. Unfortunately, no matter how large is the file (I use ~13 MB files for testing, I have ensured that the file upload size in php.ini accepts this size) the upload ends after first request because it returns 100. I have debbuged progress.php and it looks that the whole $_SESSION variable is empty.
Here is my form HTML code:
<form enctype="multipart/form-data" action="actions/upload_upgrade.php" method="post" target="hidden_iframe" onsubmit="upload_type='config'; startUpload('config_form')" id="config_form">
<p class="stdtext">
Select File:
<input type="hidden" name="type" value="config">
<input type="hidden" value="config_form"
name="<?php echo ini_get("session.upload_progress.name"); ?>">
<input type="file" size="35" name="userfile" />
<br><br>
<input type="submit" class="defaultbtn" name="Upload" value="Upload" onclick="showLoadingScreen(true)"/>
</p>
</form>
My Javascript code (please note that upload and response handling functions are made universal because they accept uploads from several different forms that are used to upload configuration, firmware etc.).
function sendUploadRequest(form_name)
{
job_name="Upload";
var http = createRequestObject();
http.open("GET", "actions/progress.php?form_name="+form_name);
http.onreadystatechange = function () { handleResponse(http,"sendUploadRequest('"+form_name+"')"); };
http.send(null);
}
function startUpload(form_name)
{
showLoadingScreen(true);
postDataSync("actions/uw.php");
document.getElementById("loadingtext").innerHTML="Uploading file...";
setTimeout("sendUploadRequest('"+form_name+"')", 200);
}
function handleResponse(http,fun_name)
{
hideInfo();
var response;
if (http.readyState == 4)
{
response = http.responseText;
document.getElementById("loadingtext").innerHTML = response + "%";
if (response < 100)
{
setTimeout(fun_name, 200);
}
else
{
showLoadingScreen(false);
if(job_name=="")
printInfo("Job completed successfuly");
else
{
if(job_name=="Upload"&&upload_type=="config")
{
if(hidden_iframe.window.document.body.innerHTML=="SUCCESS")
{
printInfo(job_name+" completed successfuly");
showLoadingScreen(true);
document.getElementById("loadingtext").innerHTML="Restoring backup...";
var result=postDataSync("actions/extract_backup.php");
showLoadingScreen(false);
if(result.substring(0,5)=="ERROR")
{
printError("Error while extracting backup configuration:<br><br>"+result.substring(6));
}
else if(result.substring(0,7)=="SUCCESS")
{
printInfo("Backup configuration restored successfully");
}
else
{
printError("Unknown error while extracting backup. Please contact service.");
}
}
else
{
printInfo(job_name+" was not completed because of errors");
}
}
else
{
if(hidden_iframe.window.document.body.innerHTML=="SUCCESS")
printInfo(job_name+" completed successfuly");
else
printError(job_name+" was not completed because of errors");
}
}
}
}
}
function createRequestObject()
{
var http;
if (navigator.appName == "Microsoft Internet Explorer")
{
http = new ActiveXObject("Microsoft.XMLHTTP");
}
else
{
http = new XMLHttpRequest();
}
return http;
}
And my PHP code progress.php:
<?php
session_start();
//print_r($_SESSION);
$key = ini_get("session.upload_progress.prefix") . $_GET['form_name'];
if (!empty($_SESSION[$key])) {
$current = $_SESSION[$key]["bytes_processed"];
$total = $_SESSION[$key]["content_length"];
echo $current < $total ? ceil($current / $total * 100) : 100;
}
else {
echo 100;
}
On http://de3.php.net/manual/de/session.upload-progress.php it's said: "Note, this feature doesn't work, when your webserver is runnig PHP via FastCGI."
I've simplified my code for uploading a file without iFrame or flash engine, and i came up to this ajax function:
<input type="file" name="uploadfile" id="myfile" /><label for="file" id="progress"></label>
<script src="js/jquery-1.7.1.min.js"></script>
<script>
function uploadFile(files) {
var xmlhttp;
if(window.XMLHttpRequest)
xmlhttp = new XMLHttpRequest();
else
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.upload.onprogress = function(e) {
$("#progress").empty().append(e.loaded + " - " + e.total);
}
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
alert(xmlhttp.responseText + "DONE!");
}
}
xmlhttp.open("post", "post.php", true);
xmlhttp.setRequestHeader("If-Modified-Since", "Mon, 26 Jul 1997 05:00:00 GMT");
xmlhttp.setRequestHeader("Cache-Control", "no-cache");
xmlhttp.setRequestHeader("X-Requested-With", "XMLHttpRequest");
xmlhttp.setRequestHeader("X-File-Name", files[0].fileName);
xmlhttp.setRequestHeader("Content-Type", "multipart/form-data");
xmlhttp.send(files[0]);
}
$(document).ready(function() {
$("#myfile").change(function() {
uploadFile(this.files);
});
});
</script>
This is the php code which reply to the ajax function:
<?php
if(isset(
$_SERVER['CONTENT_TYPE'],
$_SERVER['CONTENT_LENGTH'],
$_SERVER['HTTP_X_FILE_NAME']
) &&
$_SERVER['CONTENT_TYPE'] == 'multipart/form-data'){
$file->name = basename($_SERVER['HTTP_X_FILE_NAME']);
$input = fopen('php://input', 'rb');
$file = fopen('files/'.$file->name, 'wb');
stream_copy_to_stream($input, $file);
fclose($input);
fclose($file);
} else {
echo "Error";
}
?>
The problem is, sometimes it works sometimes it bugs up while trying to upload the same file. I hope there is a solution to fix this issue. The code is simple, when i choose a file with input file type, the uploadFile function executes.
When it bugs out, i can see the file starting to be uploaded but it doesnt have the original size, so somewhere it could bug and stop uploading.
Thank you in advance, Daniel!
I'm not sure it is your problem, but you should anyway make sure your server allows for uploading large enough files and can handle them without timing out.
You can set this in code or php.ini (example in code:)
ini_set('memory_limit', '96M');
ini_set('post_max_size', '64M');
ini_set('upload_max_filesize', '64M');
Then, make sure your server does not time out:
$seconds=120;
set_time_limit ( $seconds );
All this code coes on the top of your PHP file.
I need to take a CSV file from the client's machine and extract the data from it. I cannot save this CSV file, which is crucial (otherwise I would be laughing!). My PHP so far works like a charm:
upload.php
<?php
$file = $_FILES['file'];
if ($file['error'] === UPLOAD_ERR_OK) {
$ext = substr($file["name"], strrpos($file["name"], '.') + 1);
$maxSize = 3000000;
//Check file extension, MIME-type and size limit (3 MB).
if ($ext == "csv") {
if ($file["type"] == "text/csv" ||
$file["type"] == "text/comma-separated-values") {
if ($file["size"] < $maxSize) {
//CSV -> JSON
$fileAsArray = Array();
if (($handle = fopen($file["tmp_name"], "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$fileAsArray[] = $data;
}
fclose($handle);
}
echo json_encode($fileAsArray);
die(json_encode($fileAsArray));
}
else {
echo "File size: ".$file["size"]."bytes<br>Limit: ".$maxSize." (3MB)";
}
}
else {
echo "MIME-type: ".$file["type"]."<br>Required: text/csv";
}
}
else {
echo "File Extension: ".$ext."<br>Required: csv";
}
}
else
die("Cannot upload");
?>
Ignore the echo. It was just so I knew it was actually working. However, I've been using jQuery with this website and can't figure out the code to properly get the form to submit the file and retrieve the JSON data back (fileAsArray) at the same time. Here is my HTML/jquery in index.html:
<script type="text/javascript">
var csvData = {}; //My global variable (two-dimensional JSON array)
$(document).ready(function(){
$("#upload").click(function(){
alert('test');
$.ajax({
type: "POST",
url: "upload.php",
data: "don't know what goes here",
dataType: "json",
success: function (data) {
alert(data); //Tried everything here too. :(
}
});
});
});
and HTML:
<form method="POST" action="upload.php" enctype="multipart/form-data" class="file_upload">
<input id="getFile" type="file" name="file">
<input value="Extract Data" id="upload" type="button">
</form>
I tried type="submit" as well, and a bunch of other things including just a 'form' tag and letting jQuery handle the POST... Thanks. If there is a better way to do this, please let me know :)
(I've been struggling with this for several days now... Having gone through many renditions of the code outlined below, I've stripped it down to its basics.)
If you want to upload CSV data through an Ajax post request, you must read the content of the file and insert it into the data: "don't know what goes here" field. Currently, only HTML5 browsers provides FileReader API that enables JavaScript to read the file, for Internet Explorer you must use a Flash-based solution.
I wrote a jQuery plug-in before that works with HTML5 browsers and jQuery. It would work with jQuery 1.4 - I am not sure about jQuery 1.5.