PHP Form - download to zip - php

I have the following form:
<form action="download.php" method="get">
<input type="checkbox" name="file1" /> File1 <br/>
<input type="checkbox" name="file2" /> File2 <br/>
<input type="checkbox" name="file3" /> File3 <br/>
<input type="checkbox" name="file4" /> File4 <br/>
<input type="checkbox" name="file5" /> File5 <br/>
<input type="submit" name="mysubmit" value="Download!">
</form>
I cant then GET the ticked value:
<?php echo $_GET["file1"]; ?>
Gives the result: on
However want I want to be able to do is select those options, and each option relates to a PHP file, on Submit each file is combiled into a ZIP
Any help appreciated.

First, add a value field to your form fields and change them to an array:
<form action="download.php" method="get">
<input type="checkbox" name="file[0]" value="1" /> File1 <br/>
<input type="checkbox" name="file[1]" value="1" /> File2 <br/>
<input type="checkbox" name="file[2]" value="1" /> File3 <br/>
<input type="checkbox" name="file[3]" value="1" /> File4 <br/>
<input type="checkbox" name="file[4]" value="1" /> File5 <br/>
<input type="submit" name="mysubmit" value="Download!">
</form>
Next, in download.php:
if (!empty($_POST['file'])) {
// open zip
$zip_path = '/path/to/created/download.zip';
$zip = new ZipArchive();
if ($zip->open($zip_path, ZIPARCHIVE::CREATE) !== TRUE) {
die ("An error occurred creating your ZIP file.");
}
// checkbox values dont matter because only checked boxes show up in POST data
foreach ($_POST['file'] as $key => $val) {
// generate filename to add to zip
$filename = '/path/to/php/file' . $key . '.php';
$zip->addFile($filename) or die ("ERROR: Could not add the file $filename");
}
$zip->close();
//===============
// force download
//===============
// assume you have a full path to file stored in $zip_path
if (!is_file($zip_path)) {
die('The file appears to be invalid.');
}
$zip_path = str_replace('\\', '/', realpath($zip_path));
$filesize = filesize($zip_path);
$filename = substr(strrchr('/'.$zip_path, '/'), 1);
$extension = strtolower(substr(strrchr($zip_path, '.'), 1));
// use this unless you want to find the mime type based on extension
$mime = array('application/octet-stream');
header('Content-Type: '.$mime);
header('Content-Disposition: attachment; filename="'.$filename.'"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: '.sprintf('%d', $filesize));
header('Expires: 0');
// check for IE only headers
if (isset($_SERVER['HTTP_USER_AGENT']) && (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false))) {
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
} else {
header('Pragma: no-cache');
}
$handle = fopen($filepath, 'rb');
fpassthru($handle);
fclose($handle);
} // close $_POST check

You can use isset($_FILES['file1']) to check if file1 is uploaded
Loop from file1 to file5
Save files from temporary paths to permanent ones
Zip them using http://php.net/manual/en/book.zip.php & http://php.net/manual/en/ref.zip.php
Optional: Delete the uploaded files (using unlink)
Force download the zip file to the browser. See this: http://php.net/manual/en/function.header.php
It's quite simple. Enjoy!

Related

PHP Download Button Not Working Generate Empty File

I have two button in the form, one is to submit and second button download the output shown in the textarea.
The submit works fine but download button create empty file and does not write data of output text area.
Here is code:
<?php
error_reporting(0);
$mytext = "";
$txt = preg_replace('/\n+/', "\n", trim($_POST['inputtext']));
$text = explode("\n", $txt);
$output = array();
if(isset($_POST["submit"]))
{
for($i=0;$i<count($text);$i++)
{
$output[] .= trim($text[$i]) . ' Text added with output'.PHP_EOL;
}
}
if(isset($_POST["download"]) ) {
$handle = fopen("file.txt", "w");
fwrite($handle, implode($output));
fclose($handle);
header('Content-type: application/octet-stream');
header('Content-Disposition: attachment;filename='.basename('file.txt'));
header('Expires: 0');
ob_end_clean();
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize('file.txt'));
readfile('file.txt');
exit;
}
?>
<form method="POST" action="test.php">
<textarea name="inputtext" rows="10" cols="100" placeholder="Enter Any Text!" required><?php if(!empty($_POST["inputtext"])) { echo $_POST["inputtext"]; } ?></textarea>
<br><br>
<input type="submit" name="submit" value="Do it!">
<br><br>
<p>Output goes here. </p><textarea name="oputputtext" rows="10" cols="100" ><?php echo implode($output);?></textarea>
<input type="submit" name="download" value="Download Output">
</form>
You have to generate the output also if downloading (unless you take it from the second textarea), so use if(isset($_POST["submit"]) || isset($_POST["download"]) ) in the test, instead of only if(isset($_POST["submit"]))
The final code would look like this:
<?php
error_reporting(0);
$mytext = "";
$txt = preg_replace('/\n+/', "\n", trim($_POST['inputtext']));
$text = explode("\n", $txt);
$output = array();
/* CHANGED HERE */
if(isset($_POST["submit"]) || isset($_POST["download"]) ) {
for($i=0;$i<count($text);$i++) {
$output[] .= trim($text[$i]) . ' Text added with output'.PHP_EOL;
}
}
if(isset($_POST["download"]) ) {
$handle = fopen("file.txt", "w");
fwrite($handle, implode("\r",$output));
fclose($handle);
header('Content-type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename('file.txt'));
header('Expires: 0');
ob_end_clean();
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize('file.txt'));
readfile('file.txt');
exit;
}
?>
<form method="POST" action="test.php">
<textarea name="inputtext" rows="10" cols="100" placeholder="Enter Any Text!" required><?php if(!empty($_POST["inputtext"])) { echo $_POST["inputtext"]; } ?></textarea>
<br><br>
<input type="submit" name="submit" value="Do it!">
<br><br>
<p>Output goes here. </p>
<textarea name="oputputtext" rows="10" cols="100" ><?php echo implode($output);?></textarea>
<input type="submit" name="download" value="Download Output">
</form>

Exporting multiple CSV files from MySQL into zip

Major Edit: I've updated my code to better include the Archive class, as well as the ZIP download. The table is written to the database just fine, but I get an error in my error log saying "No such file or directory." Where do I write the file per table?
Thanks so much for any help/suggestions!
Below is my code:
HTML Form
if($_POST['submit']){
if(empty($_POST['jobtitles'])) echo "<strong>Error: You have not entered a Job Title, please go back and enter one.</strong>";
else echo "<strong>Your documents are processing and being exported.</strong>";
}
?>
<body>
<center><strong><u>BLS Data Processor and Exporter</u></strong></center>
<form method="post" action="handler.php">
<p>Enter all of the desired jobs, each separated by a new line. Note: All jobs must be spelled exactly as contained in the BLS data</p>
<textarea name="jobtitles" rows="10" cols="50">
</textarea>
<p>Upon clicking submit, your tables will be generated and exported as a CSV file</p>
<p>Select the table types you would like to receive</p>
<input type="checkbox" name="tabletype[]" value="local">Local<br>
<input type="checkbox" name="tabletype[]" value="msa">MSA<br>
<input type="checkbox" name="tabletype[]" value="nmsa">NMSA<br>
<input type="checkbox" name="tabletype[]" value="state">State<br>
<input type="checkbox" name="tabletype[]" value="nat">National<br>
<input type="submit" value="Submit and Export">
</form>
</body>
PHP side
header("Content-disposition: attachment; filename=".$fileName);
header("Content-Type: application/force-download");
header("Content-Transfer-Encoding: application/zip;\n");
header("Pragma: no-cache");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0, public");
header("Expires: 0");
// Create the ZIP file
$zip = new ZipArchive;
$result_zip = $zip->open($fileName, ZipArchive::CREATE); // We open the file
if ($result_zip === TRUE) {
$pdo = new PDO("mysql:host=localhost;dbname=BLSdata","root","root");
$tableList = $pdo->prepare('SHOW TABLES FROM BLSdata LIKE "localTable" AND "msaTable" AND "nmsaTable" AND "stateTable" AND "natTable"');
$tableList->execute(array(''));
// For each table
foreach($tableList as $aTableList)
{
$content = export_table($aTableList[0]);
$fileName = $aTableList[0].'.csv';
$zip->addFile($fileName, $fileName);
}
$zip->close();
}
else
{
echo 'Failed, code:' . $result_zip;
}
readfile($fileName);
$deleteLocal = "DROP TABLE localTable";
$pdo->query($deleteLocal);
exit();

Download html textarea content as a file

I am working on a project where the requirement is to download a textarea content as a .txt file on a wordpress site.
After searching previous questions, I got below code which marked as a correct answer.
<html>
<body>
<form action="#" method="post">
<textarea name="text" rows="20" cols="100"></textarea>
<input type="submit" value="submit">Download Text</input>
</form>
<?PHP
if(isset($_POST['submit']))
{
$text = $_POST['text'];
print ($text);
$filename = 'test.txt';
$string = $text;
$fp = fopen($filename, "w");
fwrite($fp, $string);
fclose($fp);
header('Content-disposition: attachment; filename=test.txt');
header('Content-type: application/txt');
readfile('test.txt');
}
?>
</body>
</html>
But for me it is not creating a .txt file. please help me to identify the issue
Modified little bit in your code.
First put your php code
<?php
if(isset($_POST['submit']))
{
$text = $_POST['text'];
print ($text);
$filename = 'test.txt';
$string = $text;
$fp = fopen($filename, "w");
fwrite($fp, $string);
fclose($fp);
header('Content-disposition: attachment; filename=test.txt');
header('Content-type: application/txt');
readfile('test.txt');
die; //modified code
}
?>
after that put your html code
<html>
<body>
<form action="#" method="post">
<textarea name="text" rows="20" cols="100"></textarea>
<input type="submit" value="submit" name="submit">Download Text</input>
</form>
add name attribute in submit button.
Your code actually creates a file on the server and it does not get deleted afterwards. If the code failed, it is possible that you didn't have permission to write on your server. You can trim your code down to the following so as no file is generated in the process:
<?php
if(isset($_POST['text']))
{
header('Content-disposition: attachment; filename=test.txt');
header('Content-type: application/txt');
echo $_POST['text'];
exit; //stop writing
}
?>
<html>
<body>
<form action="" method="post">
<textarea name="text" rows="20" cols="100"></textarea>
<input type="submit" value="submit" name="submit">Download Text</input>
</form>
</body>
</html>
Firstly, you should output the file before printing anything on screen and secondly, you forgot to add name="submit" to your original code. I didn't use it here, but I included for you to get an idea.
In the WordPress Context:
Add this to your functions.php or plugin file:
function feed_text_download(){
if(isset($_POST['text_to_download']))
{
header('Content-disposition: attachment; filename=test.txt');
header('Content-type: application/txt');
echo $_POST['text_to_download'];
exit; //stop writing
}
}
add_action('after_setup_theme', 'feed_text_download');
Add the form to one of your template files or in the HTML editor of your post:
<form action="" method="post">
<textarea name="text_to_download" rows="20" cols="100"></textarea>
<input type="submit" value="submit" name="submit">Download Text</input>
</form>
It should be good :)
EDIT: Add Filename
HTML:
<form action="" method="post">
<label>Filename:<input type="text" name="filename" /></label>
<label>Text:<textarea cols="100" name="text_to_download" rows="20"></textarea></label>
<input type="submit" name="submit" value="Download Text" />
</form>
PHP:
function feed_text_download() {
if ( isset( $_POST['text_to_download'] ) && isset( $_POST['filename'] ) ) {
$filename = sanitize_file_name( $_POST['filename'] );
header( 'Content-disposition: attachment; filename=' . $filename );
header( 'Content-type: application/txt' );
echo $_POST['text_to_download'];
exit; //stop writing
}
}
add_action( 'after_setup_theme', 'feed_text_download' );
Try following code, that will help you:
<?php ob_start();?>
<html>
<body>
<?php
if(isset($_POST['tarea'])){
$filename = 'test.txt';
$data = $_POST['tarea'];
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=$filename");
header("Content-Type: application/octet-stream; ");
header("Content-Transfer-Encoding: binary");
echo $data;
exit;
}
?>
<form action="" method="post">
<textarea name="tarea"></textarea>
<input type="submit">
</form>
</body>
</html>

Download script for PHP

In my website I want the users to download a music file when a button is clicked. The problem I am experiencing is that when the button is clicked the download starts but only 506 KB on a total of 4 MB are downloaded and when it is opened it shows unsupported format. I use this php download script with html form to make the download:
HTML FORM
<FORM ACTION="download.php" METHOD=POST>
<INPUT TYPE="hidden" NAME="music" VALUE= "music/<? print $file; ?>" >
<INPUT TYPE="SUBMIT" NAME="download" VALUE="Download">
</FORM>
PHP DOWNLOAD SCRIPT
<?php
$FileName = $_POST["music"];
$FilePath = "music";
$size = filesize($FilePath . $FileName);
header("Content-Type: application/force-download; name=\"". $FileName ."\"");
header("Content-Transfer-Encoding: binary");
header("Content-Length: ". $size ."");
header("Content-Disposition: attachment; filename=\"". $FileName ."\"");
header("Expires: 0");
header("Cache-Control: private");
header("Pragma: private");
echo (readfile($FilePath . $FileName));
?>
Can you please point me to the problem?
Your code is looking for a file in a location like:
musicmusic/file.mp3
Assuming your file is actually stored in something like music/file.mp3, and variable $file contains something like file.mp3, you want to replace:
<INPUT TYPE="hidden" NAME="music" VALUE= "music/<? print $file; ?>">
with:
<INPUT TYPE="hidden" NAME="music" VALUE= "<? print $file; ?>">
and then replace this:
$FilePath = "music";
with:
$FilePath = "music/";
(or delete $FilePath at all)
Also, I would recommend you to check $_POST["music"] doesn't contain .. or start with / before you let anyone download any file from your server.

Simple login for private user-files

I want to create a simple login with only a few hard-coded username/password combos which gives access to individual private directories with files that I upload. (mysite.com/user1/, mysite.com/anotheruser/...)
Below are the contents of my mylogin.php.
What approaches are there for me to "password protect" files for download only from this page and by their respective users? The information will not be terribly sensitive, but it should be somewhat secure.
<?php //List of users and their passwords
$users = array(
"myusername" => "mYpaSSw0rd2011",
"anothername" => "password2"
);?>
<html>
<head><title>Private Login</title></head>
<body>
<form method="POST" action="mylogin.php">
Username: <input type="text" name="username" size="15" /><br />
Password: <input type="password" name="password" size="15" /><br />
<input type="submit" value="Login" />
</form>
<?php //check username:password combo
if ( isset($_POST["username"]) && $_POST["username"] != "" && ($users[$_POST["username"]] == $_POST["password"])
//*******************************************************
//list (private) files in mysite.com/username's directory
//*******************************************************
}?>
</body></html>
You will find this very useful:
header('Content-disposition:attachment; filename.pdf');
Just read the file (using readfile for example), dump the data and set the header as an attachement.
Store the originals where that cannot be accessed by http (or use an HTACCESS to protect them).
I thought it might be appropriate to post the code I ended up using for future reference. I ended up splitting the project into 3 different files (as well as directories for the users).
Within the user directories I placed .htaccess files with <Files *>Deny from all</Files> so that their files are protected.
Also, I know I did some of this stuff pretty poorly. I started to use sessions, but I was having difficulty getting it to work right. You can see some of the remnants in the code. Any help refactoring would be greatly appreciated.
I cut out some markup to make the following code more readable.
==================================================================
index.php=========================================================
==================================================================
<form method="POST" action="userview.php">
Username: <input type="text" name="username" size="15" /><br />
Password: <input type="password" name="password" size="15" /><br />
<input type="submit" value="Login" />
</form>
==================================================================
userview.php======================================================
==================================================================
<?php
//List of users and their passwords
$users = array(
"myusername" => "mYpaSSw0rd2011",
"anothername" => "password2",
);
//Check posted user:pass & start session (or die on mismatch)
//****Session currently doesn't carry over to download.php. I am re-posting username with a hidden form field****
if ( isset($_POST["username"]) && $_POST["username"] != "" && ($users[$_POST["username"]] == $_POST["password"])) {
session_start();
$_SESSION['user'] = $_POST["username"];
} else die("incorrect login");
?>
<html><head><title><?php echo $_POST["username"] ?>'s Files</title></head><body>
<h1>Contents of <?php echo $_POST["username"] ?>'s Directory:</h1>
<?php
$handle = opendir( $_SESSION['user'] . '/' );
if ($handle) { //display directory contents within a radio button list.
echo '<form method="POST" action="download.php">';
echo '<input type="hidden" name="user" value="' . $_SESSION['user'] . '">';
echo '<fieldset>';
while (false !== ($file = readdir($handle))) {
if (substr($file, 0, 1) !== ".")
echo
"<label><input type=\"radio\" name=\"dlfile\" value=\"$file\" /> $file", "</label><br />\n";
}
closedir($handle);
echo '</fieldset><br /><input type="submit" value="Download" /></form>' , "\n\n";
} else die("error: Please contact administrator");
?>
</body></html>
==================================================================
download.php======================================================
==================================================================
<?php
if ( isset($_POST['user']) && isset($_POST['dlfile'])) {
$file = $_POST['user'] . "/" . $_POST['dlfile'];
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: text/plain');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
}
}
?>

Categories