CodeIgniter AJAX file upload, $_FILE is empty when upload - javascript

Iam writing a script that uploads files via Drag and Drop using jQuery which reads the file on drop and adds it to an array of files like so:
var files = [];
$(document).ready(function() {
jQuery.fn.dropbox = function(config) {
var dragging = 0;
var dragEnter = function(e) {
e.stopPropagation();
e.preventDefault();
dragging++;
$(".external-drop-indicator").fadeIn();
$(".toast.toast-success").fadeIn().css("display", "inline-block");;
return false;
};
var dragOver = function(e) {
e.stopPropagation();
e.preventDefault();
return false;
};
var dragLeave = function(e) {
e.stopPropagation();
e.preventDefault();
dragging--;
if(dragging === 0) {
$(".external-drop-indicator").fadeOut();
$(".toast.toast-success").fadeOut();
}
return false;
};
var drop = function(e) {
var dt = e.dataTransfer;
var files_upload = dt.files;
e.stopPropagation();
e.preventDefault();
if(files_upload && files_upload.length > 0 && config.onDrop !== undefined) {
files.push(files_upload);
config.onDrop(files_upload);
}
$(".external-drop-indicator").fadeOut();
$(".toast.toast-success").fadeOut();
};
var applyDropbox = function(dropbox) {
dropbox.addEventListener('dragenter', dragEnter, false);
dropbox.addEventListener('dragover', dragOver, false);
dropbox.addEventListener('dragleave', dragLeave, false);
dropbox.addEventListener('drop', drop, false);
};
return this.each(function() {
applyDropbox(this);
});
};
});
In summary what it does is, adds an extended jQuery function to enable drag and drop on a certain element of the website in which the function is applied.
Then I apply the extended functionality to the body for it to enable the file Drag and Drop functionality like so:
$(document).ready(function() {
$('body').dropbox({
onDrop: function(f) {
$(f).each(function(idx, data) {
var file_name = data.name;
var extension = file_name.split('.');
file_name = extension[0];
extension = extension[1];
if(extension == 'pdf' || extension == 'xls') {
showAjaxModal(base_url + 'index.php?modal/popup/file_create/' + folder_id + '/' + extension + '/' + file_name);
} else {
$(".upload-area").append('<div class="alert alert-danger" style="display:inline-block;width:480px;"><strong>Error!</strong> File type is incorrect.</div>');
}
});
}
});
});
In summary what this does is adds the Drag and Drop functionality to the body and when a file is dropped it detects the extension of the file by splitting the name and the extension, so that I can verify that the extension of the file that was dropped is correct. Then it proceeds to show a modal to fill information about the file that is being uploaded for later submission, if the file extension is correct.
Then I proceed to fill the file information using CodeIgniter's function "form_open()" when the modal pops like so:
<?php echo form_open(base_url() . 'index.php?client/file/create/' . $param2, array('class' => 'form-horizontal form-groups-bordered validate ajax-upload', 'enctype' => 'multipart/form-data')); ?>
<div class="col-md-4 file-info">
<div class="icon-<?=($param3 == 'pdf' ? 'pdf' : 'document')?>"></div>
<p>
<?php echo $param4;?>
</p>
</div>
<div class="col-md-8 new-file">
<div class="form-group">
<div class="col-sm-12">
<div class="input-group">
<input type="text" class="form-control" name="tags" data-validate="required" data-message-required="Field is required" placeholder="File tags" value="" autofocus>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-12">
<div class="input-group">
<input type="text" class="form-control" name="name" data-validate="required" data-message-required="Field is required" placeholder="File name" value="" autofocus>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-12">
<div class="input-group">
<textarea rows="5" class="form-control" name="description" data-validate="required" data-message-required="Field is required" placeholder="File description" value="" autofocus></textarea>
</div>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-4 col-sm-7">
<button type="submit" class="btn btn-info" id="submit-button">Upload</button>
<span id="preloader-form"></span>
</div>
</div>
<?php echo form_close(); ?>
This basically creates a form which later will be submitted via Ajax.
Now I proceed to handle the file submission via jQuery for the information to be sent with the file or files that are being uploaded like so:
$(document).ready(function(e) {
$('.ajax-upload').submit(function(e) {
e.preventDefault();
var $elm = $(this);
var fd = new FormData();
for(var i = 0; i < files.length; i++) {
fd.append("file_" + i, files[i]);
}
var form_data = $(".ajax-upload").serializeArray();
$.each(form_data, function(key, input) {
fd.append(input.name, input.value);
});
var opts = {
url: $elm.attr('action'),
data: fd,
cache: false,
contentType: false,
processData: false,
type: 'POST',
beforeSend: uValidate,
success: showResponse
};
if(fd.fake) {
opts.xhr = function() {
var xhr = jQuery.ajaxSettings.xhr();
xhr.send = xhr.sendAsBinary;
return xhr;
}
opts.contentType = "multipart/form-data; boundary=" + fd.boundary;
opts.data = fd.toString();
}
jQuery.ajax(opts);
return false;
});
});
Basically the form default action is overwritten and the files that were submitted on the previous code chunk for the drag and drop functionality are now appended to formData which later gets joined by the form data that was on the form I submit. Then the formData is sent via an AJAX call.
Now the controller looks like this, it handles the AJAX call and then executes the File Upload method on the model like so:
function file($param1 = '', $param2 = '', $param3 = 0) {
if ($this->session->userdata('client_login') != 1) {
$this->session->set_userdata('last_page', current_url());
redirect(base_url(), 'refresh');
}
if ($param1 == 'create')
$this->crud_model->create_file($param2);
if ($param1 == 'edit')
$this->crud_model->update_file($param2);
if ($param1 == 'delete')
$this->crud_model->delete_file($param2, $param3);
$page_data['page_name'] = 'files';
$page_data['page_title'] = 'Files List';
$page_data['folder_id'] = $param3;
$this->load->view('backend/index', $page_data);
}
Here is the model method:
function create_file($folder_id) {
$data['name'] = $this->input->post('name');
$data['tags'] = $this->input->post('tags');
$data['description'] = $this->input->post('description');
$data['type'] = 'file';
$data['folder_id'] = $folder_id;
$data['client_id'] = $this->session->userdata('login_user_id');
$config['upload_path'] = 'uploads/tmp/';
$config['allowed_types'] = '*';
$config['max_size'] = '100';
$this->load->library('upload');
$this->upload->initialize($config);
var_dump($_FILES);
die();
foreach($_FILES as $field => $file)
{
//var_dump($_FILES); die();
// No problems with the file
if($file['error'] == 0)
{
// So lets upload
if ($this->upload->do_upload($field))
{
$data = $this->upload->data();
echo $data['full_path'];
}
else
{
$errors = $this->upload->display_errors();
var_dump($errors);
}
}
}
$this->db->insert('client_files' , $data);
}
So basically what happens is that the $_FILES array is empty, and the file doesn't get uploaded.
The "Request Payload" as viewed on Chrome's Developer Tools looks like this:
------WebKitFormBoundaryvVAxgIQd6qU8BtkF
Content-Disposition: form-data; name="file_0"
[object FileList]
------WebKitFormBoundaryvVAxgIQd6qU8BtkF
Content-Disposition: form-data; name="tags"
bsd
------WebKitFormBoundaryvVAxgIQd6qU8BtkF
Content-Disposition: form-data; name="name"
asd
------WebKitFormBoundaryvVAxgIQd6qU8BtkF
Content-Disposition: form-data; name="description"
asd
And the response I get from the var_dump() on the model is the following:
array(0) {
}
I have tried the solution on this question: Sending multipart/formdata with jQuery.ajax But no luck so far.
Any idea on what am I doing wrong and how to fix this issue? Thanks.

The problem here is that I'm sending the array of files instead of the single files on the AJAX call, specifically in this part of the code:
for(var i = 0; i < files.length; i++) {
fd.append("file_" + i, files[i]);
}
The solution was to append file by file to the formData instead of the array of files, something like this:
for(var i = 0; i < files[0].length; i++) {
fd.append("file_" + i, files[i]);
}
This will append every single file of the files array instead of the array of files itself and it solves the problem.
In conclusion I was sending the array of files instead of the single files, the clue to this was the [object FileList] that the request was showing instead of the files information, which now makes a request like this:
Content-Disposition: form-data; name="file"; filename="exfile.pdf"
Content-Type: application/pdf

Related

Dropzone display server images but not saving laravel

I'm using Dropzone.js,I displayed server images inside dropzone box with remove link and it works fine but my problem is when I click on butto to save uploaded images server images not saving in database just new uploaded images are saving
my code
<script type="text/javascript">
Dropzone.options.dropzone =
{
autoProcessQueue: false,
maxFiles: 50,
maxFilesize: 12,
acceptedFiles: ".jpeg,.jpg,.png,.gif",
addRemoveLinks: true,
uploadMultiple: true,
timeout: 50000,
init: function () {
var myDropzone = this;
$.get('/getphoto',{'key': $('[name=key]').val()},function(data){
var files = data;
console.log(files.length);
for (var i = 0; i < files.length; i++) {
var name= files[i].name;
var link = "http://127.0.0.1:8000/storage/images/events/galleries/"+ name;
console.log(link);
var mockFile = { name: files[i].name, size: 128456, type: 'image/png', url:link};
myDropzone.emit('addedfile', mockFile);
myDropzone.options.thumbnail.call(myDropzone, mockFile, link);
myDropzone.emit('complete', mockFile);
myDropzone.files.push(mockFile);
var existingFileCount = 1; // The number of files already uploaded
myDropzone.options.maxFiles = myDropzone.options.maxFiles - existingFileCount;
}
});
// Update selector to match your button
$("#button").click(function (e) {
e.preventDefault();
myDropzone.processQueue();
});
this.on('sending', function(file, xhr, formData) {
// Append all form inputs to the formData Dropzone will POST
var data = $('#dropzone').serializeArray();
$.each(data, function(key, el) {
formData.append(el.name, el.value);
});
});
},
removedfile: function(file)
{
var fileRef;
return (fileRef = file.previewElement) != null ?
fileRef.parentNode.removeChild(file.previewElement) : myDropzone.removeFile(file);
},
success: function(file, response)
{
var name = file.upload.filename;
console.log(name);
window.location.href = "{{ route('eventlist') }}";
},
error: function(file, response)
{
return false;
}
};
function del(file)
{
console.log(file.name);
return myDropzone.removeFile(file);
}
</script>
my view blade:
<div>
<form action="{{ route('savegallery',$event->id) }}" class="dropzone" id="dropzone" method="POST" class="dropzone" enctype="multipart/form-data">
#csrf
{{-- <div class="fallback">
<input name="images" type="file" multiple="multiple">
</div> --}}
<div class="dz-message needsclick">
<div class="mb-3">
<i class="display-4 text-muted mdi mdi-upload-network-outline"></i>
</div>
<h4>Drop files here or click to upload.</h4>
</div>
</form>
</div>
<div class="text-center mt-4">
<button type="submit" id="button" class="btn btn-primary waves-effect waves-light">Send
Files</button>
</div>
First I delete all images then I get images from dropzone then save it
public function savegallery(Request $request,$id){
$eventgalleries = Eventgallery::where('event_id',$id)->delete();
foreach ($request->file('file') as $img) {
// $image = new Eventgallery;
//get file name with extention
$filenameWithExt = $img->getClientOriginalName();
//get just file name
$filename = pathinfo($filenameWithExt, PATHINFO_FILENAME);
//GET EXTENTION
$extention = $img->getClientOriginalExtension();
//file name to store
$fileNameToStore = $filename . '_' . time() . '.' . $extention;
//upload image
$path = $img->storeAs('public/images/events/galleries', $fileNameToStore);
$url = asset('storage/images/events/galleries/' . $fileNameToStore);
$img = new Eventgallery;
$img->name = $fileNameToStore;
$img->event_id = $id;
$img->save();
}
return redirect()->route('eventlist')->with('success', 'The galleries created successfully.');
}
and this function for route (/getphoto) to get all images and then display it in dropzone
public function getphoto(){
$data = Eventgallery::all()->toArray();
return $data;
}
Can someone help me I spend many days to find a solve but no result.

how to change XmlHttpRequest url in image upload

I am trying to upload image and it is working. but the problem is when I am trying to update this image I m having problem because it is redirecting to wrong url. The form is post to this url
POST http://127.0.0.1/mgt/upload/processImage/foodImage
and the result is coming like this
GET
http://127.0.0.1/mgt/food/viewFoodDetails/temp/uploads/images/foodImage/937d932fcbf3c6ba36b7eed65cecd045.png
But, I want the get result should come like this (I dont want it to get food/viewFoodDetails from url)
GET
http://127.0.0.1/mgt/temp/uploads/images/foodImage/937d932fcbf3c6ba36b7eed65cecd045.png
can anyone help me please?
here is my js
$.fn.uploadFile=function(opts)
{
var opts=$.extend({
allowed:['png, jpg']
},opts);
return this.each(function(){
var pb='<div class="progress" style="width:0"><span>0%</span></div>',
_this=$(this),
progressbar=$(_this.attr("data-progressbar")),
endpoint='http://127.0.0.1/mgt/upload/processImage/foodImage',
viewer=$(_this.attr("data-viewer")),
element=$(_this.attr("data-element")),
downloadLink=$(_this.attr("data-downloadLink"));
//cct=$(_this).parents("form").find("input[name=csrfwebpos]").val();
//console.log(_this, progressbar, endpoint, viewer, element, downloadLink);
_this.change(function(){
var filename=_this.val().toLowerCase().split(/[\\\/]/).pop(),is_allowed=false,
ext=filename.split(".").pop();
//console.log(filename, ext);
if(filename==''){
return;
}
$.each(opts.allowed,function(i,el){
if(ext==el){
is_allowed=true;
}
});
if(!is_allowed){
showError("This file type is not supported. Please select another file.");
return;
}else{
progressbar.show(0);
var files=_this[0].files,
file=_this[0].files[0],
headers={
"Cache-Control":"no-cache",
"X-Requested-With":"XMLHttpRequest",
"X-File-Name":file.fileName||file.name,
"X-File-Size":file.fileSize||file.size,
};
if(file.size>700000){
showError("File can not be larger than 700KB in size.");
return;
}
_this.attr("disabled",true);
progressbar.append(pb);
var bar=progressbar.find(".progress"),percent=bar.find("span");
var xhr = new XMLHttpRequest();
var upload = xhr.upload;
upload.fileObj = file;
upload.downloadStartTime = new Date().getTime();
upload.currentStart = upload.downloadStartTime;
upload.currentProgress = 0;
upload.startData = 0;
viewer.hide(0);
upload.onprogress=function(e){
if(e.lengthComputable){
var _p=Math.floor((e.loaded/e.total)*100);
bar.css("width",_p+"%");
percent.html(_p+"%");
if(_p==100){
percent.html("Processing...");
}
}
};
xhr.onload=function(e){
status = xhr.status;
if(e.target.readyState == 4){
var data=eval("("+this.responseText+")");
console.log(this);
console.log(data);
if(data && data.successFunction){
data.successFunction.apply(_this);
}
if(data && data.fileName!=''){
element.val(data.fileName);
element.trigger("change");
viewer.show(0);
$(viewer).find("img").prop("src",data.fileName);
}
if(data && data.downloadLink!=''){
downloadLink.html('Download Server Response');
}
_this.val("").attr("disabled",false);
progressbar.find(".progress").remove();
progressbar.hide(0);
}
};
xhr.open("POST",endpoint,true);
//console.log(endpoint);
/*
var oMyForm = new FormData();
oMyForm.append("csrfwebpos", cct);
oMyForm.append("file", file);
*/
for(var prop in headers){
xhr.setRequestHeader(prop, headers[prop]);
}
xhr.send(file);
}
});
});
};
This is my image upload function upload.php
public function processImage($uploadFolder="profile", $userFileName="")
{
$tempFilePath="temp/$uploadFolder";
if (!file_exists($tempFilePath)) {
#mkdir($tempFilePath);
}
#chmod($tempFilePath, 0777);
$path=$tempFilePath."/";
$headers=getallheaders();
if (isset($headers['X-File-Size'], $headers['X-File-Name'])) {
// create the object and assign property
$file = new stdClass;
$file->name = basename($headers['X-File-Name']);
$file->size = $headers['X-File-Size'];
$file->content = file_get_contents("php://input");
$fileparts=fileExtension($file->name);
if ($userFileName=='') {
$filename = md5(
$this->session->userdata('userid') .
uniqid() .
microtime(true) .
mt_rand() .
$file->name .
$file->size .
$this->session->userdata('userid')
);
} else {
$filename=$userFileName;
}
$file->name=$filename.$fileparts["extension"];
// echo $path.$file->name;
if (#file_put_contents($path.$file->name, $file->content)) {
$old = getcwd(); // Save the current directory
#chdir($path);
chmod($file->name, 0644);
chdir($old);
}
}
}
This is my HTML
<script type='text/javascript'>
$(document).ready(function() {
$('#uploadImage').uploadFile();
});
</script>
<form method='post' action='<?=$baseUrl?>food/saveFood' accept-charset='utf-8' enctype='multipart/form-data'>
<table class='table table-bordered table-curved'>
<tr>
<td>
<div class='form-group col-md-12' style='padding:0px;'>
<div class='fileupload fileupload-new' data-provides='fileupload'>
<div class='input-group'>
<div class='form-control uneditable-input'><i class='icon-file fileupload-exists'></i>
<span class='fileupload-preview'></span>
</div>
<div class='input-group-btn'>
<a class='btn btn-default btn-file'>
<span class='fileupload-new'>Select file</span>
<span class='fileupload-exists'>Change</span>
<input type='file' class='file-input' id='uploadImage' data-progressbar='.pb' data-element='#appImg' data-viewer='#appPhoto' />
</a>
</div>
</div>
</div>
</div>
<div class='clearfix'></div>
<div class='pb pull-left col-md-12' style='display:none;'></div>
<div id='appPhoto'><img src='' /></div>
<input type='hidden' name='imagePath' id='appImg' value='' />
</td>
</form>
I solved it, I have added baseurl to the file path
from
$(viewer).find("img").prop("src",data.fileName);
to
$(viewer).find("img").prop("src",baseurl+data.fileName);

how to upload an image with a text post AJAX, php, and html

Hi i am trying to upload an image with comments added to it into a database using php ajax and html.
here is the html part:
<form name="form1" enctype="multipart/form-data" action="">
<h2></h2>
<div class="form-group">
<textarea name="msg" class="form-control status-box" id="post" rows="3" cols="60" placeholder="What\'s on your mind?"></textarea>
<p>Upload an image.</p>
<input type="file" id="postPhoto" name="postPhoto" value="upload" placeholder="Upload Image">
</div>
</form>
<div class="button-group pull-right">
<p class="counter">200</p>
<a href="#" type="submit" onclick="submitChat()" class="post btn btn-primary">
Post</a>
</div><br><br>
this is what i have to the ajax which is on the same page as the html
<script>
function submitChat() {
var file = document.getElementById("postPhoto");
var formData = new FormData();
// alert(formData);
formData.append("file[]", file.files[0]);
if(form1.msg.value == '') {
alert('You must Enter a Post');
return;
}
var msg = form1.msg.value;
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if(xmlhttp.readyState==4 && xmlhttp.status==200) {
document.getElementById('logs').innerHTML = xmlhttp.responseText;
console.log(xmlhttp.statusText);
}
}
xmlhttp.open('POST', 'userposts.php?msg='+msg, true);
xmlhttp.setRequestHeader("Content-type", "multipart/form-data");
xmlhttp.send(formData);
}
<script>
and this is the php part:
$msg = stripslashes(htmlspecialchars($_REQUEST['msg']));
if(isset($_FILES['postPhoto']['type'])) {
$imageData = "";
$validextensions = array("jpeg", "jpg", "png");
$temporary = explode(".", $_FILES['postPhoto']['name']);
$file_extension = end($temporary);
if((($_FILES['postPhoto']['type'] === 'image/png') || ($_FILES['postPhoto']['type'] == 'image/jpg') || ($_FILES['postPhoto']['type'] == 'image/jpeg')) && ($_FILES['postPhoto']['size'] < 2500000) && in_array($file_extension, $validextensions)) {
if($FILES['postPhoto']['error'] > 0) {
echo "return code: " . $_FILES['postPhoto']['error'] . "<br/><br/>";
}
else {
$imageData = mysqli_real_escape_string($connection, file_get_contents($_FILES["postPhoto"]["tmp_name"]));
}
}
}
$stmt = "INSERT INTO posts VALUES ('', '$uname', '$msg', '$imageData')";
$result = $connection->query($stmt);
the images do not seem to be getting sent to the php file idk how to go about fixing this. any help would be much appreciated.
Maybe Helpful,
You simply can't upload a file with pure Javascript ajax functions (at least not in a cross browser way, see this article for more information)
This is because XMLHttpRequest has no support for multipart/form-data, you can do tricks like using an iframe or use flash.
There are enough articles on the internet that explain this.(maybe helpful)
http://www.ajaxf1.com/tutorial/ajax-file-upload-tutorial.html
http://www.faqs.org/rfcs/rfc2388.html
Recomand
Use jQuery Ajax. which have easy lib. support and functions to upload images and submit/parse to destination files.
below sample jQuery AJAX code for demo
$(document).ready(function(){
$(document).on('submit','form[name="form1"]',function(e){
e.preventDefault();
var form = $(this)[0];
var formData = new FormData(form);
$.ajax({
url: 'Your url here',
data: formData,
type: 'POST',
// THIS MUST BE DONE FOR FILE UPLOADING
contentType: false,
processData: false,
// ... Other options like success and etc
success : function(data){
//Do stuff for ahed process....
}
});
});
});

PHP - Uploading multiple files with Javascript and PHP

its me again. Im currently trying to build an multiple file uploader for my site but dont know how to get/handle all files. I think showing you the code first will be a better explanation:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>NDSLR - Demo Upload</title>
</head>
<body>
<script type="text/javascript">
function fileChange()
{
//FileList Objekt aus dem Input Element mit der ID "fileA"
var fileList = document.getElementById("fileA").files;
//File Objekt (erstes Element der FileList)
var file = fileList[0];
//File Objekt nicht vorhanden = keine Datei ausgewählt oder vom Browser nicht unterstützt
if(!file) {
return;
}
var x = substr(file.name, -4);
document.getElementById("status").innerHTML = x;
/*
if (x != ".pdf") {
document.getElementById("fileA").files = null;
file = null;
fileList = null;
alert("Wrong Data");
return;
} */
document.getElementById("fileName").innerHTML = 'Dateiname: ' + file.name;
document.getElementById("fileSize").innerHTML = 'Dateigröße: ' + file.size + ' B';
document.getElementById("progress").value = 0;
document.getElementById("prozent").innerHTML = "0%";
}
var client = null;
function uploadFile()
{
//Wieder unser File Objekt
for(i=0;i < document.getElementById("fileA").files; i++) {
var file = document.getElementById("fileA").files[i];
//FormData Objekt erzeugen
var formData = new FormData();
//XMLHttpRequest Objekt erzeugen
client = new XMLHttpRequest();
var prog = document.getElementById("progress");
if(!file)
return;
prog.value = 0;
prog.max = 100;
//Fügt dem formData Objekt unser File Objekt hinzu
formData.append("datei", file);
client.onerror = function(e) {
alert("onError");
};
client.onload = function(e) {
document.getElementById("prozent").innerHTML = "100%";
prog.value = prog.max;
};
client.upload.onprogress = function(e) {
var p = Math.round(100 / e.total * e.loaded);
document.getElementById("progress").value = p;
document.getElementById("prozent").innerHTML = p + "%";
};
client.onabort = function(e) {
alert("Upload abgebrochen");
};
client.open("POST", "upload.php");
client.send(formData);
}
}
}
function uploadAbort() {
if(client instanceof XMLHttpRequest)
//Briecht die aktuelle Übertragung ab
client.abort();
}
</script>
<form action="" method="post" enctype="multipart/form-data">
<input name="file[]" type="file" multiple="multiple" id="fileA" onchange="fileChange();"/>
<input name="upload[]" value="Upload" type="button" accept=".dem" onclick="uploadFile();" />
<input name="abort" value="Abbrechen" type="button" onclick="uploadAbort();" />
</form>
<div id="status"></div>
<div id="fileName"></div>
<div id="fileSize"></div>
<div id="fileType"></div>
<progress id="progress" style="margin-top:10px"></progress> <span id="prozent"></span>
</div>
</body>
</html>
So this is my HTML Code and following up my upload.php:
<?php
if (isset($_FILES['datei']))
{
move_uploaded_file($_FILES['datei']['tmp_name'], 'upload/'.$_FILES['datei']['name']);
}
?>
My Problem currently is, that i dont know how to implement the multiple upload or better said, how to upload all files at all.
There are some tutorials in the internet, that you can simply find by googling "multiple file upload". Anyway here is one of the examples:
The HTML
<!-- IMPORTANT: FORM's enctype must be "multipart/form-data" -->
<form method="post" action="upload-page.php" enctype="multipart/form-data">
<input name="filesToUpload[]" id="filesToUpload" type="file" multiple="" />
</form>
Listing Multiple Files with JavaScript
//get the input and UL list
var input = document.getElementById('filesToUpload');
var list = document.getElementById('fileList');
//empty list for now...
while (list.hasChildNodes()) {
list.removeChild(ul.firstChild);
}
//for every file...
for (var x = 0; x < input.files.length; x++) {
//add to list
var li = document.createElement('li');
li.innerHTML = 'File ' + (x + 1) + ': ' + input.files[x].name;
list.append(li);
}
The input.files property provides an array of files for which you can check the length; if there's a length, you can loop through each file and access the file paths and names.
Receiving and Handling Files with PHP
if(count($_FILES['uploads']['filesToUpload'])) {
foreach ($_FILES['uploads']['filesToUpload'] as $file) {
//do your upload stuff here
echo $file;
}
}
PHP creates an array of the files uploaded with the given INPUT's name. This variable will always be an array within PHP.
Source
Demo
This is uploading using ajax. There are other ways such the use of iframe and jquery's $.load().
ajax_upload.js
Hmm... FormData is not IE-safe. So, you may want to resort to iframe & $.load().
function doUpload(fle_id, url_upld)
{
var upldLimit = 2000000; // 2mb by default;
if( $('#'+fle_id)[0] == undefined || $('#'+fle_id)[0].files.length == 0 ) {
alert('nothing to upload');
return;
}
// put files to formData
var tfSize = 0; // in bytes
var fd = new FormData();
$.each($('#'+fle_id)[0].files, function(i, file) {
fd.append(i, file);
tfSize = tfSize + file.size;
});
// you may check file size before sending data
if(tfSize > upldLimit) {
alert('File upload exceeded the '+(upldLimit/1000000)+' MB limit.');
return;
}
// actual data transfer
$.ajax({
url: url_upld,
cache: false,
data: fd,
type: 'POST',
contentType : false,
processData : false,
success: function(data){
alert(data);
},
error: function(jqXHR, textStatus, errorMessage) {
alert(errorMessage);
}
});
}
upload_form.html
Let's use jquery to make things simple.
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="ajax_upload.js"></script>
<script type="text/javascript">
$(function(){
$('form').submit(function(e){
if( e.preventDefault ) e.preventDefault(); // chrome/firefox
else e.cancelBubble(); // IE
// supply file input id and upload url
doUpload( 'fle', $(this).attr('action') );
});
});
</script>
Upload
<form action="ajax_upload.php"
method="post"
enctype="multipart/form-data"
accept-charset="utf-8"
>
<input type="file" id="fle" name="fle[]" multiple >
<button type="submit">Upload</button>
</form>
ajax_upload.php
<?php
if(count($_FILES) == 0) {
echo 'Nothing uploaded.';
exit;
}
$upldPath = 'E:/stack/upload/';
foreach($_FILES as $file) {
if ($file['error'] == UPLOAD_ERR_OK) {
try {
if( !move_uploaded_file( $file["tmp_name"], $upldPath . $file['name']) ) {
// abort even if one file cannot be moved.
echo 'Cannot upload one of the files.';
exit;
}
}
catch(Exception $e) {
echo 'Cannot upload the files.';
exit;
}
} else {
// abort even if one file has error.
echo 'Cannot upload one of the files.';
exit;
}
}
echo 'Upload successful!';
?>
Here is a simple approach to solving this issue.
This FormData append method works on IE 10 up and any other browser.
let files = []
let formData = new FormData
let filesInput = document.getElementById('files')
function prepareFiles() {
files = filesInput.files
}
function uploadFiles() {
// Arrange the files as form data to be sent to php
files = Array.from(files)
files.forEach(file => formData.append('files[]', file))
// See all selected files
console.log('Files')
console.log(formData.getAll('files[]'))
// Then send to php with jquery, axios e.t.c
console.log('Server response')
$.post('/pathtophpscript', formData, (response) => {
console.log(response)
}).catch(error => console.log(error))
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="file" name="uploads" id="files" onchange="prepareFiles()" multiple>
<br/><br/>
<input type="submit" name="Upload" onclick="uploadFiles()">

div used for image display causing difficulties while uploading file;

Here i have a image upload mechanism. It's purpose is to accept an image and display it in a div with id=imageholder . My problem is if i have this image holder div inside my form , it gives upload error (4) . So i get an empty $_FILES array. But if i omit it i get a populated $_FILES array .But i need that div inside the form for design purpose. How i can escape this situation .
with imagehoder div inside form:
without imageholder div :
code may seem long . But none of it is related to the question. It is generally for validating the mime type
full code :
<?php print_r($_FILES);?>
<html>
<body>
<form method='post' enctype='multipart/form-data' action="<?php echo $_SERVER['PHP_SELF'] ?>">
<div id='photouploder'>
<div id='imagehoder'></div> // creating problem
<div class="inputWrapper">upload image
<input class="fileInput" id='up' type="file" name="image"/>
</div>
</div>
<input type='submit' value='submit'>
</form>
<script>
var imageholder=document.getElementById('imageholder');
function getBLOBFileHeader(url, blob, callback,callbackTwo) {
var fileReader = new FileReader();
fileReader.onloadend = function(e) {
var arr = (new Uint8Array(e.target.result)).subarray(0, 4);
var header = "";
for (var i = 0; i < arr.length; i++) {
header += arr[i].toString(16);
}
var imgtype= callback(url, header);// headerCallback
callbackTwo(imgtype,blob)
};
fileReader.readAsArrayBuffer(blob);
}
function headerCallback(url, headerString) {
var info=getHeaderInfo(url, headerString);
return info;
}
function getTheJobDone(mimetype,blob){
var mimearray=['image/png','image/jpeg','image/gif'];
console.log('mimetype is :'+mimetype);
if(mimearray.indexOf(mimetype) !=-1){
printImage(blob);
}else{
document.getElementById('up').value='';
while (imageholder.firstChild) {
imageholder.removeChild(imageholder.firstChild);
}
console.log('you can not upload this file type');
}
}
function remoteCallback(url, blob) {
getBLOBFileHeader(url, blob, headerCallback,getTheJobDone);
}
function printImage(blob) {
// Add this image to the document body for proof of GET success
var fr = new FileReader();
fr.onloadend = function(e) {
var img=document.createElement('img');
img.setAttribute('src',e.target.result);
img.setAttribute('style','width:100%;height:100%;');
imageholder.appendChild(img);
};
fr.readAsDataURL(blob);
}
function mimeType(headerString) {
switch (headerString) {
case "89504e47":
type = "image/png";
break;
case "47494638":
type = "image/gif";
break;
case "ffd8ffe0":
case "ffd8ffe1":
case "ffd8ffe2":
type = "image/jpeg";
break;
default:
type = "unknown";
break;
}
return type;
}
function getHeaderInfo(url, headerString) {
return( mimeType(headerString));
}
// Check for FileReader support
function fileread(event){
if (window.FileReader && window.Blob) {
/* Handle local files */
var mimetype;
var mimearray=['image/png','image/jpeg','image/gif'];
var file = event.target.files[0];
if(mimearray.indexOf(file.type)===-1 || file.size >= 2 * 1024 * 1024){
while (imageholder.firstChild) {
imageholder.removeChild(imageholder.firstChild);
}
document.getElementById('up').value='';
console.log("you can't upload this file type");
file=null;
return false;
}else{
while (imageholder.firstChild) {
imageholder.removeChild(imageholder.firstChild);
}
document.getElementById('up').value='';
remoteCallback(file.name, file);
}
}else {
// File and Blob are not supported
console.log('file and blob is not supported');
} /* Drakes, 2015 */
}
document.getElementById('up').addEventListener('change',fileread,false);
</script>
</body>
</html>
First of all: HTML attribute values should always be encapsulated in double quotes.
Second, this is a correct example of reading files using html5 API like you tried:
(Also check the documentation for it: https://developer.mozilla.org/en-US/docs/Web/API/FileReader)
window.onload = function() {
var fileInput = document.getElementById('up');
var fileDisplayArea = document.getElementById('imagehoder');
fileInput.addEventListener('change', function(e) {
var file = fileInput.files[0];
var imageType = /image.*/;
if (file.type.match(imageType)) {
var reader = new FileReader();
reader.onload = function(e) {
fileDisplayArea.innerHTML = "";
var img = new Image();
img.src = reader.result;
fileDisplayArea.appendChild(img);
}
reader.readAsDataURL(file);
} else {
fileDisplayArea.innerHTML = "File not supported!"
}
});
}
<body>
<form method="post" enctype='multipart/form-data' action="<?php echo $_SERVER['PHP_SELF'] ?>">
<div id="photouploder">
<div id="imagehoder"></div>
<div class="inputWrapper">upload image
<input class="fileInput" id="up" type="file" name="image" />
</div>
</div>
<input type="submit" value="submit">
</form>
</body>
I'm not sure about the 'design purpose' in your question. If the 'design purpose' means UI design (CSS related), then probably this reason doesn't stand since they are totally irrelevant.
Also, the file upload technology is very mature now. There are bunches of open source implements in all languages and are well-tested and easy-to-use I highly recommend you to take a look at them before implementing it yourself.

Categories

Resources