Downloading a CSV from tmp folder of PHP project - php

I currently am working on a PHP project that uses the Zend Framework. I am making a CSV without any issues in the controller, but then want the user to be able to download the file by clicking a button in the view.
In my .phtml I have:
<a class="btn" href="<?php echo $this->download;?>" download>Export to CSV</a>
$this->download is being set in the controller:
$view["download"] = $this->_createCSV($bqc_jobs, $startDate, $endDate, $processor_id, $defaultTime);
The _createCSV function creates the CSV and stores it in the temporary directory that the site uses. It then returns the filepath.
private function _createCSV($jobs, $start, $end, $user=null, $minutes){
$format = "Ymd_His";
if(!$start && !$user){
$start = date($format, strtoTime("-" . $minutes . " minutes"));
}
if(!$end){
$end = \DateTime::createFromFormat($format, date($format))->format($format);
}
$directory = Config::$tempDir;
$fileName = $directory . "/" . ($user ? $user . "_" : "") . ($start ? $start . "_" : "") . $end . "_report.csv";
$file = fopen($fileName, 'w');
foreach ($jobs as $job){
fputcsv($file, $job);
}
fclose($file);
return $fileName;
}
When the button is clicked, the browser tries to download the file, but errors because it cannot find the file. This makes sense, since the browser should not have access to the temporary folder, but I'm not entirely sure how to get around this.

If you are unable to see the folder due to the UNIX file permissions, then your only options will be to:
Change the file permissions on the tmp folder so that your web server can read/write there using chmod/chown (I assume it is a linux system?)
Use a different folder with sufficient permissions
Don't store the file on disk - store it in a database instead (not optimal).
Once you are sure your file permissions are in order and that the file can be read by apache, it appears that you should be able to use php's readfile function to actually transmit the file back to the browser:
<?php
$file = '/tmp/monkey.gif';
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
}
?>

Related

How to change directory of Content-Disposition in php

I just want to export my live sql data into excel file inside specific directory. I am able to to download the excel file from sql but it is downloading in download folder in sytem but i want to download it on live server "/home/jw07sp1ptrfw/public_html/" this is my directory on live server.But when I am running this code its downloading the file home_jw07sp1ptrfw_public_html_report.xls in system download folder. Please help me if any one can thanks in advance
include('config.php');
$html='<table> <tr><td> Name</td><td>Email</td><td>Phone</td></tr>';
$result = mysqli_query($link,"SELECT * FROM `order`");
while($row = mysqli_fetch_assoc($result))
{
$html.='<tr><td>'.$row["name"].'</td><td>'.$row["email"].' </td><td> '.$row["phone"].'</td></tr>';
}
$html.='</table>';
header('Content-Type: application/xls');
header('Content-Disposition: attachment; filename= /home/jw07sp1ptrfw/public_html/report.xls');
echo $html;
I have also tried this. But not getting the solution.
$file_name = "report.xls";
$rootDir = realpath("/home/jw07sp1ptrfw/public_html");
$fullPath = realpath($rootDir . "/" . $file_name);
// if ($fullPath && is_readable($fullPath) && dirname($fullPath) === $rootDir)
{
header('Content-Type: application/xls');
header('Content-Disposition: attachment; filename=' . basename($fullPath));
readfile($fullPath);
echo $html;
}
You can't do that. The filename is just a hint to the browser, and it will preprocess it for security reasons. See https://greenbytes.de/tech/webdav/rfc6266.html#disposition.parameter.filename.

How to download a text file on link click in codeigniter

I have text file contains Sample of CSV file format, I want my users can download that file on a link click.
This file resides in this folder stucture:
assets->csv->Sample-CSV-Format.txt
This is the code that I have tried to far:
<?php
$file_name = "Sample-CSV-Format.txt";
// extracting the extension:
$ext = substr($file_name, strpos($file_name,'.') + 1);
header('Content-disposition: attachment; filename=' . $file_name);
if (strtolower($ext) == "txt") {
// works for txt only
header('Content-type: text/plain');
} else {
// works for all
header('Content-type: application/' . $ext);extensions except txt
}
readfile($decrypted_file_path);
?>
<p class="text-center">Download the Sample file HERE It has a sample of one entry</p>
This code is downloading the file on page load instead of link click. Also, it is downloading the whole html structure of the page I want only the text what I have written in text file.
Please guide where is the issue?
You can do this simply in by HTML5 download atrribute . Just add this line in your downloading link .
HERE
You can do it like this, it won't redirect you and also works good for larger files.
In your controller "Controller.php"
function downloadFile(){
$yourFile = "Sample-CSV-Format.txt";
$file = #fopen($yourFile, "rb");
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=TheNameYouWant.txt');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($yourFile));
while (!feof($file)) {
print(#fread($file, 1024 * 8));
ob_flush();
flush();
}
}
In your view "view.php"
Download
make it like this
someother_file.php
<?php
$file_name = "Sample-CSV-Format.txt";
// extracting the extension:
$ext = substr($file_name, strpos($file_name,'.')+1);
header('Content-disposition: attachment; filename='.$file_name);
if(strtolower($ext) == "txt")
{
header('Content-type: text/plain'); // works for txt only
}
else
{
header('Content-type: application/'.$ext); // works for all extensions except txt
}
readfile($decrypted_file_path);
?>
some_html_page.html
<p class="text-center">Download the Sample file HERE It has a sample of one entry</p>
To my view its better to have the download code to the client side, than to have a controller-method written for this.
you can use this ref
public function getTxt()
{
$this->load->helper('download');
$dataFile = "NOTE87";
$dataContent = array();
$dt = "Date :23/07/2021";
$dataContent= array(
"\n",
"\t\t\tUTI AMC Limited\n",
"\t\tDepartment of Fund Accounts\n",
"\n",
"\tReissue of Non Sale Remittance - Axis Bank Cases\n",
"\n",
"\t\t\t\tDate :".$dt."\n",
"\n",
);
force_download($dataFile,implode($dataContent));
}

PHP Create ZIP file in background

I am using the following script to create zip files: http://davidwalsh.name/create-zip-php
It's working just fine and does exactly what I need. Sometimes though I have large files and zipping those takes up to 30 seconds.
I want to let the user know that their download is being packed and tell them whenever the download is ready.
How would I do that? I have a script which is called download.php which basically just calls this create_zip method from above and then forces a download like this:
$files = explode(":", $file_decrypted);
array_pop($files);
$zipname = 'uploads/download_' . $username . '.zip';
foreach ($files as &$value) {
$value = "uploads/" . $username_d . "/" . $value;
}
$resultat = create_zip($files, $zipname, 'uploads/' . $username . '/');
ob_clean();
ob_end_flush();
// Start the download for the user
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename=' . $zipname);
header('Content-Length: ' . filesize($zipname));
readfile($zipname);
exit();
So basically I want to show a text to the user (For example: Preparing download...) and at the same time call all the above php stuff in the background somehow.

php download file: header()

I need some eduction please.
At the end of each month, I want to download some data from my webserver to my local PC.
So, I've written a little script for that, which selects the data from the DB.
Next, I want to download it.
I've tried this:
$file=$month . '.txt';
$handle=fopen($file, "w");
header("Content-Type: application/text");
header("Content-Disposition: attachment, filename=" . $month . '.txt');
while ($row=mysql_fetch_array($res))
{
$writestring = $row['data_I_want'] . "\r\n";
fwrite($handle, $writestring);
}
fclose($handle);
If I run this, then the file is created, but my file doesn't contain the data that I want. Instead I get a dump from the HTML-file in my browser..
What am I doing wrong..
Thanks,
Xpoes
Below script will help you download the file created
//Below is where you create particular month's text file
$file=$month . '.txt';
$handle=fopen($file, "w");
while ($row=mysql_fetch_array($res)){
$writestring = $row['data_I_want'] . "\r\n";
fwrite($handle, $writestring);
}
fclose($handle);
//Now the file is ready with data from database
//Add below to download the text file created
$filename = $file; //name of the file
$filepath = $file; //location of the file. I have put $file since your file is create on the same folder where this script is
header("Cache-control: private");
header("Content-type: application/force-download");
header("Content-transfer-encoding: binary\n");
header("Content-disposition: attachment; filename=\"$filename\"");
header("Content-Length: ".filesize($filepath));
readfile($filepath);
exit;
Your current code does not output a file, it just sends headers.
in order for your script to work add the following code after your fclose statement.
$data = file_get_contents($file);
echo $data;

How do I put a download button on a site to get a CSV of a table Query?

How do I put a download button on a site to get a CSV of a table Query?
Currently I am using SELECT * INTO OUTFILE to make the CSV file on the server HD and is fine except...
I want to create the CSV like I am now, but I want the "OUTFILE" to be saved on the clients computer when they click Download.
<?php
// Create new file name for file to be created
$csvfilename = "/dropbox/consolodated-" . date("Y-M-d_H-i-s") . ".csv";
mysql_query ("SELECT * INTO OUTFILE '$csvfilename' FIELDS TERMINATED BY ',' FROM people ");
?>
<H2>Done - File created - Now download it from FTP site.</H2>
The solution to this can be that:
First you save the csv file on to server.
then get it's path
and finally create an anchor tag with its path for download eg:
_
Download
Here are a couple of similar posts:
Generating CSV file and then forcing the file to download.
PHP code to convert a MySQL query to CSV
Add a POST form at the end which includes a hidden field containing the filename (but NOT the path!) of the file to download. Then have the page it POSTs to read the variable and offer the file for download. Don't forget to enable output buffering and to occasionally flush so that the form is not visible until the query has completed.
Simple, here is a sample snippet:
$csv_filename = "/dropbox/consolodated-" . date("Y-M-d_H-i-s") . ".csv";
Download($csv_filename);
And here is the download function:
function Download($path, $speed = null)
{
if (is_file($path) === true)
{
set_time_limit(0);
while (ob_get_level() > 0)
{
ob_end_clean();
}
$size = sprintf('%u', filesize($path));
$speed = (is_null($speed) === true) ? $size : intval($speed) * 1024;
header('Expires: 0');
header('Pragma: public');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Content-Type: application/octet-stream');
header('Content-Length: ' . $size);
header('Content-Disposition: attachment; filename="' . basename($path) . '"');
header('Content-Transfer-Encoding: binary');
for ($i = 0; $i <= $size; $i = $i + $speed)
{
echo file_get_contents($path, false, null, $i, $speed);
flush();
sleep(1);
}
exit();
}
return false;
}
Merry Xmas to you too! =)

Categories