PHP download file from server from POST - php

What began here: PHP finding file where post INCLUDES portion of filename
I am trying to finish with this question.
Basically, now that I am able to post a variable to a PHP process, then use that process to find a file in a directory, I now need to be able to download the file if it exists.
Quick recap, after the user has entered a voyage number and the datatable has returned a list of voyages, the user then clicks the link, which is where I'll begin the code:
$('.voyageFileCall').on('click', function()
{
var voyage = $(this).attr('data-voyage');
$.post('fileDownload.php', {voyage:voyage}, function(data)
{
// here is where I need to where either display the file doesn't exist
// or the file downloads
});
});
The process 'fileDownload.php' looks like this:
<?php
if($_POST['voyage'] == true)
{
$voyage = $_POST['voyage'];
$files = scandir("backup/");
if(count($files) > 0)
{
$fileFound = false;
foreach($files as $file)
{
if((preg_match("/\b$voyage\b/", $file) === 1))
{
// I'm guessing the download process should happen here
echo "File found: $file \n"; // <-- this is what I currently have
$fileFound = true;
}
}
if(!$fileFound) die("File $voyage doesn't exist");
}
else
{
echo "No files in backup folder";
}
}
?>
I tried to use the answer found here: Download files from server php
But I'm not exactly sure where I should put the headers, or if I need to use them at all.

The quick solution which i can suggest you is: return path to file if it is exist, and return false if file doesn't exist.
After that in your JS code you can check, if your "data" == false, you can throw an error "file doesn't exist", and if it is not "false", you can call document.location.href = data; - it will redirect your browser to the file and it will be downloaded

Why don't you simply use download attribute:
<?php
if($_POST['voyage'] == true)
{
$voyage = $_POST['voyage'];
$files = scandir("backup/");
if(count($files) > 0)
{
$fileFound = false;
foreach($files as $file)
{
if((preg_match("/\b$voyage\b/", $file) === 1))
{
// I'm guessing the download process should happen here
echo 'File found: <a href="' . $file . '" download>' . $file . '</a> \n'; // <-- this is what I currently have
$fileFound = true;
}
}
if(!$fileFound) die("File $voyage doesn't exist");
}
else
{
echo "No files in backup folder";
}
}
?>
If you really want to use JavasScript to start download then use style="display:none;" for <a> and then in JS just click it:
echo 'File found: <a id="myDownload" style="display:none;" href="' . $file . '" download>' . $file . '</a> \n';
and call it:
$('.voyageFileCall').on('click', function()
{
var voyage = $(this).attr('data-voyage');
$.post('fileDownload.php', {voyage:voyage}, function(data)
{
if(document.getElementById("myDownload")){
document.getElementById("myDownload").click();
}else{
console.log("file does not exist");
}
});
});

Related

Upload fails "move uploaded file"

First off, the upload folder is given 777, and my old upload script works, so the server accepts files. How ever this is a new destination.
I use krajee bootstrap upload to send the files. And I receive a Jason response. The error seems to be around move uploaded file. I bet it's a simple error from my side, but I can't see it.
<?php
if (empty($_FILES['filer42'])) {
echo json_encode(['error'=>'No files found for upload.']);
// or you can throw an exception
return; // terminate
}
// get the files posted
$images = $_FILES['filer42'];
// a flag to see if everything is ok
$success = null;
// file paths to store
$paths= [];
// get file names
$filenames = $images['name'];
// loop and process files
for($i=0; $i < count($filenames); $i++){
$ext = explode('.', basename($filenames[$i]));
$target = "uploads" . DIRECTORY_SEPARATOR . md5(uniqid()) . "." . array_pop($ext);
if(move_uploaded_file($_FILES["filer42"]["tmp_name"][$i], $target)) {
$success = true;
$paths[] = $target;
} else {
$success = false;
break;
}
}
// check and process based on successful status
if ($success === true) {.
$output = [];
$output = ['uploaded' => $paths];
} elseif ($success === false) {
$output = ['error'=>'Error while uploading images. Contact the system administrator'];
// delete any uploaded files
foreach ($paths as $file) {
unlink($file);
}
} else {
$output = ['error'=>'No files were processed.'];
}
// return a json encoded response for plugin to process successfully
echo json_encode($output);
?>
I think field name is the issue. Because you are getting image name with filer42 and upload time, you are using pictures.
Please change
$_FILES["pictures"]["tmp_name"][$i]
to
$_FILES["filer42"]["tmp_name"][$i]
And check now, Hope it will work. Let me know if you still get issue.
The error is not in this script but in the post.
I was using <input id="filer42" name="filer42" type="file">
but it have to be <input id="filer42" name="filer42[]" type="file" multiple>
as the script seems to need an arrey.
It works just fine now.

php-how to delete files from directory if files already exist?

I tried deleting file if its already existing .
But i ended up with no result.
Can any one help me with this!!!
$path_user = '/wp-content/plugins/est_collaboration/Files/'.$send_id.'/';
if (!file_exists($path_user)) {
if (mkdir( $path_user,0777,false )) {
//
}
}
unlink($path_user);
if(move_uploaded_file($file['tmp_name'],$path_user.$path)){
echo "Your File Successfully Uploaded" . "<br>";
}
Organize your code, try this:
$path = 'filename.ext'; // added reference to filename
$path_user = '/wp-content/plugins/est_collaboration/Files/'.$send_id.'/';
// Create the user folder if missing
if (!file_exists($path_user)) {
mkdir( $path_user,0777,false );
}
// If the user file in existing directory already exist, delete it
else if (file_exists($path_user.$path)) {
unlink($path_user.$path);
}
// Create the new file
if(move_uploaded_file($file['tmp_name'],$path_user.$path)) {
echo"Your File Successfully Uploaded"."<br>";
}
Keep in mind that PHP will not recursively delete the directory contents, you should use a function like this one
Maybe you missing else condition ?? And file_name variable :
$file_name = 'sample.jpg';
$path_user = '/wp-content/plugins/est_collaboration/Files/'.$send_id.'/';
if (!file_exists($path_user.$file_name))
{
if (mkdir( $path_user,0777,false )) {
}
} else {
unlink($path_user.$file_name);
}

How to copy the set of files from one folder to another folder using php

I want to copy set of uploaded files from one folder to another folder.From the below code, all the files in one folder is copied.It takes much time. I want to copy only the currently uploaded file to another folder.I have some idea to specify the uploaded files and copy using for loop.But I don't know to implement.I am very new to developing.Please help me.Below is the code.
<?php
// connect to the database
include('connect-db.php');
if (isset($_POST['submit']))
{
// get form data, making sure it is valid
$udate = mysql_real_escape_string(htmlspecialchars($_POST['udate']));
$file_array=($_FILES['file_array']['name']);
// check to make sure both fields are entered
if ($udate == '' || $file_array=='')
{
// generate error message
$error = 'ERROR: Please fill in all required fields!';
// if either field is blank, display the form again
renderForm($udate, $file_array, $error);
}
else
{
$udate = mysql_real_escape_string(htmlspecialchars($_POST['udate']));
if(isset($_FILES['file_array']))
{
$name_arrray=$_FILES['file_array']['name'];
$tmp_name_arrray=$_FILES['file_array']['tmp_name'];
for($i=0;$i <count($tmp_name_arrray); $i++)
{
if(move_uploaded_file($tmp_name_arrray[$i],"test_uploads/".str_replace(' ','',$name_arrray[$i])))
{
// save the data to the database
$j=str_replace(' ','',$name_arrray[$i]);
echo $j;
$udate = mysql_real_escape_string(htmlspecialchars($_POST['udate']));
$provider = mysql_real_escape_string(htmlspecialchars($_POST['provider']));
$existfile=mysql_query("select ubatch_file from batches");
while($existing = mysql_fetch_array( $existfile)) {
if($j==$existing['ubatch_file'])
echo' <script>
function myFunction() {
alert("file already exists");
}
</script>';
}
mysql_query("INSERT IGNORE batches SET udate='$udate', ubatch_file='$j',provider='$provider',privilege='$_SESSION[PRIVILEGE]'")
or die(mysql_error());
echo $name_arrray[$i]."uploaded completed"."<br>";
$src = 'test_uploads';
$dst = 'copy_test_uploads';
$files = glob("test_uploads/*.*");
foreach($files as $file){
$file_to_go = str_replace($src,$dst,$file);
copy($file, $file_to_go);
/* echo "<script type=\"text/javascript\">
alert(\"CSV File has been successfully Uploaded.\");
window.location = \"uploadbatches1.php\"
</script>";*/
}
} else
{
echo "move_uploaded_file function failed for".$name_array[$i]."<br>";
}
}
}
// once saved, redirect back to the view page
header("Location:uploadbatches1.php");
}
}
else
// if the form hasn't been submitted, display the form
{
renderForm('','','');
}
?>
To copy only the uploaded files, there is only a slight change in the coding which I have made. That is instead of using "." from one folder, I passed the array value. So that only the files which are uploaded will be copied to the new folder instead of copying everything which takes long time.Below is the only change made to do:
$files = glob("test_uploads/$name_arrray[$i]");

Adding Random Number to Uploaded File

I'm using Valum's Ajax-Uploader script to upload files to my server. Because there's a good chance of the uploaded files have the same name I add a random number to the filename. The problem is that the ajax uploader is returning the original filename into the input[type=text] instead of the new filename with the random number added. I've tried echo $file; instead of echo "success"; , but all that happens is that the file is uploaded, and the script returns with the pop-up error.
jQuery(function() {
var url = "http://example.com/uploads/samples/";
var button = jQuery('#up');
new AjaxUpload(button, {
action: 'upload.php',
name: 'upload',
autoSubmit: true,
onSubmit: function(file, ext) {
// do stuff while file is uploading
},
onComplete: function(file, response) {
if (response === "success") {
$('input[type=text]').val(url + file);
} else {
jAlert('Something went wrong!', 'Error!');
}
}
});
});
upload.php
<?php
$uploaddir = '/path/to/uploaddir/';
$file = basename($_FILES['file']['name']);
if($_FILES['file']['name']) {
$file = preg_replace('/\s+/', '_', $file);
$rand = rand(0000,9999);
if (move_uploaded_file($_FILES['file']['tmp_name'], $uploaddir . $rand . $file)) {
echo "success";
} else {
echo "error";
}
}
?>
Change
$('input[type=text]').text(url + file);
To
$('input[type=text]').val(url + file);
Client code and server code exist completely independently of each other. Basically, your JavaScript code has no way of knowing what your PHP code just did. url doesn't update automatically when you change it in the PHP file.
An alternate solution would be to have your PHP code echo the new filename, or echo an error message.
For example:
PHP
<?php
if (move_uploaded_file($_FILES['file']['tmp_name'], $uploaddir . $rand . $file)) {
// Everything went well! Echo the dollar sign ($) plus the new file name
echo '$' . $_FILES['file']['tmp_name'], $uploaddir . $rand . $file;
} else {
echo "error";
}
?>
JS
onComplete: function(file, response) {
// If the first character of the response is the "$" sign
if (response.substring(0,1) == "$") {
$('input[type=text]').val(response.substring(1));
} else {
jAlert('Something went wrong!', 'Error!');
}
}
I would like to suggest using date and time to create a unique random number.
You can use following function in your code, I am fully trusted on this function because I already use this in my project.
`
/**
* This function return unique string as a key
*/
public static function getUniqueKey(){
$currentDateTime = date("YmdHisu");
return $currentDateTime . BTITTools::createRandomString(3);
}
`
# My Code Programs

Passing uploaded files to another part of the script for onward processing

I have searched the forum but the closest question which is about the control stream did not help or I did not understand so I want to ask a different question.
I have an html form which uploads multiples files to a directory. The upload manager that handles the upload resides in the same script with a different code which I need to pass the file names to for processing.
The problem is that the files get uploaded but they don't get processed by the the other code. I am not sure about the right way to pass the $_FILES['uploadedFile']['tmp_name']) in the adjoining code so the files can be processed with the remaining code. Please find below the script.
More specif explanation:
this script does specifically 2 things. the first part handles file uploads and the second part starting from the italised comment extracts data from the numerous uploaded files. This part has a variable $_infile which is array which is suppose to get the uploaded files. I need to pass the files into this array. so far I struggled and did this: $inFiles = ($_FILES['uploadedFile']['tmp_name']); which is not working. You can see it also in the full code sample below. there is no error but the files are not passed and they are not processed after uploading.
<?php
// This part uploads text files
if (isset($_POST['uploadfiles'])) {
if (isset($_POST['uploadfiles'])) {
$number_of_uploaded_files = 0;
$number_of_moved_files = 0;
$uploaded_files = array();
$upload_directory = dirname(__file__) . '/Uploads/';
for ($i = 0; $i < count($_FILES['uploadedFile']['name']); $i++) {
//$number_of_file_fields++;
if ($_FILES['uploadedFile']['name'][$i] != '') { //check if file field empty or not
$number_of_uploaded_files++;
$uploaded_files[] = $_FILES['uploadedFile']['name'][$i];
//if (is_uploaded_file($_FILES['uploadedFile']['name'])){
if (move_uploaded_file($_FILES['uploadedFile']['tmp_name'][$i], $upload_directory . $_FILES['uploadedFile']['name'][$i])) {
$number_of_moved_files++;
}
}
}
}
echo "Files successfully uploaded . <br/>" ;
echo "Number of files submitted $number_of_uploaded_files . <br/>";
echo "Number of successfully moved files $number_of_moved_files . <br/>";
echo "File Names are <br/>" . implode(',', $uploaded_files);
*/* This is the start of a script to accept the uploaded into another array of it own for* processing.*/
$searchCriteria = array('$GPRMC');
//creating a reference for multiple text files in an array
**$inFiles = ($_FILES['uploadedFile']['tmp_name']);**
$outFile = fopen("outputRMC.txt", "w");
$outFile2 = fopen("outputGGA.txt", "w");
//processing individual files in the array called $inFiles via foreach loop
if (is_array($inFiles)) {
foreach($inFiles as $inFileName) {
$numLines = 1;
//opening the input file
$inFiles = fopen($inFileName,"r");
//This line below initially was used to obtain the the output of each textfile processed.
//dirname($inFileName).basename($inFileName,'.txt').'_out.txt',"w");
//reading the inFile line by line and outputting the line if searchCriteria is met
while(!feof($inFiles)) {
$line = fgets($inFiles);
$lineTokens = explode(',',$line);
if(in_array($lineTokens[0],$searchCriteria)) {
if (fwrite($outFile,$line)===FALSE){
echo "Problem w*riting to file\n";
}
$numLines++;
}
// Defining search criteria for $GPGGA
$lineTokens = explode(',',$line);
$searchCriteria2 = array('$GPGGA');
if(in_array($lineTokens[0],$searchCriteria2)) {
if (fwrite($outFile2,$line)===FALSE){
echo "Problem writing to file\n";
}
}
}
}
echo "<p>For the file ".$inFileName." read ".$numLines;
//close the in files
fclose($_FILES['uploadedFile']['tmp_name']);
fflush($outFile);
fflush($outFile2);
}
fclose($outFile);
fclose($outFile2);
}
?>
Try this upload class instead and see if it helps:
To use it simply Upload::files('/to/this/directory/');
It returns an array of file names that where uploaded. (it may rename the file if it already exists in the upload directory)
class Upload {
public static function file($file, $directory) {
if (!is_dir($directory)) {
if (!#mkdir($directory)) {
throw new Exception('Upload directory does not exists and could not be created');
}
if (!#chmod($directory, 0777)) {
throw new Exception('Could not modify upload directory permissions');
}
}
if ($file['error'] != 0) {
throw new Exception('Error uploading file: '.$file['error']);
}
$file_name = $directory.$file['name'];
$i = 2;
while (file_exists($file_name)) {
$parts = explode('.', $file['name']);
$parts[0] .= '('.$i.')';
$new_file_name = $directory.implode('.', $parts);
if (!file_exists($new_file_name)) {
$file_name = $new_file_name;
}
$i++;
}
if (!#move_uploaded_file($file['tmp_name'], $file_name)) {
throw new Exception('Could not move uploaded file ('.$file['tmp_name'].') to: '.$file_name);
}
if (!#chmod($file_name, 0777)) {
throw new Exception('Could not modify uploaded file ('.$file_name.') permissions');
}
return $file_name;
}
public static function files($directory) {
if (sizeof($_FILES) > 0) {
$uploads = array();
foreach ($_FILES as $file) {
if (!is_uploaded_file($file['tmp_name'])) {
continue;
}
$file_name = static::file($file, $directory);
array_push($uploads, $file_name);
}
return $uploads;
}
return null;
}
}

Categories