I am a new PHP programmer. I am trying to write code to allow users to download text file from my website. I followed the answers to similar questions on this subject and put together this following test program. It did not force the download to go to a file, instead, it sent the content to the screen (in Chrome, IE, Firefox). Could someone point out what I did wrong?
Here is my test code:
<?php
$file = "test.txt";
if(!file_exists($file)) die("I'm sorry, the file doesn't seem to exist.");
$type = filetype($file);
// Send file headers
header("Content-type: $type");
header("Content-Disposition: attachment;filename=\"test.txt\"");
header("Content-Transfer-Encoding: binary");
header('Pragma: no-cache');
header('Expires: 0');
// Send the file contents.
set_time_limit(0);
readfile($file);
exit();
?>
You can simply use
$handle = fopen("file.txt", "w");
fwrite($handle, "Shadow ");
fclose($handle);
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename('file.txt'));
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize('file.txt'));
readfile('file.txt');
exit;
Edited , try it on single php page .
This code will display the text file content in the screen, and user can download it as a text plain file:
$file = "test.txt";
if(!file_exists($file)) die("I'm sorry, the file doesn't seem to exist.");
$type = filetype($file);
// Send file headers
header("Content-type: $type");
header('Pragma: no-cache');
header('Expires: 0');
// Send the file contents.
set_time_limit(0);
echo file_get_contents($file);
But this code (by #Drop Shadow) will force browser to show download dialog without displaying anything:
$file = "test.txt";
if(!file_exists($file)) die("I'm sorry, the file doesn't seem to exist.");
$type = filetype($file);
// Send file headers
header("Content-type: $type");
header("Content-Disposition: attachment;filename=\"test.txt\"");
header("Content-Transfer-Encoding: binary");
header('Pragma: no-cache');
header('Expires: 0');
// Send the file contents.
set_time_limit(0);
readfile($file);
exit();
Related
I can't download files that already uploaded in my website, for example :
I already uploaded a video file with 800mb file size and it is okay, the file is save to my directory in the File folder, then I want to download that file again, but as soon as I download the file, I will always got 1kb file not the exact size of the file, and when I play it, nothing happen
this is my code:
<?php
include 'db.php';
if(isset($_REQUEST['name']))
{
$var =$_REQUEST['name'];
$dir = "../files/";
$file = $dir . $var;
if(file_exists($file))
{
header('Content-Description: File Transfer');
header('Content-Type: video');
header('Content-Disposition: attachment;
filename='.basename($file));
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
mysqli_close($conn);
exit();
}
else{
echo "File not found";
}
}
?>
Yeah, I had the same problem too. After searching alot on the internet, I found out that the problem is related to output buffering. The following code solved my problem.
<?php
$file = $_GET['file'];
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));
ob_end_clean(); //adding this line solves my problem
readfile($file);
exit;
?>
The code ob_end_clean() basically runs grabs everything in the buffer, then erases the buffer, and turns off output buffering.
I am having a problem that I just can't solve and I'm going madness with this!
Basically I have to export a csv file. The site is obviously running on a server, and the idea is that onclick the file is generated and automatically downloaded.
Everything is just fine, however, the file is being download to the server directory instead of the local user machine. I just can't make it.
What is wrong? Thank you very much!
if(!isset($crm_contas))
$crm_contas = new crm_contas;
$resultGetValues = $crm_contas->getExportContas($filtros, $idsToSend);
// filename for download
$filename = "ContasExportadas" . date('Ymd') . ".csv";
$output = fopen($filename, 'w');
foreach($resultGetValues as $row) {
fputcsv($output, $row);
}
fclose($output);
$filename = realpath($filename);
$fp = #fopen($filename, 'rb');
if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE"))
{
header('Content-Type: "application/octet-stream"');
header('Content-Disposition: attachment; filename='.$filename);
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header("Content-Transfer-Encoding: binary");
header('Pragma: public');
header("Content-Length: ".filesize($filename));
} else {
header('Content-Type: "application/octet-stream"');
header('Content-Disposition: attachment; filename='.$filename);
header("Content-Transfer-Encoding: binary");
header('Expires: 0');
header('Pragma: no-cache');
header("Content-Length: ".filesize($filename));
}
fpassthru($fp);
fclose($fp);`
--> This is the action that calls the code above.
echo "<a href='#' onclick='changeFormAction(\"form_list\",\"".$CONF['HOME']."/contas/index.php?view=export\");document.form_list.submit();changeFormAction(\"form_list\",pesquisa);'><img src='".$CONF['HOME']."/images/structure/excel.png' alt='Exportar' title='Exportar'></a>";
Meanwhile, I noticed that error_log is writting down this lines when I try do download.
[21-Apr-2016 16:23:44 UTC] PHP Warning: Module 'imap' already loaded in Unknown on line 0
Hi I am trying to allow download a demo file which is related to a product. my code is like this
if(isset($_POST['submit'])){
$root = $_SERVER['DOCUMENT_ROOT'];
$path = "/download/";
$path = $root.$path;
$filename = $demo;
$file = $path.$filename;
header('Content-Type: application/force-download');
header("Content-Transfer-Encoding: Binary");
header("Content-Disposition: attachment; filename=\"".basename($file)."\";" );
header("Content-Length: ".filesize($file));
readfile($file);
}
I am able to get file name which is associated with the product by
$demo
After user submits his information, download will start automatically. Now this is downloading a non existing file or corrupted file with the proper file name. please help
<?php
$file = '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('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;
}
?>
As you can see Content type is application/octet-steam meaning file is byte by byte encoded. Also the cache headers are set. Then headers are forcefully sent by ob_clean();flush(); and then the file is read.
The file_exists is there to ensure that given file exists. You should also try not not thrust user input as they could easy write names for your php codes and download EACH file. And with ../ in names of the files, even your documents or system files and so on.
I have created a beginner program to forcefully download file from unix box to windows through browser, it is not throwing any error but shows nothing on browser just a blank page.
PHP version- 5.2.13
Apache-2.0
Unix Box- HP-UX 11.11 (old version latest is 11.31)
local PC- windows XP Prof.
Browser- IE 7, Mozilla.
Below is my code (this code resides on unix box):
<?php
ob_start();
$file = '/opt/hpws/apache/htdocs/barn/file2';
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream;charset=utf-8');
header('Content-Disposition: attachment; filename=$file');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
}
?>
This line had quotation marks missing:
header('Content-Disposition: attachment; filename=$file');
and in trying to use that line of code, the browser would prompt to save the file as $file.
The line of code should read as:
header('Content-Disposition: attachment; filename="'.basename($file).'"');
The following (tested with a binary file) with file inside the same folder as executed code.
NOTE: You could use header("Content-Type: application/text"); if it's an ASCII file.
<?php
ob_start();
$file = 'file.zip';
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream;charset=utf-8');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
}
?>
Okay, let's add some checks and debugging.
<?php
$file = '/opt/hpws/apache/htdocs/barn/file2';
if (!file_exists($file)) {
die("The file does not exist");
}
if (!is_file($file)) {
die("Not a file"); // Worry about symlinks later
}
if (!is_readable($file)) {
die("The file is not readable");
}
die("DEBUG: Okay, will send the file -- remove this line and retry");
$name = basename($file); // Or anything else
header('Content-Type: application/octet-stream');
header("Content-Disposition: attachment; filename=\"{$name}\"");
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
exit();
?>
If this does not work, it should at least tell you why. Also, on the first run, the one when it will still not download the file but only tell you that it will, check that the page does not contain anything else except that one line. Otherwise, you're setting yourself up for a fall; if not this once, as soon as you have to send a file larger than your output buffers, or too many files for your system memory.
In my code I am creating a file with fgetcsv. I download it and open the file but all the html from my page is included with the csv file. Is there anyway I can just have the data I want to output from the file and not the extra html. my function for creating the csv is below
function makefile()
{
header('Content-type: text/csv');
header("Cache-Control: no-store, no-cache");
header("Content-Disposition: attachment;filename=file.csv");
$this->filepointer = fopen('php://output', 'a');
for($count=0;$count < count($this->alldata);$count++)
{
fputcsv($this->filepointer, $this->alldata[$count]);
}
fclose($this->filepointer);
}
also I was wondering if i use $this->filepointer = fopen('file.csv', 'w') will the file still be populated with the html. as I dont have to have the file downloading I was just using it to check if the file was being created in the correct format. thanks again
You can try the below code. You need to add read_file at the end after setting some header as below.
<?php
if(isset($_GET['link']))
{
$var_1 = $_GET['link'];
$file = $var_1;
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));
ob_clean();
flush();
readfile($file);
exit;
}
} //- the missing closing brace
?>
use ob_end_clean() ; before writing the file