Read/download large file in PHP without running out of memory - php

How can I read/download a large file in PHP without running into allowed memory bytes exhausted?
I am currently trying:
$content = null;
while (!feof($file['data'])) {
$content .= fread($file['data'], 8192);
}
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=\"" . $file['real_filename'] . "\"");
header("Content-Length: " . $file['length']);
echo $content;

Have you tried this ?
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=\"" . $file['real_filename'] . "\"");
header("Content-Length: " . $file['length']);
while (!feof($file['data'])) {
print fread($file['data'], 8192);
}

Related

php download a file from a password protected folder

I have to start a download with php of a file inside a password protected folder.
I have the following code:
<?php
$File="https://testuser:password#www.testdomain.com/test/2/file.zip";
if(file_exists($File))
{
header("Content-Disposition: attachment; filename=\"" . basename($File) . "\"");
header("Content-Type: application/octet-stream");
header("Content-Length: " . filesize($File));
header("Connection: close");
readfile($File);
}
?>
file_exists and filesize seems that don't work with this kind of url.
How can I solve the problem?

download file using php, file is stored in a folder and name of the file is stored in database

I am trying to download a file from mysqli database using php for that i have stored file in a folder and file name is stored in the mysqli database.
here is my code...
$query= mysqli_query($dbo,"SELECT * FROM diff_questions WHERE email = ' $email ' and status= '0' ");
$rows=mysqli_fetch_array($query);
$file=$rows['file'];
$path='http://localhost/admin1/uploads';
?>
echo "<a href='download.php?file=".$file."&path=".$path." '>Download File</a> ";
and now
download.php-
<?php
$file = $_GET["file"];
$path = $_GET["path"];
$fullfile = $path.$file;
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=" . Urlencode($file));
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Description: File Transfer");
header("Content-Length: " . Filesize($fullfile));
flush();
$fp = fopen($fullfile, "r");
while (!feof($fp))
{
echo fread($fp, 65536);
flush();
}
fclose($fp);
?>
Can someone please tell me what is wrong with code. Its not working .
i mean it working file till saving file but its not downloading full file imean afther downloading file size of file is 0kb
Once replace your download.php with following code and check if its working for you or not :
if(isset($_GET["file"])){
$file = $_GET["file"];
$path = $_GET["path"];
$fullfile = $path.$file;
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=" . Urlencode($file));
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Description: File Transfer");
$fp = fopen($fullfile,'r');
while ($line = fgets($fp)) {
echo($line);
}
fclose($fp);
}

View PDF in browser rather than download

There are meetings on this website and each meeting has a PDF attached showing the meeting minutes. The next meeting that takes place dynamically collects this attached PDF and allows for a download as the previous minutes. This is all working perfectly, however, when clicking the link for the previous minutes it always opens up a save as box. I was wondering how to get this to just display in the browser (assuming the user has a PDF viewer enabled)?
Here is the function from the controller:
public function current_pdf($id = null, $pdf = null) {
$this->loadModel('Document');
$document = $this->Document->find('list', array(
'fields' => array('Document.dir', 'Document.url')
));
$request_pdf = $this->Meeting->read(null, $id);
if ($pdf == 'current') {
$file = $document[$request_pdf['Meeting']['minutes']];
if (!empty($file)) {
header("Content-Disposition: attachment; filename=" . urlencode($file));
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Description: File Transfer");
header("Content-Length: " . filesize(WWW_ROOT . 'files/document/url/' . $request_pdf['Meeting']['minutes'] . '/' . $file));
flush(); // this doesn't really matter.
$fp = fopen(WWW_ROOT . 'files/document/url/' . $request_pdf['Meeting']['minutes'] . '/' . $file, "r");
while (!feof($fp)) {
echo fread($fp, 65536);
flush(); // this is essential for large downloads
}
fclose($fp);
//echo WWW_ROOT.'files/document/url/pdf/'.$file; die;
//readfile(WWW_ROOT.'files/document/url/pdf/'.$file);
exit;
}
$this->redirect(array('controller' => 'meetings', 'action' => 'view/' . $id));
} else {
$file = $request_pdf['Meeting']['current_minutes'];
if (!empty($file)) {
//echo filesize(WWW_ROOT.'files/document/url/pdf/'.$file); die;
/* header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header("Content-Type: application/force-download");
header('Content-Disposition: attachment; filename=' . urlencode(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(); */
header("Content-Disposition: attachment; filename=" . urlencode($file));
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Description: File Transfer");
header("Content-Length: " . filesize(WWW_ROOT . 'files/document/url/pdf/' . $file));
flush(); // this doesn't really matter.
$fp = fopen(WWW_ROOT . 'files/document/url/pdf/' . $file, "r");
while (!feof($fp)) {
echo fread($fp, 65536);
flush(); // this is essential for large downloads
}
fclose($fp);
//echo WWW_ROOT.'files/document/url/pdf/'.$file; die;
//readfile(WWW_ROOT.'files/document/url/pdf/'.$file);
exit;
}
$this->redirect(array('controller' => 'meetings', 'action' => 'view/' . $id));
}
}
And here is the link in the view:
<?php echo $this->Html->link(__('Download Previous Minutes'), array('controller' => 'meetings', 'action' => 'current_pdf', $download, 'current')); ?>
I have tried removing the header("Content-Type...") lines of code and changing attachment in header("Content-Disposition: attachment; filename=" . urlencode($file)); to inline. This stopped the save as pop-up but displayed a load of spurious code in the browser instead.
Any help would be greatly appreciated as I'm currently very confused.
I believe this is as simple as removing this line in your code:
header("Content-Disposition: attachment; filename=" . urlencode($file));
This line will server up the file as a download, and not display the content in the browser.
I hope that helps!

How to download PDF file from blob oracle using PHP?

I want to download blob file from oracle, that is PDF file, this is my code to get and download file:
<?php
$conn = ocilogon('user', 'pass', '//localhost/XE');
$sql = "SELECT PDFFILE FROM TFILE";
$stid = ociparse($conn,$sql);
ociexecute($stid);
$rowResult = ocifetch($stid);
settype($arrayResult,"array");
if($rowResult != null){
header("Content-Type: application/octet-stream");
header('Content-Disposition: attachment; filename="' . OCIResult($stid,'PDFFILE') . '"');
header("Content-Length: " . filesize(OCIResult($stid,'PDFFILE')->load()));
header('Content-Disposition: attachment; header("Content-Transfer-Encoding: binary\n");
}
?>
but when i run this code,i not get pdf file..
something wrong with my code??
header("Content-Type: application/octet-stream");
header('Content-Disposition: attachment; filename="' . OCIResult($stid,'PDFFILE') . '"');
header("Content-Length: " . filesize(OCIResult($stid,'PDFFILE')->load()));
header('Content-Disposition: attachment; header("Content-Transfer-Encoding: binary\n");
You're sending the Content-Disposition header twice. You probably don't even need the second one, the client should know all it needs to know about the stream from the Content-Type header. Omit the second Content-Disposition so you're not over-writing the header that has the filename.

How do I provide a download for existing Excel with PHP?

I have a generated xls file on my server that I would like to push to the client for download but can't seem to get it working. Here is what I have so far:
$xlsFile = 'test.xls';
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");;
header("Content-Disposition: attachment;filename=$xlsFile");
header("Content-Transfer-Encoding: binary ");
exit();
My excel file is correct and can be opened if I open it from the server but how can I push this file to the client for download?
You seem to be overdoing it with your "Content-type" headers. Oh, and you need to actually send the file before exit()ing. All you need is
header("Content-Type: application/vnd.ms-excel");
header('Content-Disposition: attachment; filename="' . $xlsFile . '"');
readfile($xlsFile);
exit();
See this older post on the correct MIME type to send with your upload:
Setting mime type for excel document
Sample function.
function file_download($filename, $mimetype='application/octet-stream') {
if (file_exists($filename)) {
// send headers
header($_SERVER["SERVER_PROTOCOL"] . ' 200 OK');
// type
header('Content-Type: ' . $mimetype);
// date of modified
header('Last-Modified: ' . gmdate('r', filemtime($filename)));
header('ETag: ' . sprintf('%x-%x-%x', fileinode($filename), filesize($filename), filemtime($filename)));
// file size
header('Content-Length: ' . (filesize($filename)));
header('Connection: close');
header('Content-Disposition: attachment; filename="' . basename($filename) . '";');
// send file
echo file_get_contents($filename);
} else {
header($_SERVER["SERVER_PROTOCOL"] . ' 404 Not Found');
header('Status: 404 Not Found');
}
exit;
}
You just need to add one more line
$xlsFile = 'test.xls';
header("Content-Type: application/vnd.ms-excelapplication/vnd.ms-excel");
header("Content-Disposition: attachment;filename='$xlsFile'");
header("Content-Transfer-Encoding: binary ");
echo file_get_contents($xlsFile);
exit();

Categories