I have a form that has multiple file uploads and each input is uniquely named, however, when attempting to get the uploaded file, my test if showing false.
Please find the code below. I am at a loss as to why this is happening.
<label class="label" for="uploadfile">Contract:</label>
<input name="'.$ICP.'_uploadedfile" id="'.$ICP.'_uploadedfile" type="file" />
The $ICP var is looped out, as there can be multiple instances, so this way each name is unique and on the server side, the POST is requested for each loop of the ICP.
while($icp_details = mysqli_fetch_array($ICP_exist_qry)){
$ICP_ID = stripslashes($icp_details['ICP_ID']);
if(!file_exists($_FILES[$ICP_ID."_uploadedfile"]['tmp_name']) || !is_uploaded_file($_FILES[$ICP_ID."_uploadedfile"]['tmp_name'])) {
echo false;
} else {
echo true;
}
}
I am not having any problems retrieving the values of the other posted inputs, just the files uploaded part.
Any help on this one is appreciated. :)
Note: Form is being submitted by Ajax.
To upload the file correctly using Ajax (and in this case JQuery) you need to use the FormData object. The code snippet below illustrates how it can be used. It is used instead of the .serialize() or .serializeArray() methods.
$('#file-form').submit(function(e) {
$.ajax({
url: 'http://example.com/upload/',
type: 'POST',
data: new FormData(this),
processData: false,
contentType: false
});
e.preventDefault();
});
Related
I am having trouble uploading a picture file via AJAX.
Web:
<div>
<form id="birdi_image_form">
<input type="file" name="birdi_image" id="birdi_image" ></input>
</form>
<input type="text" name="species"></input>
<textarea name="comments"></textarea>
</div>
<div id="debug"></div>
<script type="text/javascript">
jQuery(function($){
$('#birdi_image').change(function(){
var ima = new FormData($('#birdi_image_form')[0]);
$.ajax({
url:"/bird/bird_scripts/fu.php",
type:"post",
data: ima,
processData: false,
dataType:"text",
success:function(data, textStatus, jqXHR) {
$('#debug').text(data);
}
});
});
});
</script>
/bird/bird_scripts/fu.php:
<?php
$imagedir = '/images';
$tmpfname = tempnam($imagedir, "b_");
echo var_dump($_POST);
if (move_uploaded_file($_FILES['birdi_image']['tmp_name'], $tmpfname)) {
echo "File is valid, and was successfully uploaded.\n";
} else {
echo "Upload failed";
}
?>
From looking around online I was expecting to find contents in my $_FILES variable, but this is empty. Dumping out the $_POST var to the screen like in the example gives me the following. $_POST['birdi_image'] gives me NULL.
array(68) { ["------WebKitFormBoundaryYCAoI8shwgBavjJP
Content-Disposition:_form-data;_name"]=> string(339) ""birdi_image";
filename="test.jpg" Content-Type: image/jpeg ����JFIFdd��
ExifMMbj(1r2��i��B#'B#'Adobe Photoshop
CS2 Windows2008:06:24 11:11:48��b�g"
["?o��(�ci�\�R��Μꟑ���]T��z���"]=> string(82) "���
f�zߠ����i���/��v��E~��[,�Y
�s�������1l�G����-���߿�enu'=�v�z���=?Ҳ���"
["�{��<o��ӗ�M��ysnʨo87~;l���۔�"]=> string(172) "�<��t�2~���O�S
�����t���㵺C�}E������}��I�d]c���y}#�����C,�Z��־��V��ynʿ��?�g�*����o��ٌ�.}�y����}��z����w^�]�m�u������z>�37�_C긵��K𭪣�Y-{��뺷��M���ul��Y�"
["c�yhHp����"]=> string(152)
"��[-���1�]��|�����۽Q�\�e���o�~��g������u�.���A��t�]�3�W�ד��b���}>�����%��K���Ѳ�3���zX��qZ��}u��sc�
���N� ^-w�7���\r� ����c��=?δX�j" ["C�uw���-��"]=> string(57)
"���m��w��������ѩ���������k��r����m�t�62rIk���m�ߗV��}" ["�"]=>
string(384)
"!�<��B���6*�c��劷Q���uF*��U��������ď,�y{R���������E%���Q����5.��IE���N�����Ο�̿4~R��...............Upload failed.
I have uploaded files before by using a complete form submit. This is the first time I am trying to do it with AJAX. It looks like the data is getting to the server, but I can't seem to make any sense of it from the server side. As you can see in the code I expected $_FILES['birdi_image'] to exist but it doesn't. Am I doing something completely wrong?
Thanks
You have to set the content type to false, otherwise jQuery will set one(the wrong one) for you
$.ajax({
url:"/bird/bird_scripts/fu.php",
type:"post",
data: ima,
processData: false,
contentType: false,
dataType:"text",
success:function(data, textStatus, jqXHR) {
$('#debug').text(data);
}
});
I struggled with this also - it's just not as easy as it should be. I finally found a guy who did it right, and studied his code.
Ravi Kusuma's jQuery File Upload
In the end, because Kusuma wrote a plugin, I just used his code/plugin. Why re-invent the wheel? He's got everything solved, right down to sending extra data along with the uploaded file.
I have the following form:
<form id="f-comment" class="form" method="post" action="submit_img_comment.php">
<textarea name="comment"></textarea>
<input type="submit" value="Publish" data-params='{"imageid":<?php echo $imageid; ?>}'>
</form>
and the following javascript:
$(document).on("submit", ".form", function(e) {
e.preventDefault();
// what form are you submitting?
var form = $("#" + e.target.id);
var data = new FormData(this);
var params = $("input[type=submit]", this).data("params"); // parameters to send along with data
data.append("params", params);
// data is ok
console.log(params)
$.ajax({
type: form.attr("method"),
url: "include/" + form.attr("action"),
data: data,
dataType: "json",
contentType: false,
processData: false,
cache: false
}).done(function(data) {
alert(data['msg']);
}).fail(function(data) {
alert("Error: Ajax Failed.");
}).always(function(data) {
// always do the following, no matter if it fails or not
})
});
in my php file (submit_img_comment.php) im able to get the comment, like this
$_POST['comment'];
But, when i try to get the imageid, like this
$_POST['imageid'];
I get the error: Undefined index: imageid
The comment is part of the form, but the imageid is send as a parameter and appended in FormData.
How do i get the imageid in my php file?
You are look at this all wrong, what you have appended to your form is not imageid but params. Also, what you are sending is a javascript object, you need to convert this to a string first. You will need to do the following in JavaScript:
var data = new FormData(this);
var params = $("input[type=submit]", this).data("params"); // parameters to send along with data
var json_params = JSON.stringify(params); // This converts your javascript object into a string that you can send to the server.
data.append("params", json_params); // We are adding the string we have converted from the javascript object.
Now that we have sent a JSON string to the server, we now need to decode it. To decode the JSON in php we use:
$params = json_decode($_POST['params']);
The variable $params will now be a php object which contains imageid as a property. This means that your image id is now stored in $params->imageid variable e.g. echo $params->imageid will output your image id.
As #baboizk has rightly mentioned, you should use isset() in PHP to make sure it actually exists before using it. E.g.
$params = json_decode($_POST['params']);
// Check that imageid exists.
if(isset($params->imageid) == true) {
// Do code that needs $params->imageid;
} else {
// Fail gracefully.
}
You are probably attempting to acces an unset value and this leads to a runtime error. $_POST does not have any element with the index 'imageid' so your program gets aborted by the interpreter before it ever gets to the null test.
Here is where isset() is handy for testing the existence of a variable or array element without actually trying to acces it.
http://php.net/manual/en/function.isset.php
Try
$_POST["params"]["imageid"]
I'm trying to check the progress of files uploaded. I'm using the Kohana framework which has a Session class, but for the upload progress I'm using native PHP sessions. I'm calling session_start() in Kohana's bootstrap.php, which means session_start() will be called on every page request.
After the upload form is submitted, I wait 1 second and then begin calling a PHP file to check the upload progress using jQuery $.ajax().
The problem is that $_SESSION[$key] ($key contains the key for the upload data) isn't set on the first call to the PHP. I've tried debugging this quite a bit, and session_id() returns the correct session ID, so the session is definitely the right one and is active. I'm also waiting 1 second before checking the upload progress, so it's not a timing issue. I could fix this by continuing even if $_SESSION[$key] is not set, but the way to check if the upload is complete is when $_SESSION[$key] is unset.
The HTML form is created on-the-fly with jQuery because this is a multi-file upload. Here's the HTML for a generated form:
<form action="ajax/upload" id="form-HZbAcYFuj3" name="form-HZbAcYFuj3" method="post" enctype="multipart/form-data" target="frame-HZbAcYFuj3">
<iframe id="frame-HZbAcYFuj3" name="frame-HZbAcYFuj3"></iframe>
<input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="HZbAcYFuj3">
<input type="file" id="file-HZbAcYFuj3" name="photo" accept="image/jpeg,image/pjpeg,image/png,image/gif">
<button type="button">+ Select Photo</button>
</form>
Here's the PHP that the JavaScript calls to check the progress:
public function action_uploadprogress()
{
$id = isset($_POST['id']) ? $_POST['id'] : false;
if (!$id)
throw new Kohana_HTTP_Exception_404();
$progress = 0;
$upload_progress = false;
$key = ini_get("session.upload_progress.prefix") . $id;
if (isset($_SESSION[$key]))
$upload_progress = $_SESSION[$key];
else
exit('100');
$processed = $upload_progress['bytes_processed'];
$size = $upload_progress['content_length'];
if ($processed <= 0 || $size <= 0)
throw new Kohana_HTTP_Exception_404();
else
$progress = round(($processed / $size) * 100, 2);
echo $progress;
}
Here's the jQuery ajax() request:
this.send_request = function()
{
$.ajax(
{
url: 'ajax/uploadprogress',
type: 'post',
dataType: 'html',
data: { id: _this.id },
success:
function(data, textStatus, jqXHR)
{
if (textStatus == "success")
{
if (data < 100)
setTimeout(_this.send_request, 1000);
}
}
}
);
};
You are sending a POST called 'id' to the PHP script.
However, the documentation says that the upload progress will be available only when you send a POST with same name as session.upload_progress.name configured in php.ini.
So, in other words, if your session.upload_progress.name is set to default value (PHP_SESSION_UPLOAD_PROGRESS), you have to change the following line, in send_request function:
Change:
data: { id: _this.id }
To:
data: { PHP_SESSION_UPLOAD_PROGRESS: _this.id }
You also have to change the $_POST['id'] to $_POST['PHP_SESSION_UPLOAD_PROGRESS'] or $_POST[ini_get("session.upload_progress.name")] in the PHP script (and the name of input too in case it's not default).
The upload progress will be available in the $_SESSION superglobal when an upload is in progress, and when POSTing a variable of the same name as the session.upload_progress.name INI setting is set to. When PHP detects such POST requests, it will populate an array in the $_SESSION, where the index is a concatenated value of the session.upload_progress.prefix and session.upload_progress.name INI options. The key is typically retrieved by reading these INI settings, i.e.
Source: http://php.net/manual/pt_BR/session.upload-progress.php
Lets see if I can get some of that sweet sweet bounty.. My first thought is that the $key string is not getting set properly.
Try echoing its value out and doing a print_r on the entire $_SESSION variable to keep track of things.
Now I don't see a 'success' output from action_uploadprogress() at all. I see 100 which I guess indicates done but you aren't checking for that in js. I would recommend looking into that. Might as well echo out your calculations as well. I assume its very unlikely but make sure that you are uploading files properly and are able to determine their current size without any issue.
Another issue could be with how you are handling ajax with jquery. I'm not 100% sure about this but I think the success option has been depreciated (1.5+).
From : http://api.jquery.com/jQuery.ajax/
$.ajax({
type: "POST",
url: "some.php",
data: { name: "John", location: "Boston" }
}).done(function( msg ) {
alert( "Data Saved: " + msg );
});
The only way I've seen success being used is like this....
$.ajax({
type: "POST",
url: '/login/spam',
data: formData,
success: function (data) {
if (data == 'value') {
//Do stuff
}
}
});
However I could be completely wrong about this....your setup might be perfectly fine. What I want you to do is get is directly in the success/done function is
alert(data);
alert(textStatus); //if you still use it
This will tell you if you are getting a proper response from your ajax query.
I will check back a few times tonight and I'll be around tomorrow to help. Tell me if anything I said helps anything.
This question already has answers here:
How can I upload files asynchronously with jQuery?
(34 answers)
Closed 9 years ago.
i have made a form that will be send a input type file, in my server side i want to get $_FILES value so i used print_r($_FILES), but in my ajax response i don't get anything value, here my code..
<form id="my_form">
<input type="file" id="image_file" name="image_file"/>
</form>
$('#my_form').submit(function() {
var data = $('#my_form').serialize();
$.ajax({
url: 'ajax.php',
type: 'POST',
data: data,
enctype: 'multipart/form-data',
success: function(response) {
alert(response);
},
});
return false;
});
and here my php code
<?php
$name = $_FILES['image_file']['name']; // get the name of the file
$type = $_FILES['image_file']['type']; // get the type of the file
$size = $_FILES['image_file']['size'];
echo $name;
//or
print_r($_FILES);
?>
please help me ...
thanks..
AjaxFileUpload
Maybe this plugin could help you fix the problem.
The way of this plugin doing is just like the way people did before ajax theory proposed which is using an iframe tag handle all the request without refreshing the page.
Without HTML5,I don't think we can use XMLHttpRequest to upload file.
First of all I'd like to ask that you don't suggest I turn to a jQuery plugin to solve my issue. I'm just not willing to make my app work with a plugin (and it prevents me from learning!)
I have a form with a bunch of fields that I'm passing to my backend via the use of jQuery's $.post() This is what I have as my jQuery function:
$.post(
"/item/edit",
$("#form").serialize(),
function(responseJSON) {
console.log(responseJSON);
},
"html"
);
This is how I opened my form:
<form action="http://localhost/item/edit" method="post" accept-charset="utf-8" class="form-horizontal" enctype="multipart/form-data">
This was auto generated by codeigniter's form_open() method (hence why action="" has a value. Though this shouldn't matter because I don't have a submit button at the end of the form)
Within my #form I have this as my file input: <input type="file" name="pImage" />
When the appropriate button is hit and the $.post() method is called, I have my backend just print the variables like so: print_r($_POST) and within the printed variables the 'pImage' element is missing. I thought that maybe files wouldn't come up as an element in the array so I went ahead and just tried to upload the file using this codeigniter function: $this->upload->do_upload('pImage'); and I get an error: "You did not select a file to upload."
Any idea as to how I can overcome this problem?
You cannot post an image using AJAX, i had to find out here as well PHP jQuery .ajax() file upload server side understanding
Your best bet is to mimic an ajax call using a hidden iframe, the form has to have enctype set to multipart/formdata
Files wont be sent to server side using AJAX
One of the best and simplest JQuery Ajax uploaders from PHP LETTER
all you need is include js in your header normally and Jquery code will be like below
$.ajaxFileUpload({
url:'http://localhost/speedncruise/index.php/snc/upload/do_upload',
secureuri:false,
fileElementId:'file_upload',
dataType: 'json',
data : {
'user_email' : $('#email').val()
},
success: function (data, status) {
// alert(status);
// $('#avatar_img').attr('src','data');
}
,
error: function (data, status, e) {
console.log(e);
}
});
wish this can help you
I can't do this with codeigniter and Ajax, I pass the image to base64 and in the controller I convert into a file again
//the input file type
<input id="imagen" name="imagen" class="tooltip" type="file" value="<?php if(isset($imagen)) echo $imagen; ?>">
//the js
$(document).on('change', '#imagen', function(event) {
readImage(this);
});
function readImage(input) {
var resultado='';
if ( input.files && input.files[0] ) {
var FR= new FileReader();
FR.onload = function(e) {
//console.log(e.target.result);
subirImagen(e.target.result);
};
FR.readAsDataURL( input.files[0] );
}
}
function subirImagen(base64){
console.log('inicia subir imagen');
$.ajax({
url: 'controller/sube_imagen',
type: 'POST',
data: {
imagen: base64,
}
})
.done(function(d) {
console.log(d);
})
.fail(function(f) {
console.log(f);
})
.always(function(a) {
console.log("complete");
});
}
//and the part of de controller
public function sube_imagen(){
$imagen=$this->input->post('imagen');
list($extension,$imagen)=explode(';',$imagen);
list(,$extension)=explode('/', $extension);
list(,$imagen)=explode(',', $imagen);
$imagen = base64_decode($imagen);
$archivo='archivo.'.$extension;
file_put_contents('imagenes/'.$archivo, $imagen);
chmod('imagenes/'.$archivo, 0777); //I use Linux and the permissions are another theme
echo $archivo; //or you can make another thing
}
ps.: sorry for my english n_nU