I am working on existing products and i am trying to resolve problem with downloading xlsx file.
When i download file through file manager, file is allright. But when i download file through Yii app, the file is corrupted.
Here is my code
public function actionCallLog($hash, $filename)
{
var_dump(
$hash, $filename
);
ignore_user_abort(true);
set_time_limit(0);
$path = "/var/www/html/uploads/call_log/".$hash.'/';
$dl_file= basename($filename).'.xlsx';
if (!file_exists($path.$dl_file)) {
$dl_file= basename($filename).'.csv';
}
$fullPath = $path.$dl_file;
if ($fd = fopen ($fullPath, "r"))
{
$fsize = filesize($fullPath);
$path_parts = pathinfo($fullPath);
$ext = strtolower($path_parts["extension"]);
switch ($ext)
{
case "xlsx":
header('Content-Description: File Transfer');
header("Content-type: application/xlsx");
header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\"");
break;
case "csv":
header('Content-Description: File Transfer');
header("Content-type: application/csv");
header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\"");
break;
// add more headers for other content types here
default;
header('Content-Description: File Transfer');
header("Content-type: application/octet-stream");
header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");
break;
}
header("Content-length: $fsize");
header("Cache-control: private");
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Expires: 0');
header('Pragma: public');
while(!feof($fd))
{
$buffer = fread($fd, 2048);
echo $buffer;
}
}
fclose ($fd);
exit;
}
Does anybody know where can be the problem?
Thanks
Try turning off all the header instructions (and also the "echo $buffer;" as that might be a lot on screen) and see if any warnings or errors is printed on screen when opening the url for the file download.
If the corrupted file has a size, your code might actually give a warning or generate other output which will become part of the file because it is also echo'ed. Obviously that extra plain text output by your code would turn your correct xlsx into a corrupt file. You might be able to get that text by opening your corrupted file in a text-editor as it would show in there in plain text (probably at the start).
try add the response format
\Yii::$app->response->format = \yii\web\Response::FORMAT_RAW;
and for xlsx the content type should be
'application/vnd.ms-excel'
Related
I've got a php file downloader that I've been using to download a word document, now I need to allow it to download pdfs and it won't open the document stating that the pdf is corrupted.
I've looked up the content-type, ect and t appears to be correct for pdfs, however, I'm unsure of what else it could be. Am I missing some more headers that are necessary for downloading pdfs? I'm very new to this so I'm uncertain of all the possible problems.
my code:
if ($fd = fopen ($fullPath, "r")) {
$fsize = filesize($fullPath);
$path_parts = pathinfo($fullPath);
$ext = strtolower($path_parts["extension"]);
switch ($ext) {
case "pdf":
header("Content-Type: application/pdf");
header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\"");
break;
case "docx":
header('Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document');
header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");
break;
default;
header("Content-type: application/octet-stream");
header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");
break;
}
<?php
header("Content-Type: application/pdf");
header("Content-Type: application/x-download");
header('Content-disposition: attachment; filename="test.pdf"');
header('Content-length: ' . filesize('test.pdf'));
readfile('test.pdf');
This works for me every time. You can try it.
Here, I have been trying to convert the HTML file to PDF using PHP and download it when user clicks on 'download' button. I am able to convert HTML to PDF but I am not able to download it, instead some erroneous file($file) gets downloaded when I try to open this PHP page.
I have referred download file using PHP and SO question Using php to force download a pdf but did not help me.
Here is my PHP code:
<?php
function download_pdf()
{
require('html2pdf/html2fpdf.php');
$pdf=new HTML2FPDF();
$pdf->AddPage();
$fp = fopen("demo.html","r");
$strContent = fread($fp, filesize("demo.html"));
fclose($fp);
$pdf->WriteHTML($strContent);
$pdf->Output("sample.pdf");
}
function download()
{
download_pdf();
// Define the path to file,you want to make it downloadable
$file = ‘sample.pdf’;
if(!$file)
{
// File doesn’t exist, output will show error
die(" file not found");
}
else
{
// Set headers
header('Cache-Control: public');
header('Content-Description: File Transfer');
header('Content-Disposition: attachment; filename=$file');
header('Content-Type: application/pdf');
header('Content-Transfer-Encoding: binary');
// Read the file from disk
readfile($file);
}
}
?>
<input type="button" name="download" value="Download as PDF" style=" position:absolute; top:520px; left:600px;" onclick="<?php download(); ?>"/>
Change your PHP code to this and make some changes accordingly, especially setting the path of your file. Reference link: download file.
<?php
// place this code inside a php file and call it f.e. "download.php"
$path = $_SERVER['DOCUMENT_ROOT']."/path2file/"; // change the path to fit your websites document structure
$fullPath = $path.$_GET['download_file'];
if ($fd = fopen ($fullPath, "r")) {
$fsize = filesize($fullPath);
$path_parts = pathinfo($fullPath);
$ext = strtolower($path_parts["extension"]);
switch ($ext) {
case "pdf":
header("Content-type: application/pdf"); // add here more headers for diff. extensions
header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); // use 'attachment' to force a download
break;
default;
header("Content-type: application/octet-stream");
header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");
}
header("Content-length: $fsize");
header("Cache-control: private"); //use this to open files directly
while(!feof($fd)) {
$buffer = fread($fd, 2048);
echo $buffer;
}
}
fclose ($fd);
exit;
// example: place this kind of link into the document where the file download is offered:
// Download here
?>
You need double quotes here:
header("Content-Disposition: attachment; filename=$file");
I want to create a download link, and I found an example online. I forget where I get it.
Here is the code:
<?php
// place this code inside a php file and call it f.e. "download.php"
//$path = $_SERVER['DOCUMENT_ROOT']."/path2file/"; // change the path to fit your websites document structure
$path = "music/";
$fullPath = $path.$_GET['download_file'];
if ($fd = fopen ($fullPath, "r")) {
$fsize = filesize($fullPath);
$path_parts = pathinfo($fullPath);
$ext = strtolower($path_parts["extension"]);
switch ($ext) {
//case "pdf":
//header("Content-type: application/pdf"); // add here more headers for diff. extensions
//header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); // use 'attachment' to force a download
//break;
case "mp3":
header("Content-type: audio/mpeg"); // add here more headers for diff. extensions
header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); // use 'attachment' to force a download
break;
case "wma":
header("Content-type: audio/wma"); // add here more headers for diff. extensions
header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); // use 'attachment' to force a download
break;
case "ogg":
header("Content-type: audio/ogg"); // add here more headers for diff. extensions
header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); // use 'attachment' to force a download
break;
default:
header("Content-type: application/octet-stream");
header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");
}
header("Content-length: $fsize");
header("Cache-control: private"); //use this to open files directly
while(!feof($fd)) {
$buffer = fread($fd, 2048);
echo $buffer;
}
fclose ($fd);
}
exit;
// example: place this kind of link into the document where the file download is offered:
// Download here
?>
The problem is when I click the download link, it works. But after few seconds, my whole computer freezes and I need to force a shutdown.
What is the cause of this problem? Is it my computer fault or the code? I am using WAMP Server 2.
Update :
I tried to use readfile() instead of fread(), however I still get the same problem. Below is my code :
<?php
$directory_load = simplexml_load_file('conf/configuration.xml');
$path = $_SERVER['SERVER_ROOT'].$directory_load -> directories;
echo $path;
if($_GET['download_file'] != NULL) {
$fullPath = $path.$_GET['download_file'];
if (file_exists($fullPath)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($fullPath));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($fullPath));
ob_clean();
flush();
readfile($fullPath);
exit;
}
else {
echo "<span style=\"font-size: 15px;\">The file you requested to download <span style=\"font-size: 30px; font-weight: bold; color: red; padding: 0px 20px;\">".$_GET['download_file']."</span> does not exists.</span>";
}
}
else {
header("location: index.php");
}
?>
UPDATE 2 :
I tested the code with Mozilla version 21.0, it works fine. But as I stated, my computer freeze when I click the download link, it is when I am using Coolnovo (ChromePlus) Version 2.0.8.33. Is it related to the browser?
Try clearing the buffer and flushing headers. See example below:
header("Content-type: text/csv");
header("Cache-Control: no-store, no-cache");
header('Content-Disposition: attachment; filename="' . $download_info->original . '"');
ob_clean(); // discard any data in the output buffer (if possible)
flush(); // flush headers (if possible)
readfile($path . $download_info->renamed);
SureVerify - Email Verification
I'm currently using this code to hide download link but its giving uncompleted download for some users. I don't know why, but too many users report this problem to me.
My current code is:
file = "../".$realFileName;
$fakeFileName= 'Upbaz.ir-'.base64_decode($_GET['ffname']);
$fp = fopen($file, 'rb');
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=$fakeFileName");
header("Content-Length: " . filesize($file));
fpassthru($fp);
Anyone know other way to hide download link?
This script will handle the downloading of the file and it includes a buffer/ different ext types (if you desire). A good way to hide links is to put files in a protected directory and have links stored in a database. The user sees an ID or a session tied to a file and the server finds the file and serves it.
if ($fd = fopen ($fullPath, "r")) {
$fsize = filesize($fullPath);
$path_parts = pathinfo($fullPath);
$ext = strtolower($path_parts["extension"]);
switch ($ext) {
case "txt":
header("Content-type: application/txt"); // add here more headers for diff. extensions
header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); // use 'attachment' to force a download
break;
default:
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\"");
}
header("Content-length: $fsize");
header("Cache-control: private"); //use this to open files directly
while(!feof($fd)) {
$buffer = fread($fd, 2048);
echo $buffer;
}
}
fclose ($fd);
.htaccess to protect directory (you should have a dir for only these files
deny from all
Above script modified to yours:
$file = "../".$realFileName;
$fakeFileName= 'Upbaz.ir-'.base64_decode($_GET['ffname']);
if ($fd = fopen ($file, "r")) {
$fsize = filesize($file);
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"$fakename\"");
header("Content-length: $fsize");
header("Cache-control: private"); //use this to open files directly
while(!feof($fd)) {
$buffer = fread($fd, 2048);
echo $buffer;
}
}
fclose ($fd);
Increase script time run eq
#set_time_limit(120);
I have created a file, using fopen('contacts','w').
now i want to prompt user to save this file where he want in his local machine(using php).
Any suggestion or sample code will be appreciated.
Thanks!!
Assuming your file - "contacts" is a physical file exists now in the server.
<?php
$file = 'contacts.csv';
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');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
}
?>
Ref: http://php.net/manual/en/function.readfile.php
Download code
<?php
// place this code inside a php file and call it f.e. "download.php"
$path = $_SERVER['DOCUMENT_ROOT']."/path2file/"; // change the path to fit your websites document structure
$fullPath = $path.$_GET['download_file'];
if ($fd = fopen ($fullPath, "r")) {
$fsize = filesize($fullPath);
$path_parts = pathinfo($fullPath);
$ext = strtolower($path_parts["extension"]);
switch ($ext) {
case "pdf":
header("Content-type: application/pdf"); // add here more headers for diff. extensions
header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); // use 'attachment' to force a download
break;
default;
header("Content-type: application/octet-stream");
header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");
}
header("Content-length: $fsize");
header("Cache-control: private"); //use this to open files directly
while(!feof($fd)) {
$buffer = fread($fd, 2048);
echo $buffer;
}
}
fclose ($fd);
exit;
// example: place this kind of link into the document where the file download is offered:
// Download here
?>