I have a script (index.php) to create a list of all added files from "browse file" button. And I have a script (process.php) to send all files on the list to email with phpmailer.
My problem is, only file(s) at the last click that sent. File(s) that have been added previously unsent.
index.php script
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
</head>
<body>
<form id="data" action="process.php" method="POST" enctype="multipart/form-data">
<input id="file" type="file" name="files[]" multiple="multiple"/>
<div id="output"><ul></ul></div>
<input type="submit" name="submit" value="OK">
</form>
</body>
<script>
$("#file").change(function() {
var ele = document.getElementById($(this).attr('id'));
var result = ele.files;
for(var x = 0; x < result.length; x++){
var file = result[x];
$("#output ul").append("<li>" + file.name + "</li>");
}
});
</script>
</html>
process.php script
<?php
require 'mail/PHPMailerAutoload.php';
$to = 'destination#email.com';
$subject = 'Test';
if(isset($_POST['submit'])){
$attachment_name = $_FILES['files']['name'];
$attachment_type = $_FILES['files']['type'];
$attachment = $_FILES['files']['tmp_name'];
include 'smtp.php';
$mail->addAddress($to);
$mail->Subject = $subject;
$mail->msgHTML('Tes');
foreach($attachment_name as $key => $att){
$nama_file = $attachment_name[$key];
$tmp_file = $attachment[$key];
$mail->addAttachment($tmp_file, $nama_file);
}
if (!$mail->send()) {
echo '<script>alert("Fail"); </script>';
} else {
echo '<script>alert("Success"); </script>';
}
}
?>
Assume you have success create multiple input tag for upload file. (using jquery)
And at the php side:
// first file
$_FILES['files']['name'][0];
$_FILES['files']['type'][0];
$_FILES['files']['tmp_name'][0];
// second file
$_FILES['files']['name'][1];
$_FILES['files']['type'][1];
$_FILES['files']['tmp_name'][1];
OR:
$total = count($_FILES['upload']['name']);
// Loop through all files
for($i = 0; $i < $total; $i++) {
$_FILES['files']['name'][$i];
//do what you want
}
Your current code is unsafe. Read the PHP docs on handling file uploads.
You can attach multiple files using a single file input tag if you set a multiple attribute on it, like this;
<input name="userfile[]" type="file" multiple="multiple">
The 'send_multiple_file_upload` example provided with PHPMailer handles this correctly. The inportant part is:
//Attach multiple files one by one
for ($ct = 0; $ct < count($_FILES['userfile']['tmp_name']); $ct++) {
$uploadfile = tempnam(sys_get_temp_dir(), sha1($_FILES['userfile']['name'][$ct]));
$filename = $_FILES['userfile']['name'][$ct];
if (move_uploaded_file($_FILES['userfile']['tmp_name'][$ct], $uploadfile)) {
$mail->addAttachment($uploadfile, $filename);
} else {
$msg .= 'Failed to move file to ' . $uploadfile;
}
}
Related
I have created a jQuery/AJAX script for file uploading and I handle the upload with PHP. It works perfectly with a progress bar and validations. There is one issue however, I cannot get any response text that I have set in PHP and encoded it using json_encode();, but don't get any response and get this instead:
<div class="upload-div">
<form method="post" enctype="multipart/form-data" class="upload_form" >
<label for="file" id="file_label" class="file-label"><i class="fa fa-plus"></i> إضافة صور<input type="file" name="files[]" id="file" multiple="" accept="image/*" /></label>
<input type="submit" id="upload_files" name="submitUpload" value="رفع الصور" />
</form>
<div class="progress">
<div class="bar"></div>
</div>
<div class="status-message"></div>
<div class="images-previews"></div>
<div id="next_step"></div>
<span class="submit-buttons">
<i class="fa fa-arrow-right"></i> الرجوع
<form method="post"><input type="submit" name="submitNoPics" value="التقدم بدون صورة" /></form>
</span>
</div>
<script src="js/upload.js"></script>
<script src="js/jquery.form.min.js"></script>
{"message":"Successfully uploaded 1 files!"}
As you can see the message I want to display is on the last line of code but it doesn't show alone. It shows with the whole HTML document. I will post my HTML and PHP code below, because I am new to Ajax and I am struggling. Please help me if you can and explain because I don't just want to get it done, I want to actually understand how and why this is not working. Thank you.
PHP:
<?php
//file upload
$extensions = array('jpeg', 'jpg', 'png', 'gif');
$dir = 'user-uploads/';
$count = 0;
$imgCounter = 1;
if ($_SERVER['REQUEST_METHOD'] == 'POST' and isset($_FILES['files'])){
for($x = 1; $x <= 8; $x++){
unlink('user-uploads/img'.$listingID.'-'.$x.'.jpg');
unlink('user-uploads/img'.$listingID.'-'.$x.'.png');
unlink('user-uploads/img'.$listingID.'-'.$x.'.gif');
}
mysqli_query($connectionDB, "DELETE FROM ad_image_tbl WHERE ad_id = $listingID");
// loop all files
foreach ( $_FILES['files']['name'] as $i => $name ){
// if file not uploaded then skip it
if ( !is_uploaded_file($_FILES['files']['tmp_name'][$i]) )
continue;
/* skip unprotected files
if( !in_array(pathinfo($name, PATHINFO_EXTENSION), $extensions) )
continue;
*/
switch($_FILES['files']['type'][$i]){
case 'image/jpeg' : $ext = '.jpg'; break;
case 'image/png' : $ext = '.png'; break;
case 'image/gif' : $ext = '.gif'; break;
default : $ext = '';
}
if($ext == ''){
echo errorMessage('<li>الملف المرفق لا يعتبر صورة</li>');
$error_message = 'الملف المرفق لا يعتبر صورة';
$message = array('message'=>'Attached file is not a valid image file.');
exit();
}
else{
// now we can move uploaded files
if($count <= 7 ){
$listingImage = $dir.'img'.$listingID.'-'.$imgCounter.$ext;
if( move_uploaded_file($_FILES["files"]["tmp_name"][$i], $listingImage))
mysqli_query($connectionDB, "INSERT INTO ad_image_tbl VALUES('$imgCounter', '$listingID', '$listingImage')");
$imgCounter++;
$count++;
}
}
}
$message = array('message'=>'Successfully uploaded '.$count.' files!');
echo json_encode($message);
}
?>
jQuery/AJAX:
$(function() {
/* variables */
var fileInput = document.getElementById('file');
var fileCount = fileInput.files.length;
if(fileCount > 8){
fileCount = 8;
}
var bar = $('.bar');
var progress = $('.progress');
/* submit form with ajax request using jQuery.form plugin */
$('.upload_form').ajaxForm({
/* set data type json */
dataType:'JSON',
/* reset before submitting */
beforeSend: function() {
bar.width('0%');
progress.css('display', 'block');
},
/* progress bar call back*/
uploadProgress: function(event, position, total, percentComplete) {
var pVel = percentComplete + '%';
bar.width(pVel);
},
/* complete call back */
complete: function(message){
// var responseMessage = $.parseJSON(data.responseText);
progress.css('display', 'none');
document.getElementById('next_step').innerHTML = '<form method="post"><input type="submit" name="uploadSubmit" value="الانتهاء" /></form>';
console.log(message)
}
});
});
Why could you use a plugin to handle upload.
dropzone.js
You can get response as below
$(function() {
Dropzone.options.uiDZResume = {
success: function(file, response){
alert(response);
}
};
});
I want to upload files in to webroot/files folder, but my controller doing nothing, is there any mistake ?
View file name: uploadfile.ctp
Controller name: UploadFileController.php
Model name: UploadFile.php
In my view file I have:
<div class="files">
<input type="file" name="files[]" /><br/>
</div>
<button type="button" class="plus">+</button> <br><br>
<form name="frm1" method="post" onsubmit="return greeting()">
<input type="submit" value="Submit">
</form>
<?php echo $this->Html->script('addFile');
addFile script :
$(document).ready(function() {
$(".plus").click(function() {
$(".files").append("<input type='file' name='files[]'/><br/>");
});
});
And my Controller, I think that a mistake is somewhere here :
public function uploadFile() {
$uploadedFile = $this->request->params['UploadFile']['files[]']['tmp_name'];
$dir = WWW_ROOT . 'files/';
if ( !is_dir( $dir ) ) {
mkdir($dir);
chmod( $dir , 777);
}
$fileName = 'file_' . date( 'Y_m_d_h_i_s', time() );
move_uploaded_file( $uploadedFile, $dir. $fileName);
}
I got one Notice to:
Notice (8): Undefined index: UploadFile [APP\Controller\UploadFileController.php, line 7]
Thank you for any clue !
Solution
View File (uploadfile.ctp) :
<?php
echo $this->Form->create('uploadFile', array( 'type' => 'file'));
?>
<div class="input_fields_wrap">
<label for="uploadFilefiles"></label>
<input type="file" name="data[]" id="uploadFilefiles">
</div>
<button type="button" class="add_field_button">+</button> <br><br>
<form name="frm1" method="post" onsubmit="return greeting()">
<input type="submit" value="Submit">
</form>
<?php
echo $this->Html->script('addFile');
Controller (UploadFileController.php) :
class UploadFileController extends AppController {
public function uploadFile() {
$filename = '';
if ($this->request->is('post')) { // checks for the post values
$uploadData = $this->data;
//print_r($this->data); die;
foreach($uploadData as $file){
if ( $file['size'] == 0 || $file['error'] !== 0) { // checks for the errors and size of the uploaded file
return false;
}
$filename = basename($file['name']); // gets the base name of the uploaded file
$uploadFolder = WWW_ROOT. 'files'; // path where the uploaded file has to be saved
$filename = $filename; // adding time stamp for the uploaded image for uniqueness
$uploadPath = $uploadFolder . DS . $filename;
if( !file_exists($uploadFolder) ){
mkdir($uploadFolder); // creates folder if not found
}
if (!move_uploaded_file($file['tmp_name'], $uploadPath)) {
return false;
}
echo "Filename: $filename<br>";
}
}
}
}
Script (addFile.js) :
$(document).ready(function() {
var max_fields = 2;
var wrapper = $(".input_fields_wrap");
var add_button = $(".add_field_button");
var x = 1;
$(add_button).click(function(e){
e.preventDefault();
if(x <= max_fields){
x++;
$(wrapper).append("<div><input type='file' name='data[]' id='uploadFilefiles'/><button href='#' class='remove_field'>Kustuta</button></div>");
}
});
$(wrapper).on("click",".remove_field", function(e){ //user click on kustuta text
e.preventDefault(); $(this).parent('div').remove(); x--;
})
});
I want to track the upload progress of a file to my server so I read this (German) article. I already checked my PHP.ini:
session.upload_progress.enabled = 1
session.upload_progress.cleanup = 1
session.upload_progress.prefix = upload_progress_
session.upload_progress.name = PHP_SESSION_UPLOAD_PROGRESS
session.upload_progress.freq = 1%
session.upload_progress.min_freq = 1
upload_max_filesize = 128M
I began to write a very simple script that only shows a form and uploads a file, when submitted:
<!-- upload.php -->
<?php
session_start();
$maxSize = 10485760;
$uploadName = "test";
if (#$_POST["upload"] ?: 0) { // Check, if upload is in progress
$t = getcwd() . "\\" . basename($_FILES["file"]["name"]);
if ($_FILES["file"]["size"] > $maxSize) {
echo "Upload " . (move_uploaded_file($_FILES["file"]["tmp_name"], $t) ? "succeeded" : "failed"); // Return, if upload is succeeded or failed
}
} else {
?>
<form action="<?= basename(__FILE__); ?>" enctype="multipart/form-data" id="frmUpload" method="POST" target="upload">
<input name="file" type="file" />
<input type="submit" value="Upload" />
<input name="MAX_FILE_SIZE" type="hidden" value="<?= $maxSize; ?>" />
<input name="upload" type="hidden" value="1" />
<input name="<?= ini_get("session.upload_progress.name"); ?>" type="hidden" value="<?= $uploadName; ?>" /> <!-- Set session name -->
</form>
<div style="display: none; ">
<iframe id="upload"></iframe>
</div>
<?php
}
?>
My second script should check the upload progress with the session name
// uploadProgress.php
<?php
session_start();
$pName = ini_get("session.upload_progress.prefix") . "test";
echo json_encode(#$_SESSION[$pName] ?: []);
?>
I created a 10mb file, to ensure a long upload time. Everytime I call uploadProgress.php while the upload is running $_SESSION[$pName] is not set and I cannot find my mistake. Is there something I overlooked or something I made wrong?
Forgive me as I'm not used to the syntax you're using... Not sure why you're using ternary operators in your IF statements, or why you're suppressing the $_SESSION and $_POST variables.
The only thing that stands out to me in your examples is I don't see any call to session_start()?
Here is another article that may help.
Solved the problem. Found a way to track the progress with JavaScript. Here is my solution:
/**********************\
| Script of upload.php |
\**********************/
var ui = { elems: ["dUploads", "fFile", "frmUpload", "pbPercent", "pbUpload", "pbWrpUpload"] }; for (var n = 0; n < ui.elems.length; n++) { ui[ui.elems[n]] = document.getElementById(ui.elems[n]); } delete ui.elems;
function refreshUploads (files) {
var tmp;
while (tmp = dUploads.firstChild) {
tmp.remove();
}
for (var file in files) {
var a = document.createElement("a");
a.setAttribute("href", "uploads/" + files[file]);
a.setAttribute("target", "_blank");
a.appendChild(document.createTextNode(files[file]));
var div = document.createElement("div");
div.appendChild(a);
ui.dUploads.appendChild(div);
}
}
ui.frmUpload.onsubmit = function (e) {
e.preventDefault();
var ajax = new XMLHttpRequest();
var data = new FormData();
data.append("ajax", 1);
data.append("file", ui.fFile.files[0]);
ajax.upload.onprogress = function (e) {
var percent = Math.floor(e.loaded / e.total * 100) + "%";
ui.pbUpload.style.left = percent;
ui.pbPercent.style.left = percent;
ui.pbPercent.innerHTML = percent;
};
ajax.onreadystatechange = function (e) {
if (ajax.readyState == 4 && ajax.status == 200) {
ui.pbWrpUpload.style.opacity = "0";
refreshUploads(eval(ajax.responseText));
}
};
ui.pbWrpUpload.style.opacity = "1";
ajax.open("POST", "upload.php", true);
ajax.send(data);
};
refreshUploads([]); // Normally all already existing files are loaded via PHP
I have a single file named test.php. In this file, I written below codes to upload a picture (.PNG and .JPG). I also add some code to make a preview of pictures before being uploaded...
Nothing seems to be wrong but when I press the SUBMIT button, nothing happens...
Why? Where is my problem?
Update: I make changes and now I get this warning:
Warning: Invalid argument supplied for foreach() in...
test.php:
<script type="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
<body>
<?php
if ( isset( $_POST[ 'submit' ] ) ) {
define ("UPLOAD_DIR" , "uploaded/pic/");
foreach ($_FILES["images"]["error"] as $key => $error) {
if ($error == UPLOAD_ERR_OK) {
$name = $_FILES["images"]["name"][$key];
$info = getimagesize($_FILES["images"]["tmp_name"][$key]);
$image_type = $info[2];
$type = $_FILES['images']['type'][$key];
// if the image is .JPG or .PNG
if ( ($image_type == 3) || ($image_type == 2) ){
// ensure a safe filename
$name = preg_replace("/[^A-Z0-9._-]/i", "_", $name);
// don't overwrite an existing file
$i = 0;
$parts = pathinfo($name);
while (file_exists(UPLOAD_DIR . $name)) {
$i++;
$name = $parts["filename"] . "-" . $i . "." . $parts["extension"];
}
// preserve file from temporary directory
$success = move_uploaded_file($_FILES["images"]["tmp_name"][$key], UPLOAD_DIR . $name);
if (!$success) {
echo "<p>Unable to save file.</p>";
exit;
}
// set proper permissions on the new file
chmod(UPLOAD_DIR . $name, 0644);
echo "<h2>Successfully Uploaded Images</h2>";
}
else{
echo "<h2>format not supported... </h2>";
}
}
}
}
?>
<div id="upload_form">
<form id="frm1" name="frm1" method="post" action="test.php" enctype="multipart/form-data">
<p>
<label for="images">insert your image</label>
<input type="file" name="images" id="images" tabindex="80"/>
</p>
<img id="pic" name="pic" src="#" />
<button type="submit" id="submit" name="submit">Upload Files!</button>
</form>
<script type="text/javascript" language="javascript">
// Preview the picture before Uploading on the server!
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#pic').attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
}
$("#images").change(function(){
readURL(this);
});
</script>
</div>
You need to put your name="images as an array using []
Like this:
<input type="file" name="images[]" id="images" tabindex="80"/>
I'm writing a fairly simple fileserver and was doing well with uploading a single file, moving it to a folder on the server and keeping info about it in a database. Now when I tried modifying it to accept multiple files from a single input field, I can't get it to progress past the first test for errors.
This is my index.php here:
<body>
<img src="style/images/sitename.gif" alt="sitename" align="absmiddle" class="displayed" />
<div id="sidediv">
<ul>
<li>Multiple files uploaded at once will return a link to a zip archive of those files.
</ul>
</div><!--close the sidediv-->
<div id="container">
<div id="content">
<!--form starts here-->
<form action="upload.php" id="group" method="post" enctype="multipart/form-data" target="upload_target" onsubmit="startUpload();" >
<p id="f1_upload_process">Loading...<br/><img src="loader.gif" /><br/></p>
<p id="f1_upload_form" align="center"><br/>
<label>File:
<input name="myfile[]" type="file" size="30" multiple="multiple" />
</label>
<label>
<input type="submit" name="submitBtn" class="sbtn" value="Upload" multiple="multiple" />
</label>
</p>
<iframe id="upload_target" name="upload_target" src="#" style="width:0;height:0;border:0px solid #fff;"></iframe>
</form>
<!--form ends here-->
</div>
<!--<div id="footer">sitename</div>-->
</div>
<div id="link"></div>
</body>
And my upload.php here:
<?php
//database
$username="";
$password="";
$database="";
mysql_connect(localhost,$username,$password);
#mysql_select_db($database) or die( "Unable to select database");
$message = array();
$result = array();
$fileName = array();
$ext = array();
$tmpName = array();
$path = array();
$target_path = array();
$count = count($_FILES['myfile']['name']);
for($i=0;$i<$count;$i++)
{
//file info
$fileName[$count] = $_FILES['myfile']['name'][$count]; // Get the name of the file (including file extension).
$ext[$count] = pathinfo($fileName[$count], PATHINFO_EXTENSION); // Get the extension from the filename.
$tmpName[$count] = $_FILES['myfile']['tmp_name'][$count];
$fileSize[$count] = $_FILES['myfile']['size'][$count];
$fileType[$count] = $_FILES['myfile']['type'][$count];
//file info
/* $fileName = $myfile['name']; // Get the name of the file (including file extension).
$ext = pathinfo($fileName, PATHINFO_EXTENSION); // Get the extension from the filename.
$tmpName = $myfile['tmp_name'];
$fileSize = $myfile['size'];
$fileType = $myfile['type'];*/
// Edit upload location here
$destination_path = './files/';
$allowed_filetypes = array('idx','sub','txt','srt');
$max_filesize = 5242880; //bytes
$prefix = substr(md5(time()),0,7); //new name of the file
$target_path[$count] = $destination_path . $prefix .".".$ext[$count];
// Check if the filetype is allowed, if not DIE and inform the user.
if(!in_array($ext[$count],$allowed_filetypes)){
$result[$count] = 2;
$message[$count] = "The file you attempted to upload is not allowed.".$fileName[$count];}
// Now check the filesize, if it is too large then DIE and inform the user.
else if(filesize($_FILES['myfile']['tmp_name'][$count]) > $max_filesize){
$result[$count] = 3;
$message[$count] = "The file you attempted to upload is too large.";}
else if(!file_exists($destination_path)){
$result[$count] = 4;
$message[$count] = "The upload path does not exist";}
// Check if we can upload to the specified path, if not DIE and inform the user.
else if(!is_writable($destination_path)){
$result[$count] = 5;
$message[$count] = "You cannot upload to the specified directory, please CHMOD it to 777.";}
else
{
#move_uploaded_file($tmpName[$count], $target_path[$count]);
$file_info = pathinfo($fileName[$count]);
$sql = "INSERT INTO Files SET
uploader_ip = '".$_SERVER['REMOTE_ADDR']."',
File_Name = '".$fileName[$count]."',
File_Type = '".$fileType[$count]."',
File_Size = '".$fileSize[$count]."',
File_Hash = '".$prefix.".".$ext[$count]."',
File_Extension = '".$file_info['extension']."'";
$sqlresult = mysql_query($sql);
// If the query was successful, give success message
if(!$sqlresult){
$result[$count] = 6;
$message[$count] = "Could not add this file.";//not actually displayed
exit;
}
else{
$message[$count] = "New file successfully added.";//not actually displayed
$result[$count] = 1;
$path[$count] = 'Your file upload was successful, view the file here';
}
}//closes last else (all the writing to the db)
}
sleep(1);
?>
<script language="javascript" type="text/javascript">window.top.window.stopUpload(
<?php echo json_encode($result[$count]); ?>,
<?php echo json_encode($message[$count]); ?>,
<?php echo json_encode($path[$count]); ?>,
<?php echo json_encode($count); ?>,
<?php echo json_encode($fileName[$count]); ?>,
<?php echo json_encode($ext[$count]); ?>);
</script>
Every time I am getting the error "the file you uploaded is not allowed" when it should pass that test. Any help is greatly appreciated.
I think that everywhere that you are using $count in the arrays inside your for loop, you need to be using $i instead of $count.
$count is always the same (and is outside the bounds of the array).
Try that and see if you have any more luck.