I am unable to catch the $productid from the form. Not sure what I'm doing wrong. Any ideas?
The selected files do upload, but not to the product folder specified, and nothing about the success is returned to index.php
It's strange but stackoverflow also mentions when trying to post "It looks like your post is mostly code; please add some more details", but I have no more info to add?
Thanks
index.php
<form method='post' action='' enctype="multipart/form-data">
<input type="hidden" id='productid' name="productid" value="<?=$productid?>">
<input type="file" id='files' name="files[]" multiple><br>
<input type="button" id='submitphotos' value='Upload'>
<!-- Preview -->
<div id='successupload'></div>
<div id='preview'></div>
<script>
$(document).ready(function(){
$('#submitphotos').click(function(){
var form_data = new FormData();
// Read selected files
var totalfiles = document.getElementById('files').files.length;
var productid= $("#productid").val();
for (var index = 0; index < totalfiles; index++) {
form_data.append("files[]", document.getElementById('files').files[index]);
}
// AJAX request
$.ajax({
url: 'ajaxfile.php',
type: 'post',
data: form_data,
dataType: 'json',
contentType: false,
processData: false,
success: function (response) {
for(var index = 0; index < response.length; index++) {
var src = response[index];
// Add img element in <div id='preview'>
$('#preview').append('<img src="'+src+'" width="400px;">');
}
$('#successupload').append('<h6>Successfully uploaded</h6>back');
files.style.display = "none";
submitphotos.style.display = "none";
}
});
});
});
ajaxfile.php
// Count total files
$countfiles = count($_FILES['files']['name']);
// Get product id
$productid = $_POST['productid'];
//Create request id folder if doesn't exist
if (!file_exists($_SERVER['DOCUMENT_ROOT'].'/images/products/'.$productid.'/')) {
mkdir($_SERVER['DOCUMENT_ROOT'].'/images/products/'.$productid.'/', 0777, true);
}
// Upload directory
$upload_location = $_SERVER['DOCUMENT_ROOT']."/images/products/".$productid."/";
// To store uploaded files path
$files_arr = array();
// Loop all files
for($index = 0;$index < $countfiles;$index++){
if(isset($_FILES['files']['name'][$index]) && $_FILES['files']['name'][$index] != ''){
// File name
$filename = $_FILES['files']['name'][$index];
// Get extension
$ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
// Valid image extension
$valid_ext = array("png","jpeg","jpg","svg");
// Check extension
if(in_array($ext, $valid_ext)){
// File path
$path = $upload_location.$filename;
// Upload file
if(move_uploaded_file($_FILES['files']['tmp_name'][$index],$path)){
$files_arr[] = $path;
}
}
}
}
echo json_encode($files_arr);
die;
</script>
You haven't passed the productid to the ajax call so just before ajax call add this:
form_data.append('productid', productid);
and your code should work fine.
I have a form that uploads multiple files using dropzone - I have that working, and have the values posting to the database. In the form I have a text area that I want to upload to the same database, but a different table. For reference the images are uploaded to a table called files, which has a column called post_id that will reference the id column in the posts table. Here's the form:
<form action="file_upload.php" method="POST" enctype="multipart/form-data">
<textarea class="form-control border-bottom" name="gallery_text" id="gallery_text" placeholder="Add gallery message..."></textarea>
<div class="dropzone mt-3" id="myDropzone"></div>
<button class="btn btn-primary mt-3" type="submit" name="gallery_submit" id="gallery_submit"> Post Gallery </button>
</form>
Here's the current file upload PHP file:
// Count # of uploaded files in array
$total = count($_FILES['file']['name']);
$filename_arr = [];
// Loop through each file
for ($i = 0; $i < $total; $i++) {
// Get the temp file path
$tmpFilePath = $_FILES['file']['tmp_name'][$i];
// Make sure we have a file path
if ($tmpFilePath != "") {
// Setup our new file path
$newFilePath = "assets/img/posts/" . $_FILES['file']['name'][$i];
// Upload the file into the temp dir
if (move_uploaded_file($tmpFilePath, $newFilePath)) {
$filename_arr[] = $newFilePath;
$images_sql = "INSERT INTO files (file_name, uploaded_on) VALUES(?,NOW())";
$images_stmt = $pdo->prepare($images_sql);
$images_stmt->execute([$newFilePath]);
}
}
}
And for reference here's the dropzone script:
Dropzone.options.myDropzone= {
url: "file_upload.php",
autoProcessQueue: false,
uploadMultiple: true,
parallelUploads: 5,
maxFiles: 20,
maxFilesize: 2,
acceptedFiles: ".jpeg,.jpg,.png,.gif",
addRemoveLinks: true,
dictDuplicateFile: "Duplicate Files Cannot Be Uploaded",
preventDuplicates: true,
init: function() {
var myDropzone = this; // Makes sure that 'this' is understood inside the functions below.
// For Dropzone to process the queue (instead of default form behavior):
document.getElementById("gallery_submit").addEventListener("click", function(e) {
// Make sure that the form isn't actually being sent.
e.preventDefault();
e.stopPropagation();
myDropzone.processQueue();
});
// Send all the form data along with the files:
// this.on("sendingmultiple", function(data, xhr, formData) {
// formData.append("gallery_text", jQuery("#gallery_text").val());
// });
}
}
I thought I could use isset to get the form textarea value and upload that to the appropriate table, then use lastInsertId to upload the images as well as reference the post. Right now I can't seem to get the textarea value to upload to the database at all. Since I'm relatively new at this I'm struggling to understand where I'm going wrong. I get the feeling I'm missing something. Here's one of the ways I've tried.
if (isset($_POST['submit'])) {
$gallery_text = $_POST['gallery_text'];
$userLoggedIn = $user['username'];
$text_sql = "INSERT INTO posts(body, added_by, user_to, date_added, user_closed, deleted, likes, image) VALUES(?,?,'',NOW(),'no','no',0,'')";
$text_stmt = $pdo->prepare($text_sql);
$text_stmt->execute([$gallery_text, $userLoggedIn]);
}
I would be grateful for some guidance on how to get this working.
EDIT:
I separated out the form to just submit "gallery_text" and it worked. When I add dropzone and the image upload process back in it fails silently. Still searching. Here's the form that worked:
if (isset($_POST['gallery_submit'])) {
$gallery_text = $_POST['gallery_text'];
$userLoggedIn = "steve_shead";
$date_added = date("Y-m-d H:i:s");
$text_sql = "INSERT INTO posts(body, added_by, user_to, date_added, user_closed, deleted, likes, image) VALUES(?,?,?,?,?,?,?,?)";
$text_stmt = $con->prepare($text_sql);
$text_stmt->execute([$gallery_text, $userLoggedIn,"", $date_added, "no", "no", 0, ""]);
echo "<h1 class='display-1 mt-5 text-center'>Success!</h1>";
}
After re-reading the documentation I have it working now. The form remains the same. Here's the form handler, file_upload.php:
<?php
require 'inc/header.php';
$gallery_text = $_POST['gallery_text'];
$userLoggedIn = $user['username'];
$date_added = date("Y-m-d H:i:s");
$text_sql = "INSERT INTO posts(body, added_by, user_to, date_added, user_closed, deleted, likes, image) VALUES(?,?,?,?,?,?,?,?)";
$text_stmt = $pdo->prepare($text_sql);
$text_stmt->execute([$gallery_text, $userLoggedIn, "", $date_added, "no", "no", 0, ""]);
$post_id = $pdo->lastInsertId();
// Count # of uploaded files in array
$total = count($_FILES['file']['name']);
$filename_arr = [];
// Loop through each file
for ($i = 0; $i < $total; $i++) {
// Get the temp file path
$tmpFilePath = $_FILES['file']['tmp_name'][$i];
// Make sure we have a file path
if ($tmpFilePath != "") {
// Setup our new file path
$newFilePath = "assets/img/posts/" . $_FILES['file']['name'][$i];
// Upload the file into the temp dir
if (move_uploaded_file($tmpFilePath, $newFilePath)) {
$filename_arr[] = $newFilePath;
$images_sql = "INSERT INTO files (file_name, uploaded_on, post_id) VALUES(?,?,?)";
$images_stmt = $pdo->prepare($images_sql);
$images_stmt->execute([$newFilePath, $date_added, $post_id]);
}
}
}
?>
<?php include 'inc/footer.php'; ?>
The notable difference is the $_POST function is handled by the Dropzone jquery - therefore - you don't need the if(isset($_POST['gallery_text'] function in file_upload.php. Here's that jquery again - note the last two lines - they tell Dropzone to include the data name="gallery_text" id="gallery_text" in the $_POST to file_upload.php.
<script>
Dropzone.options.myDropzone= {
url: "file_upload.php",
autoProcessQueue: false,
uploadMultiple: true,
parallelUploads: 5,
maxFiles: 20,
maxFilesize: 2,
acceptedFiles: ".jpeg,.jpg,.png,.gif",
addRemoveLinks: true,
dictDuplicateFile: "Duplicate Files Cannot Be Uploaded",
preventDuplicates: true,
init: function() {
var myDropzone = this; // Makes sure that 'this' is understood inside the functions below.
// For Dropzone to process the queue (instead of default form behavior):
document.getElementById("gallery_submit").addEventListener("click", function(e) {
// Make sure that the form isn't actually being sent.
e.preventDefault();
e.stopPropagation();
myDropzone.processQueue();
});
// Send all the form data along with the files:
this.on("sendingmultiple", function(data, xhr, formData) {
formData.append("gallery_text", jQuery("#gallery_text").val());
});
}
}
Note also the PDO function lastInsertId() - I assigned the variable $post_id = $pdo->lastInsertId - that way the text is linked to the images uploaded. When creating the images database table I added an INT row called post_id - by using lastInserId it associated the images with a post (hope that makes sense?)
If anyone is having a similar problem I'd be happy to expand on the solution if you think it would help.
I am building a PHP application where a new user has to upload an avatar.
I managed to save the uploaded file path into my database,
but now I have to move the uploaded image from the temporary to the permanent directory, which is the folder 'avatars'.
I have searched through many answers on the same problem but haven't managed to find a working one. Since I am really new to PHP I'm gonna need some help for a working solution.
I have also tried copy() instead of move_uploaded_file with no luck.
HTML:
<div class="input-form">
<label for="avatar">Kies een profielfoto</label>
<input type="file" id="avatar-input" name="avatar" accept="image/*" onchange="loadFile(event)">
<img id="output" width="150" />
<input type="submit" id="submit-btn" name="vervolledig-submit" value="START">
</div>
PHP:
if(!empty($_POST)){
$fileSize = $_FILES["avatar"]["size"];
if($fileSize < 2000000){
$fileSizeOk = true;
}else{
throw new Exception("Je profielfoto heeft een grotere file size dan is toegelaten (max 2MB)");
$imgSizeOk = false;
}
$img = $_FILES["avatar"]["name"];
if($imgSizeOk == true){
move_uploaded_file($_FILES["avatar"]["tmp_name"], "avatars/$img");
}
}
EDIT: was asked to share my JS code:
a function that shows a preview of the uploaded picture:
let loadFile = function(event) {
let image = document.getElementById('output');
image.src = URL.createObjectURL(event.target.files[0]);
};
Suggested solution with AJAX
$('#submit-btn').on('click', function() {
var file_data = $('#avatar-input').prop('files')[0];
var form_data = new FormData();
form_data.append('avatar', file_data);
alert(form_data);
$.ajax({
url: 'profielVervolledigen.php', // point to server-side PHP script
dataType: 'text', // what to expect back from the PHP script, if anything
cache: false,
contentType: false,
processData: false,
data: form_data,
type: 'post',
success: function(php_script_response){
alert(php_script_response); // display response from the PHP script, if any
}
});
});
with the following php code:
if(!empty($_POST)){
if ( 0 < $_FILES['avatar']['error'] ) {
echo 'Error: ' . $_FILES['avatar']['error'] . '<br>';
}
else {
move_uploaded_file($_FILES['avatar']['tmp_name'], 'avatars/' . $_FILES['avatar']['name']);
}
}
the alert gives [object FormData]
Thanks for any help
I have fair knowledge of JS, PHP and Ajax but this simple problem has driven me nuts.
I am trying to upload an image silently, without using a form. I am not using a form because that will lead to nested forms in my HTML, which I read, can cause additional issues.
I have been able to use oFReader, to preview the images.
To upload the image, I am attempting an AJAX call as given below:
HTML
<div id="loginButton2">
<div id="personalimg" >
<img src="photos/seller_photos/<?php echo $profile_pic; ?>" width="70" hight="70" />
</div>
</div>
<div id="loginBox2" style="display:none">
<div id="loginForm2" class="floatLeft" >
<fieldset>
<input id="file" type="file" name="profile_img" value="photos/seller_photos/<?php echo $profile_pic;?>"/>
<input id="file_submit" type="hidden" name="submit4" value="1" >
</fieldset>
</div>
</div>
JS
$('#file').change(function(){
var oFReader = new FileReader();
oFReader.readAsDataURL(this.files[0]);
var fd = new FormData();
var file = $("#file").prop("files")[0];
fd.append('profile_img', file);
fd.append('submit4', 1);
fd.append('filename', 1);
oFReader.onload = function (oFREvent) {
$.ajax({
url: "upload.php",
dataType: 'image',
cache: false,
contentType: false,
processData: false,
type: "POST",
data: fd,
success: function(data){
console.log(data);
},
error: function(){
console.log("image upload failed");
}
});
$('#loginForm2').toggle();
$('#personalimg').html('<img src="'+oFREvent.target.result+'" width="70" height="70">');
};
});
PHP
if(isset($_POST['submit4'])) {
$check_sql = "select profile_pic from profile where user_id=$user_id";
$check_rs = mysql_query($check_sql);
$check_num = mysql_num_rows($check_rs);
if($check_num==0) {
$sql = "insert into profile(user_id) values($user_id)";
$rs = mysql_query($sql);
}
$fName = $_FILES["profile_img"]["name"] ;
$data = explode(".", $fName);
$fileName = $user_id.'.'.$data[1];
if($fName!='')$user->update('profile_pic',$fileName);
$fileTmpLoc= $_FILES["profile_img"]["tmp_name"];
//image store path
$pathAndName = "photos/seller_photos/".$fileName;
$moveResult = move_uploaded_file($fileTmpLoc, $pathAndName);
if(move_uploaded_file) {
$response['status'] = '1';
header('Location: edit_profile_new.php');
} else {
$response['status'] = '0';
}
return $response;
}
But somehow, I have not been able to get this to work. I am using chrome. I get 302 Found status code and "image upload failed" in console.
Can someone please help me out?
ps: I know, mysql is deprecated and will migrate to pdo. This code is inherited and hence has old standards.
My problem is, I want to upload a csv file without pressing a submit button and I used ajax for that case. But now, their is something errors appear, and the error said fopen() Filename cannot be empty. But I already get the file value that I want, but the $_FILES[$fie]['tmp_name'] can't read this value. But if I attach the variable in an alert() they display the exact filename. This is my sample codes.
This is the html:
<form id="Form2">
<input type="file" id="fie" />
</form>
this is the javascript:
<script style="text/javascript">
$(function(){
$('#Form2').change(function(e){
e.preventDefault();
var sub = document.getElementById("fie").files[0].name;
if($('#cat1').hasClass('show')){
$('#cat1').hide();
$('#cat2').html("<img src='pb1.gif' />");
$.ajax({
url:'uploading.php',
action:'get',
data: 'fie='+sub,
success: function(data){
$('#cat2').html(data);
}
});
}
});
});
</script>
This is the Php:
uploading.php
<?php
include("conn.php"); //assuming that connected to a database.
if (isset($_GET['fie'])) {
echo "<script>alert('".$_GET['fie']."')</script>";//IN ALERT THEY EXECUTE THE EXACT VALUE OF THE FILE I INPUT
$fie = $_GET['fie'];
$file = $_FILES[$fie]['tmp_name']; //PROBLEM IS THIS. THEY CAN'T READ THE VALUE AND TELL THEIR IS NO FILE.
$handle = fopen($file,'r') or die ('Cannot open file');
fgets($handle);
do {
if (isset($data[0])) {
mysql_query("INSERT INTO tbl_numbers (numbers,cute) VALUES ('".addslashes($data[0])."','".addslashes($data[1])."')");
}
}
while ($data = fgetcsv($handle,1000,",","'"));
echo "Successful Upload~!";
}
?>
Thanks for the reply.