PHP - Download script only downloads 300B instead of 170MB - php

I'm having an issue when trying to make a download script on my website. What ends up happening is that it only downloads between 160B to 310B instead of the whole 170MB that the file is. I'm not sure why it's happening, and if anyone can help that would be greatly appreciated. Also, I'm not sure if it's an issue with the code itself or that my host doesn't allow big files to be downloaded, as I get this message on net2ftp: "Files which are too big can't be downloaded, uploaded, copied, moved, searched, zipped, unzipped, viewed or edited; they can only be renamed, chmodded or deleted."
Here is my code:
ignore_user_abort(true);
set_time_limit(0);
$path = "/versions/";
$dl_file = $_GET['file'];
$fullPath = $path.$dl_file;
if ($fd = fopen($fullPath, "r")) {
$fsize = filesize($fullPath);
$path_parts = pathinfo($fullPath);
header("Content-type: application/octet-stream");
header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");
header("Content-length: $fsize");
header("Cache-control: private");
while(!feof($fd)) {
$buffer = fread($fd, 2048);
echo $buffer;
}
}
fclose($fd);
exit;

Related

Need to refresh the page to see the download

I'm trying to download a simple text file from my server to the client in php. Unfortunately, when i try to download, a new white page appear and the download isn't ask to the user. But, if i refresh the page, the download is now ask and the user can accept to download the file like usual. Do anyone know why?
P.S. If anyone knows about how not opening another blank page to show the download and just show it on the page i clicked the link, any information would be appreciated.
Here is the code :
HTML
Download file
PHP
<?php
ignore_user_abort(true);
set_time_limit(0); // disable the time limit for this script
$path = "toDownload/"; // change the path to fit your websites document structure
$dl_file = $_GET['download_file']; // simple file name validation
$fullPath = $path.$dl_file;
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");
header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); // use 'attachment' to force a file download
break;
// add more headers for other content types here
default;
header("Content-type: application/octet-stream");
header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");
break;
}
header("Content-length: $fsize");
header("Cache-control: public"); //use this to open files directly
while(!feof($fd))
{
$buffer = fread($fd, 2097152); // 2097152 Octet = 2Mo
echo $buffer;
}
}
fclose ($fd);
exit;
?>

(PHP) Save file in folder to computer

I'm using PHP (PHPExcel) to handle all the excel files.
Currently I have saved a "New Template.xlsx" in a folder. And now I want the users to be able to download the "New Template.xlsx" at a click of a button.
How do i do that with php or phpexcel (i'm using Yii PHP framework as well)?
I'm not sure how to start, all I have now is
$filePath = Yii::app()->basePath . '\\vendors\\Excel Template\\New Template.xlsx';
Yii::import('application.vendors.PHPExcel', true);
$objPHPExcel = PHPExcel_IOFactory::load($filePath);
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
Edit
Thanks to Miqi180's comments, I'm now able to download the excel file, however I am unable to open it because of invalid file extension/file format.
Here are my codes:
<?php
ignore_user_abort(true);
set_time_limit(0); // disable the time limit for this script
//$path = "/absolute_path_to_your_files/"; // change the path to fit your websites document structure
$path = Yii::app()->basePath . '\\vendors\\Excel Template\\';
//$dl_file = preg_replace("([^\w\s\d\-_~,;:\[\]\(\].]|[\.]{2,})", '', $_GET['download_file']); // simple file name validation
$dl_file = preg_replace("([^\w\s\d\-_~,;:\[\]\(\].]|[\.]{2,})", '', 'NewTemplate.xlsx'); // simple file name validation
$dl_file = filter_var($dl_file, FILTER_SANITIZE_URL); // Remove (more) invalid characters
$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-type: application/vnd.ms-excel");
header("Content-type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); // use 'attachment' to force a file download
break;
// add more headers for other content types here
default;
header("Content-type: application/octet-stream");
header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");
break;
}
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;
Stop Yii from sending its own headers and output
Send the appropriate headers for an xlsx file
Save the file to php://output
Look at some of the examples in the PHPExcel Examples folder like 01simple-download-xlsx.php
But unless you're changing the template between loading it and sending it to the user, there's no need to use PHPExcel for this
Basically, what you need to do is execute a php script which fires when another page is loaded, e.g. "download.php" and then send the file through the header commands in that script.
Complete working code example taken from here:
<?php
ignore_user_abort(true);
set_time_limit(0); // disable the time limit for this script
$path = "/absolute_path_to_your_files/"; // change the path to fit your websites document structure
$dl_file = preg_replace("([^\w\s\d\-_~,;:\[\]\(\].]|[\.]{2,})", '', $_GET['download_file']); // simple file name validation
$dl_file = filter_var($dl_file, FILTER_SANITIZE_URL); // Remove (more) invalid characters
$fullPath = $path.$dl_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");
header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); // use 'attachment' to force a file download
break;
// add more headers for other content types here
default;
header("Content-type: application/octet-stream");
header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");
break;
}
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;
However, you need to set the content-type correctly first (see this post).
from
header("Content-type: application/pdf");
to
header("Content-type: application/vnd.ms-excel");
or for For Excel2007 and above .xlsx files
header("Content-type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
Edit:
According to this MSDN blog article, the correct Extension MIME type for Excel .xlsx files actually is:
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

Unable to download as a pdf file

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");

Tracking bandwidth usage per download

I'm trying to count total bandwidth usage per download.
For a example if I'm sending a 100 mb file to a user and the user disconnects/stops downloading half way so actually only 50 mb being used. Is there a way to track this?
I found this example in a tutorial and in a question on sof.
if ($fd = fopen ($fullPath, "r")) {
//the next part outputs the file
$fsize = filesize($fullPath);
$path_parts = pathinfo($fullPath);
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);
and
PHP - determine how many bytes sent over http

Alternative way to hide download link

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);

Categories