Initiate download without button - php

I'm a PHP newbie ... and stuck!
I would like to realize this HTML/PHP project in a single file (as opposed to using .html and .php files separately).
Basically, 3 steps are necessary.
upload a PDF file.
process the PDF file. Output is a .txt file.
offer the user the processed .txt file without the standard download button.
(1.) and (2.) is already properly implemented and works fine. (3.) is my problem/question. The internet offers several solutions, but all with download buttons which the user has to press to trigger download from server to local machine. I would like to write (in PHP only) code which offers the user a Save Dialog Box, which permits saving the .txt file locally. Is this possible without any HTML code, hence solely by PHP?
Below the real code heavily simplified to the necessary.
<form action = "" method = "POST" enctype = "multipart/form-data">
Select PDF file to be uploaded.
<input type = "file" name="pdffile" />
<input type = "submit" name = "submit" value = "upload roster" />
</form>
<?php
if(isset($_FILES['pdffile'])) {
$errors = array();
$file_name = $_FILES['pdffile']['name'];
$file_size = $_FILES['pdffile']['size'];
$file_tmp = $_FILES['pdffile']['tmp_name'];
...
move_uploaded_file($file_tmp, "/home/user/pdf2txt/uploads/" . $file_name);
$cmd = "../../pdf2txt/pdf2txt ../../pdf2txt/uploads/" . $file_name;
...
// the stdout of pdf2txt is stored in /tmp/pdffile.txt
// initiate download to user - THAT'S MY PROBLEM/QUESTION
...
?>
EDIT
Maybe I was too short. The project should be realized inside a WordPress page. I use a PHP plugin which permits PHP code injection. Now ... using the code of #mrid, I get ...
Warning: Cannot modify header information – headers already sent by (output started at /home/geohei/mysite/WP_TEST/wp-content/themes/blackoot-pro/header.php:12) in /home/geohei/mysite/WP_TEST/wp-content/plugins/insert-php/insert_php.php(48) : eval()’d code on line 81
insert-php.php is the WordPress PHP plugin.
blackroot is the theme.
I understand that headers were already previously sent by the theme and I am not allowed to change them.
What can be done in such a situation?

Here's an example of
header('Content-Disposition: attachment; filename=' . basename($filename) . '"');
header("Content-type: text/plain");
header('Content-Length: ' . filesize($filename));
readfile($filename);

Related

Using input[type="file"] to prompt the user to save the file

I am trying to achieve two actions from an input file tag. I have the following input:
<input id='file-input' name='attach' type='file' style='margin-left:15px;'/>
This is found in messages.php. What I am trying to achieve are two things:
If the file uploaded is over 1mb in size (or is a file which is not an image), then produce a button which on click opens the save as menu, from where a user can select where they wish to download the data.
And secondly, as mentioned, if the file size is lower than 1mb, then simply display the data on the page (only works for image files).
I have other pages where I have used input type="file" to upload profile images, and have just displayed the image on the page. But I am unsure on how I can execute (1) - how I can open a menu from where the user can save the data?
Just serve the file with a Content-Disposition: attachment header, see PHP Outputting File Attachments with Headers
Among other nice answers I will do it this way.
I have made it possible by clicking on your suggested Download button, if file is greater than 1Mb you will get download pop up like this
Otherwise if file less than 1Mb it will just show it on browser will look like this:
Btw, the code is self explaining.
PHP part called index.php
<?php
$filename = "test3.jpg";
$maxSize = 1000000; // 1Mb
if (isset($_POST['save']))
fileHandler($filename, $maxSize);
function fileHandler($filename, $maxSize)
{
$fileinfo = getimagesize($filename);
$filesize = filesize($filename);
$fp = fopen($filename, "rb");
if ($fileinfo && $fp)
{
header("Content-Type: {$fileinfo['mime']}");
if ($filesize > $maxSize)
{
header('Content-Disposition: attachment; filename="NewName.jpg"');
}
fpassthru($fp);
exit;
} else
{
echo "Error! please contact administrator";
}
}
?>
HTML part inside index.php but it is important this code should comes after php tags and not before.
<form action="index.php" method="post">
<button type="submit" style="border: 0; background: transparent" name="save">
<img src="download.jpg" alt="submit" />
</button>
</form>
Note: it is important your php document start directly with <?php ..., please read
You won't need to fake a click or something. You probably need something like this.
User selects file and clicks the "Upload file" button.
File gets uploaded using e.g. PHP.
PHP displays the contents of the file, using the correct headers.
PHP determines if the file is smaller or larger than 1MB.
If the file is larger, set a header that forces the user to download the file (causing a select location popup).
If the file is smaller, do not set the header, causing the file to display in the browser.
Where Italic is a user action and Bold is a server action.
You can do this by getting the image mime type and setting the content disposition and content type headers:
$file = 'path/to/file';
if (file_exists($file)) {
$contents = file_get_contents($file);
$fileSize = filesize($file);
$image_info = getImageSize($file);
$mimeType = $image_info['mime'];
header("content-disposition: attachment; filename=" . basename($file));
header("content-type:$mimeType");
header("Content-length: $fileSize");
echo $contents;
exit;
}

File downloaded from PHP script is different than file on server

I have a html file that allows a user to submit a file to post a file to my 'upload_file.php' PHP script.
index.html:
<html>
<body>
<form action="upload_file.php" method="post" enctype="multipart/form-data">
<label for="file">Filename:</label>
<input type="file" name="file" id="file"><br>
<input type="submit" name="submit" value="Submit">
</form>
</body>
</html>
upload_file.php referenced above takes in a file, does some work, and spits out a xlsx file (using PHPExcel). After creating the PHPExcel object, this is how I write it to the server and then force the user to download:
// Save Excel 2007 file
$objWriter = new PHPExcel_Writer_Excel2007($objPHPExcel);
$fileBase = explode(".",$_FILES['file']['name']);
$outFilename = $fileBase[0] . date('His') . ".xlsx";
$objWriter->save($outFilename);
$url = "http://localhost/QWDATA/$outFilename";
//Initiate user download of file
header("Content-Type: application/octet-stream");
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"$outFilename\"");
echo readfile($url);
When I do this, the download is initiated successfully... with one issue:
Opening the file that is downloaded results in an error in excel:
"We found a problem with some content in $filename. Do you want us to
try to recover as much as we can? If you trust the source of this
workbook, click Yes."
Clicking "yes" on the excel error results in a 'repaired' xlsx file opening and looking exactly as one would expect. Looking at a log of repairs that were done gives me this:
error129480_02.xmlErrors
were detected in file
'C:\XPATHX\$filename.xlsx'Excel
completed file level validation and repair. Some parts of this
workbook may have been repaired or
discarded.
... which is to say, nothing specific.
Tracking the issue back, opening the file directly from the server does NOT result in this error; telling me something additional is going on in the download code above.
My question is: What could be causing this and/or how can I solve the problem?
readfile echoes by itself. You don't need to call echo.
Actually, doing so, will echo the result of readfile (which is the size of the file as an integer), so that causes a couple of extra bytes at the end of the file. This will be easy for Excel to fix, and probably won't result in actual data loss, but still the file is invalid, so you get the error.
Looking at the file on the server and the file that downloads, I noticed a 5 byte difference.
Having already removed all other echo commands from the php file due to suggestions here (https://phpexcel.codeplex.com/discussions/42854) and here (PHPExcel File format or extension is not valid) I knew something had to be adding information.
I made the following changes to the above code -- taking out the escaped quotes in the filename (just a personal guess) in the header setting and changing echo to readfile (as suggested here: http://webdesign.about.com/od/php/ht/force_download.htm). Thus giving me:
// Save Excel 2007 file
$objWriter = new PHPExcel_Writer_Excel2007($objPHPExcel);
$fileBase = explode(".",$_FILES['file']['name']);
$outFilename = $fileBase[0] . date('His') . ".xlsx";
$objWriter->save($outFilename);
$url = "http://localhost/QWDATA/$outFilename";
//Initiate user download of file
header("Content-disposition: attachment; filename=$outFilename");
header("Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
header("Content-Transfer-Encoding: Binary");
readfile($outFilename);
This appears to directly download the file with no additions -- which means excel is happy and the problem is solved.
In short, it appears echo readfile($outFilename); needed to just be readfile($outFilename);

Link to a PDF in html, the file has no extension, but I know it is pdf how to make it open appropriately

First post. I'm working on a project for a client where they have pdf files uploaded to a file structure (LAMP Stack) but the files have no extensions on them. Under the assumption that those files have to be PDF how would I get the browsers to understand that, and open them accordingly? Obviously with adding the file extensions this would suddenly work but I can't change the way their system works, it would result in too many changes and they are on a tight deadline. As for saving a temporary copy somewhere, I could do that, but I was hoping for a better solution. Is there a way to suggest to the browsers that they open a file a certain way?
Any thoughts guys/gals?
You just set the application type and file name in the headers, like so:
// This points to the file in question, note that it doesn't
// care whether it has an extension on the name or not.
$filePathOnDisk = '/path/to/your/pdffile';
// You can make this whatever you like, it doesn't have to
// be the same as the file name on the disk! This is the name of the file your end
// user will see when they are asked if they want to save. open, etc in the browser.
$fileName = 'file.pdf';
$data = file_get_contents($filePathOnDisk);
header("Content-type: application/pdf");
header("Content-disposition: attachment;filename=$fileName");
echo $data;
See PHP: stream remote pdf to client browser and Proper MIME media type for PDF files for reference as well.
Tested
You can use the following which will prompt the user to save the (PDF) file on their computer.
Notice the different file names.
One is the file that will be uploaded/prompted to the user download_example.pdf, while the other is the file without an extension as set in readfile('example');
<?php
header('Content-type: application/pdf');
header('Content-Disposition: attachment; filename="download_example.pdf"');
readfile('example');
?>

html/php user download files

On my web server, I have a bat (harmless) file.
And I have code,
Test Bat File
But when the user clicks, it shows the code instead of downloading the file.
You have to right click "save as.." to download the bat file.
Is there way that when a user clicks, it downloads (not having to right click save as)?
Maybe a pop up window that asks user if he/she wants to download the file or not?
you could write a php file, which adds a content-disposition header, sets the mime type to something binary and echo the files content.
Example:
file.php
$batchfile = file_get_contents('batchlocation');
$size = strlen($batchfile);
header('Content-Disposition: attachment; filename="downloaded.bat"');
header('Content-Type: BAT MIME TYPE or something like application/octet-stream');
header('Content-Lenght: '.$size);
echo $batchfile;
You can do so through setting the file in the PHP header() function.
It is explained here:
How to Automatically Start a Download in PHP?

Javascript and PHP export data to file

I have a button. By clicking the button, I want to export some data shown on the webpage to a file for downloading.
I am doing this in this way: I have a export.php. I send the data as the parameter to PHP file (another parameter is filename), and PHP server create a file and write the data, and then send file. Code is like:
$filename = $_GET['filename'] . '.csv';
$export = $_GET['export'];
$writer = fopen($filename, 'w') or die('cannot create');
fwrite($writer, $export . "\n");
fclose($writer);
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename='.basename($filename));
readfile($filename);
unlink($filename);
exit();
For cases that the data are short, it works fine. But if the data are long, since the data are passed as part of the URL, I will get "Request-URI Too Large" error.
Is there any alternative way to do that? Is it possible to directly write data using JavaScript?
It sounds like you are sending to export.php with a GET, when you should be using a POST. GET is limited to 2048 characters, while a POST is not limited.
You'll need to POST the data to the server. Change the METHOD in your FORM tag to POST (in your html not your php code).
Each browser limits the size of the query string / length of the URL and the limit is browser dependent. You can POST a very large amount of data to the server however. The only limit is how fast is the user's upstream bandwidth and their patience.
Instead of passing the data as a query string, use javascript to create an iframe and build a form which then posts to the php file.
IF your using jquery there's a good tutorial http://tutorialzine.com/2011/05/generating-files-javascript-php/

Categories