PHP APC multiple upload work incorrectly - php

I have a form:
<form onsubmit="upload_start()" target="upload_iframe" action="../blocks/file_tools/upload.php" enctype="multipart/form-data" method="post">
<input type="hidden" name="APC_UPLOAD_PROGRESS" value="<?php echo md5(rand().time()); ?>" />
<input id="upload_files" name="upload_files[]" type="file" multiple accept="image/*" />
<button id="addFilesButton" type="button" class="button button_gray" title="Добавить файлы"> + Добавить файл</button>
<button class="button button_green" type="submit" title="Загрузить выбранный файлы">Загрузить</button>
</form>
In this file i read upload status:
<?php
session_start();
$id = isset($_POST['id']) ? $_POST['id'] : 0;
$status =apc_fetch("upload_".$id);
header('Content-type: application/json');
print_r(apc_fetch("upload_".$id));
echo json_encode($status);
?>
I send via ajax
//Получаем статус загрузки фалов на сервер.
function upload_status()
{
var id = $("input[name='APC_UPLOAD_PROGRESS']").val();
$.ajax(
{
url: '/blocks/file_tools/upload_status.php', type: 'POST', dataType: 'HTML', charset: 'utf-8', async:false,
data: ({id:id}),
success: function(data)
{
// some code
}
})
setTimeout(upload_status, 2000);
}
If I upload a file, the code works correctly
If you are loading multiple files, APC returns the status of loading only the last file in the array upload_files[ ].
How to get the upload status of each file in the array upload_files[ ]?

See http://php.net/manual/en/apc.configuration.php#ini.apc.rfc1867:
Note that the file upload tracking is not threadsafe at this point, so
new uploads that happen while a previous one is still going will
disable the tracking for the previous.
That basically means that upload progress can only be displayed for a single file at a time.
If you need it bad it is better to implement via webserver:
http://wiki.nginx.org/HttpUploadProgressModule
http://commons.apache.org/proper/commons-fileupload/using.html ("Watching progress" section)

Related

Sending images from form with AJAX

I've been working on a form where you upload an image and a comment. I got it working in PHP, but now I'd like to do it in AJAX. The reason I'd like to do it in AJAX is because the user has to type all of their text again when the upload fails (due to conditions like: fields can't be empty or the aspect ratio of the image is off). However whatever I do, I fail to do it in AJAX.
I've tried to do it in FormData, with $.post and with $.ajax. I've also looked up a lot of guides, and other posts about this, but nothing seems to work for me.
Below you will find the HTML form, the jQuery AJAX call and the PHP code from the PHP page the AJAX call calls.
HTML FORM
<form action="uploadpost.php" id="postForm" method="POST" enctype="multipart/form-data">
<div class="form-group">
<label for="postImage">Upload image</label>
<input type="file" id="fileToUpload" name="postImage" class="form-control">
</div>
<div class="form-group">
<label for="description">Write a caption</label>
<textarea name="description" id="postMessage" cols="30" rows="5" class="form-control"></textarea>
</div>
<input type="submit" id="postSubmit" value="Create post" name="upload_image" class="btn btn-primary">
</form>
The AJAX call
<script type="text/javascript">
$(document).ready(function(){
$("#postSubmit").on("click", function(e){
var formData = new FormData($("#postForm"));
//var message = $("#postMessage").val();
$.ajax({
url: "ajax/postUpload.php",
type: "POST",
data: formData,
contentType: "multipart/form-data",
cache: false,
processData:false,
success: function(data)
{
console.log(data);
}
});
e.preventDefault();
});
});
The PHP code in ajax/postUpload.php
<?php
include_once("../classes/Post.class.php");
$post = new Post();
var_dump($_FILES);
if(!empty($_POST)){
$file_tmp_name = $_FILES['postImage']['tmp_name'];
$result = $post->createPost($file_tmp_name);
if($result){
$uploadCheck['check'] = "success";
}else{
$uploadCheck['check'] = "error";
}
header('Content-Type: application/json');
echo json_encode($uploadCheck);
}
?>
Output from console.log(data) on ajax call return
<pre class='xdebug-var-dump' dir='ltr'>
<b>array</b> <i>(size=0)</i>
<i><font color='#888a85'>empty</font></i>
</pre>
The problem is that I can't send the image nor the message over to that PHP page, which doesn't allow me to do createPost().
var formData = new FormData($("#postForm"));
The argument to FormData should be a DOM form object, not a jQuery object.
new FormData($("#postForm")[0])
Setting the content type manually:
contentType: "multipart/form-data",
… will fail to set the boundary data in it. Say:
contentType: false,
… so that jQuery won't try to set it at all and the XHR object will generate it from the FormData object.

how to send formData to php with ajax

I am trying to generate multiple form that will provide a system to upload multiple files. So far code is
<?php
...
foreach($all_cat as $cat)
{
?>
<form method="post" class="uploadform" enctype="multipart/form-data" action="">
<label for="file-upload" class="custom-file-upload">
<i class="cloud-upload"></i> Add Files
</label>
<input id="file-upload" type="file" name="files[]" multiple />
<input type="submit" value ="uplaod" size="60">
</form>
...
<?php
...
jquery
$(".uploadform").on('submit',(function(e)
{
e.preventDefault();
if($('input[type=file]').val()=="")
{
alert("no file is selected");
return false;
}
else
{
$.ajax({
url: "form_process.php",
type: "POST",
data: new FormData(this),
contentType: false,
cache: false,
processData:false,
success: function(result)
{
alert(result);
}
})//ajax
}//else
}));//onsubmit
But it seems that form_process.php file is not getting data form jquery. alert producing long mark-up of table, and somewhere in that it says file name can not be empty.
form_process.php
if(isset($_FILES['files']))
{
foreach($_FILES['files']['tmp_name'] as $key3)
{
$exif = exif_imagetype($key3);
echo "file type is ".$exif."<br/>";
}
How do I access those selected files upload and other data of the form? I have been trying for hours, anybody can help me,please ? Thanks in advance
Try appending them instead of using 'this'.

Ajax large-ish file upload with FormData and jQuery fails to post the data

I am trying to upload files via AJAX using FormData. If I submit the AJAX call without selecting any files to upload, the post works fine, and other fields (that are not file uploads) are received on the server OK. If I select a file to upload though, the call arrives at the server with no data whatsoever (in PHP, the $_POST and $_FILES arrays are both completely empty). I understand this can happen if you fail to tell jQuery not to set the contentType, but I am setting contentType and processData to false and it still won't send the data.
Here is my code:
function AddComment(taskid) {
var newnote = $('#newnote_'+taskid).val();
if(newnote != '') {
$('#tasklist *').css('cursor', 'progress');
var formData = new FormData();
$('.upload-' + taskid).each(function() {
if (this.files[0]) {
formData.append($(this).attr('name'), this.files[0]);
}
});
formData.append("taskid", taskid);
formData.append("newnote", newnote);
$.ajax({
url: '/modules/task/ajax/ajaxAddComment.php',
data: formData,
processData: false,
contentType: false,
type: 'post',
success: function(data){
alert(data);
}
});
}
}
I'm sure I'm doing something stupid, but I can't see what...?
Edit: Here is the HTML:
<form id="frmNewComment544" enctype="multipart/form-data" method="post" action="">
<div>
<textarea style="width:100%;" cols="30" rows="5" id="newnote_544"></textarea>
</div>
<div>
<input type="button" onclick="AddComment(544)" value="Append Comment">
</div>
<div class="attachment-browsers" id="attachmentBrowsers544" style="display: block;">Attachments will be uploaded when you append a comment.
<div>
<input type="file" id="upload_544_151ab3cfe69" name="upload_544_151ab3cfe69" class="upload-544">
</div>
<div>
<input type="file" id="upload_544_3y4afe6eg7a" name="upload_544_3y4afe6eg7a" class="upload-544">
</div>
</div>
</form>
Edit 2: OK, the problem only occurs when uploading relatively large files (not massive - in this case it was 10MB). Small files upload OK. So now the question is why I cannot upload large files using this method?
I knew it would be something stupid!
My php.ini had the default 2MB limit for file uploads. D'oh.
I don't see any reference to your form.
May be you would do it like this:
.....
var form = $('form#frmNewComment544');
var formdata = false;
if (window.FormData){
formdata = new FormData(form[0]);
}
var formAction = form.attr('action');
$.ajax({
url: formAction,
data : formdata ? formdata : form.serialize(),
....

Session Upload Progress, Ajax call and empty $_SESSION

My goal is to, upon clicking the form submit button, to upload the attachments from the form to the server and show a progress bar of that happening and then submitting the form (ie. mailing the message).
upload_form.php:
<form action="email_message.php" method="post" enctype="multipart/form-data" name="fileform" id="fileform">
<input type="hidden" name="MAX_FILE_SIZE" value="50000000"/>
<input type="hidden" name="<?php echo ini_get("session.upload_progress.name"); ?>" value="uploads"/>
<label for="userfile1">Upload a file:</label>
<input type="file" name="userfile1" id="userfile1" class="userfile"/>
<input id="submit_btn" type="submit" value="Send Message"/>
</form>
In the same page, I run the following code to prevent the form from being executed and sending a request to upload all of the files from the form.
$(document).ready(function(){
$("#fileform").submit(function(e){
e.preventDefault();
var self = this;
var formData = new FormData(document.getElementById("fileform"));
var upload_req = $.ajax({
url: "./upload_multiple_files.php",
type: "POST",
data: formData,
processData: false,
contentType: false
});
upload_req.done(function(data){
alert("Uploading complete!");
});
});
});
upload_multiple_files.php:
<?php
session_start();
foreach ($_FILES as $k => $v){
// code to deal with file errors
if (is_uploaded_file($v['tmp_name'])){
// code to rename file
echo "<p>The file was successfully uploaded.</p>";
}else{
echo "<p>The file was not uploaded.</p>";
}
}
?>
All of this works: the files are all uploaded to the server.
The problem I have is integrating PHP Upload Session Progress (http://php.net/manual/en/session.upload-progress.php).
I know I need to use session.upload_progress.name and the $_POST array to get the file upload information but I'm not sure where to place it. I want to create an ajax call with an interval to periodically get the upload progress to be displayed on my form page. However, when I create a new page, the session information is empty. Here is an example of a page I tried:
get_progress.php:
<?php
session_start();
// $key is a combination of session.upload_progress.prefix and session.upload_progress.name
$results = array("content_length" => $_SESSION[$key]['content_length'],
"bytes_processed" => $_SESSION[$key]['bytes_processed']
);
echo json_encode($results);
?>
I checked the session ids from upload_form.php and get_progress.php and they are the same.
Any reason why $_SESSION is empty in get_progress.php? I think I missed something easy but I can't figure it out.
#Perry Your answer is right, session.upload_progress.enabled wasn't enabled in php.ini. Thanks.

Working with input type file AJAX/PHP

I have got this html/php in my index.php
if (isset($_POST['UploadMSub'])) {
$fileP=$_FILES['Upload_f'];
$fileP_name=$fileP['name'];
$fileP_tmp=$fileP['tmp_name'];
$fileP_size=$fileP['size'];
$fileP_error=$fileP['error'];
$fileP_extension=explode('.', $fileP_name);
$fileP_extension=strtolower(end($fileP_extension));
$allowed=array('jpg','png');
if (in_array($fileP_extension, $allowed)) {
if ($fileP_error===0) {
if ($fileP_size<=2097152) {
$fileP_new_name=uniqid().'.'.$fileP_extension;
}
}
}
$_SESSION['fileP']=$fileP;
$_SESSION['fileP_name']=$fileP_name;
$_SESSION['fileP_tmp']=$fileP_tmp;
$_SESSION['fileP_size']=$fileP_size;
$_SESSION['fileP_error']=$fileP_error;
$_SESSION['fileP_extension']=$fileP_extension;
$_SESSION['fileP_new_name']=$fileP_new_name;
}
<form method="post" enctype="multipart/form-data" class='SubmUploadFu'>
<textarea maxlength="400" type="text" class='Text' placeholder="New post"></textarea>
<input type="file" name="Upload_f" style="display:none;" id="Nameupload">
<label for="Nameupload" class='LabelCamerUp'>
<img src="../img/camera.png" class='CamerUp'>
</label>
<input type="submit" class="UploadMSub">
</form>
And this ajax
$(".UploadMSub").click(function() {
var text=$(".Text").val();
var file=$("#Nameupload").val();
$.ajax({
type: "GET",
url: '../connect.php',
data: "Text=" + text+"&&file="+file,
success: function(data)
{
alert(data);
}
});
return false;
});
connect.php
if (isset($_GET['Text'])) {
$Text=htmlspecialchars($_GET['Text'],ENT_QUOTES);
$file=htmlspecialchars($_GET['file'],ENT_QUOTES);
echo $Text." ".$_SESSION['fileP_new_name'];
}
But when i submit form it returns(alerts)
"Undefine index ''fileP_new_name'"
Is there any other way of getting all information about file in my connect.php?
The problem is,
When you hit the submit button, the form doesn't get submitted, which means none of your session variables are set when you hit the submit button. Instead jQuery script runs straight away when you hit the submit button, and that's why you're getting this error,
Undefine index: fileP_new_name
From your question,
Is there any other way of getting all information about file in my connect.php?
So the solution is as follows. You have to change few things in your code, such as:
Add a name attribute in your <textarea> element, like this:
<textarea maxlength="400" name="new_post" class='Text' placeholder="New post"></textarea>
Instead of returning false from your jQuery script, use preventDefault() method to prevent your form from being submitted in the first place, like this:
$(".UploadMSub").click(function(event){
event.preventDefault();
// your code
});
If you're uploading file through AJAX, use FormData object. But keep in mind that old browsers don't support FormData object. FormData support starts from the following desktop browsers versions: IE 10+, Firefox 4.0+, Chrome 7+, Safari 5+, Opera 12+.
Set the following options, processData: false and contentType: false in your AJAX request. Refer the documentation to know what these do.
So your code should be like this:
HTML:
<form method="post" enctype="multipart/form-data" class='SubmUploadFu'>
<textarea maxlength="400" name="new_post" class='Text' placeholder="New post"></textarea>
<input type="file" name="Upload_f" style="display:none;" id="Nameupload">
<label for="Nameupload" class='LabelCamerUp'>
<img src="../img/camera.png" class='CamerUp'>
</label>
<input type="submit" class="UploadMSub">
</form>
jQuery/AJAX:
$(".UploadMSub").click(function(event){
event.preventDefault();
var form_data = new FormData($('form')[0]);
$.ajax({
url: '../connect.php',
type: 'post',
cache: false,
contentType: false,
processData: false,
data: form_data,
success: function(data){
alert(data);
}
});
});
And on connect.php, process your form data like this:
<?php
if(is_uploaded_file($_FILES['Upload_f']['tmp_name']) && isset($_POST['new_post'])){
// both file and text input is submitted
$new_post = $_POST['new_post'];
$fileP=$_FILES['Upload_f'];
$fileP_name=$fileP['name'];
$fileP_tmp=$fileP['tmp_name'];
$fileP_size=$fileP['size'];
$fileP_error=$fileP['error'];
$fileP_extension=explode('.', $fileP_name);
$fileP_extension=strtolower(end($fileP_extension));
$allowed=array('jpg','png');
if (in_array($fileP_extension, $allowed)){
if ($fileP_error===0) {
if ($fileP_size<=2097152){
$fileP_new_name=uniqid().'.'.$fileP_extension;
}
}
}
// your code
//echo $fileP_new_name;
}
?>

Categories