I am using the following function to download pdf file it is working fine when i download it from PC or laptop but when i click on download link using ipad it opens a page with lots of special chracters and I am unable to download the file.
My download function is
public function download() {
$download_path = $_SERVER['DOCUMENT_ROOT'] . "/import";
$filename = $_GET['file'];
$file = str_replace("..", "", $filename);
$file = "$download_path/$file";
if (!file_exists($file))
die("Sorry, the file doesn't seem to exist.");
$type = filetype($file);
header("Content-type: $type");
header("Content-Disposition: attachment;filename=$filename");
header('Pragma: no-cache');
header('Expires: 0');
readfile($file);
}
Any idea about this error ?
This is probably the issue:
$type = filetype($file);
header("Content-type: $type");
From the manual
Possible values are fifo, char, dir, block, link, file, socket and
unknown.
Which are not things you want to see in the header. You are probably looking for:
header('Content-type: application/pdf');
You probably want finfo_file() and not filetype().
Related
I'm trying to download a .rar file from a cloud (for sake of simplicity I'm using my google drive storage), the file is downloading perfectly, but once i want to open the .rar file , it says that "the archive is either unknown format or damaged" , tried all methods even cURL ,but it didnt want to work,
Im just wondering what I'm missing in my code, thank you
<?php
$filename = 'stu.rar';
if ( file_put_contents( $filename,file_get_contents("mygoogleDriveLink/search?q=stu.rar"))) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.$filename.'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
//header('Content-Length: '.filesize($filename));
readfile($filename);
//print_r("this is ".$id);
exit();
}
else{
echo "err";
}
You may use file_put_contents to save the file to the server first, before you stream it to your browser.
if you do not need to stream to user's web browser, then you may remove the codes from start streaming to end streaming.
Please try the following:
<?php
// Initialize a file URL to the variable
$url = 'http://www.xxxxxxxxxxx.com/xxxxx.rar';
// Use basename() function to return the base name of file
$file_name = basename($url);
// Use file_get_contents() function to get the file
// from url and use file_put_contents() function to
// save the file by using base name
if(file_put_contents( $file_name,file_get_contents($url))) {
// File successfully saved in the server
// start streaming . The following is to stream and save to browser
$file_name = $file_name;
$file_url = $file_name;
header('Content-Type: application/octet-stream');
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"".$file_name."\"");
readfile($file_url);
exit;
/// end streaming
}
else {
echo "File downloading failed.";
}
?>
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));
}
Here's my code:
<?php
$download = './downloads/'.$mp3;
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=".basename($download));
header("Content-Type: audio/mpeg");
readfile($download);
?>
On android, once download starts, it downloads an unreadable htm file. $mp3 is like this: NAME.mp3. What may be wrong?
Hmmm, have you looked at your PHP error logs? This sounds to me like your server / dev environment doesn't have PHP running correctly.
I found this post relating, seems they were able to get it to work with some extra headers, that is if your PHP is working properly:
https://stackoverflow.com/a/2367506/2080324
Yes, but remember headers tell devices what type of file it is. Different devices will interpret different files in different ways. In the example I linked, he sets the mime-type as well as headers:
$dir = dirname($_SERVER['DOCUMENT_ROOT'])."/protected_content";
$filename = $_GET['file'];
$file = $dir."/".$filename;
$extension = "mp3";
$mime_type = "audio/mpeg, audio/x-mpeg, audio/x-mpeg-3, audio/mpeg3";
if(file_exists($file)){
header('Content-type: {$mime_type}');
header('Content-length: ' . filesize($file));
header('Content-Disposition: filename="' . $filename);
header('X-Pad: avoid browser bug');
header('Cache-Control: no-cache');
readfile($file);
}else{
header("HTTP/1.0 404 Not Found");
}
I've made a page where you can go and write text in a "textarea" and then when you click download you download that file as a .txt file. I've done the same thing to some other extensions and that is working fine. But it won't work with .PDF, nothing I read works. Here is the snippet I use for the .PDF downloading:
<?php
if($fileFormat == ".pdf"){
$content = $_POST['text'];
$name = stripslashes($_POST['name']);
$nameAndExt = $name.".pdf";
print strip_tags($content);
header('Content-type: application/pdf');
header('Content-Disposition: attachment; filename="'.$nameAndExt.'"');
header('Content-Transfer-Encoding: binary ');
}
?>
I'm grateful for any answear, thanks!
// hold the filename for use elsewhere so you don't have to append .pdf every time
$filename = "$id.pdf";
// create the file
$pdf->output( $filename );
// set up the headers
header("Content-Description: File Transfer");
header("Content-disposition: attachment; filename={$filename}");
header("Content-Type: application/pdf");
header("Content-Transfer-Encoding: binary");
header('Content-Length: ' . filesize($file));
// push the buffer to the client and exit
ob_clean();
flush();
// read the file and push to the output stream
readfile( $filename );
// remove the file from the filesystem
unlink( $filename );
exit();
I would recommend a class like TCPDF, see http://www.tcpdf.org/. I used it couple of times and it's quite nice (open source).
I have set up a page using php and mysql that requires user to log in to download various paid for programs. They can click on a link as here and the program downloads and runs correctly.
$c3 = mysql_result($result,$i,"exe");
echo "<a href='$c3'>... etc
However, RT-click properties lets them see the path to that file, so I changed the above to:
$c3="downloads3.php?link=".mysql_result($result,$i,"exe");
Where downloads3.php is as follows:
<?php
$file = $_GET['link'];
$size = filesize($file);
$type = filetype($file);
$path = "../downloads/";
header('Content-Type: $type');
header("Content-Transfer-Encoding: Binary");
header("Content-Disposition: attachment; filename=$path.$file");
header("Content-Length: ".filesize($file));
readfile($file_url);?>
?>
It finds the correct file and I get a security warning but on clicking run anyway it immediately gives a windows error message that the file is not compatible with this version of windows. Must be something in the above header but can't figure out what. Tried various permutations.
Any brill ideas, either of getting the above to work or other ways of hiding the source path? Thanks.
It's far more likely that the EXE is getting corrupted due to unexpected output. Your downloads3.php file has some extra output that will appear in the download:
readfile($file_url);?> //PHP stops parsing here
?> //output "\n?>"
The PE header itself tells Windows what versions it can run on, so if any errors get generated before the file gets sent, they'll appear in the place Windows is expecting the header.
To mitigate this you can remove the extra newline and ?> at the end of the file and turn error reporting off with error_reporting(0) at the top of the file.
The Best solution for here to get download file with any name what do you have want
function force_download($filename = '', $data = '')
{
if ($filename == '' OR $data == '')
{
return FALSE;
}
// Try to determine if the filename includes a file extension.
// We need it in order to set the MIME type
if (FALSE === strpos($filename, '.'))
{
return FALSE;
}
// Grab the file extension
$x = explode('.', $filename);
$extension = end($x);
// Load the mime types
if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/mimes'.EXT))
{
include(APPPATH.'config/'.ENVIRONMENT.'/mimes'.EXT);
}
elseif (is_file(APPPATH.'config/mimes'.EXT))
{
include(APPPATH.'config/mimes'.EXT);
}
// Set a default mime if we can't find it
if ( ! isset($mimes[$extension]))
{
$mime = 'application/octet-stream';
}
else
{
$mime = (is_array($mimes[$extension])) ? $mimes[$extension][0] : $mimes[$extension];
}
// Generate the server headers
if (strpos($_SERVER['HTTP_USER_AGENT'], "MSIE") !== FALSE)
{
header('Content-Type: "'.$mime.'"');
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: ".strlen($data));
}
else
{
header('Content-Type: "'.$mime.'"');
header('Content-Disposition: attachment; filename="'.$filename.'"');
header("Content-Transfer-Encoding: binary");
header('Expires: 0');
header('Pragma: no-cache');
header("Content-Length: ".strlen($data));
}
exit($data);
}
$data = 'Here is some text!';
$name = 'mytext.txt';
force_download($name, $data);
DOH!!!!!!!!!!!!!!!! Too much cutting and pasting, that code has a really stupid error readfile($file_url) should be readfile($file), no wonder my 36Mb file was only 1KB after download, it was empty!
Thanks for all the comments, apologies for wasting your time.