Save a file created by fopen() function in php? - php

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
?>

Related

Yii2 - download corrupted file

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'

How to download image file by force download

I am trying to download image file in CI but getting error when I open download image file. Need help :(
$file_name = $_GET['file_name'];
$file_path = "./ups_printimages/".$file_name;
if(file_exists($file_path))
{
$this->load->helper('download');
$data = file_get_contents($file_path); // Read the file's contents
$name = 'ups_label.png';
force_download($name, $data);
}
else
{
echo "file does not exist";
}
GOD. Found out the solution :)
if(!file)
{
File doesn't exist, output error
die('file not found');
}
else
{
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');
ob_clean();
flush();
readfile($file);
exit;
}
Use header to force download. Use the code below
$file_name = $_GET['file_name'];
$file_path = "./ups_printimages/".$file_name;
if(file_exists($file_path))
{
header('Content-Type: image/jpeg');
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"" . basename($file_name) . "\"");
readfile($file_path);
}
else
{
echo "file does not exist";
}
Hope this helps yoiu

PHP download file freezes the computer

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

Downloading file from localhost site in PHP

When i am download a file with extention like mp3,flv etc it will now download it start buffering And when I remove extention from the file it downloads ...
can you please tell whats the problem behind that ...
file to download is => theangelfoundation-12-5-2012-09-17-27-somebody.mp3
Thanks in advance ..
$file_types=array();
$file_types['mp3'] ='audio/mpeg';
$file_types['mpeg'] ='video/mpeg';
$file_types['mpg'] ='video/mpeg';
$file_types['pdf'] ='application/pdf';
$file_types['pps'] ='application/vnd.ms-powerpoint';
$file_types['ppt'] ='application/vnd.ms-powerpoint';
$file_types['ps'] ='application/postscript';
$file = 'you.mp3';
download($file,$file_types);
function download($file_name,$file_types){
$file = $file_name;
$ext = end(explode('.',$file_name));
if($ext && array_key_exists($ext,$file_types)){
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;
}
}
else {
die("this is not a downloadable file");
}
}
?>
download ok.txt

PHP Force Download Causing 0 Byte Files

I'm trying to force download files from my web server using PHP.
I'm not a pro in PHP but I just can't seem to get around the problem of files downloading in 0 bytes in size.
CODE:
$filename = "FILENAME...";
header("Content-type: $type");
header("Content-Disposition: attachment;filename=$filename");
header("Content-Transfer-Encoding: binary");
header('Pragma: no-cache');
header('Expires: 0');
set_time_limit(0);
readfile($file);
Can anybody help?
Thanks.
You're not checking that the file exists. Try using this:
$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;
}else
{
echo "File does not exists";
}
And see what you get.
You should also note that this forces a download as an octet stream, a plain binary file. Some browsers will struggle to understand the exact type of the file. If, for example, you send a GIF with a header of Content-Type: application/octet-stream, then the browser may not treat it like a GIF image. You should add in specific checks to determine what the content type of the file is, and send an appropriate Content-Type header.
I use the following method in phunction and I haven't had any issues with it so far:
function Download($path, $speed = null)
{
if (is_file($path) === true)
{
$file = #fopen($path, 'rb');
$speed = (isset($speed) === true) ? round($speed * 1024) : 524288;
if (is_resource($file) === true)
{
set_time_limit(0);
ignore_user_abort(false);
while (ob_get_level() > 0)
{
ob_end_clean();
}
header('Expires: 0');
header('Pragma: public');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Content-Type: application/octet-stream');
header('Content-Length: ' . sprintf('%u', filesize($path)));
header('Content-Disposition: attachment; filename="' . basename($path) . '"');
header('Content-Transfer-Encoding: binary');
while (feof($file) !== true)
{
echo fread($file, $speed);
while (ob_get_level() > 0)
{
ob_end_flush();
}
flush();
sleep(1);
}
fclose($file);
}
exit();
}
return false;
}
You can try it simply by doing:
Download('/path/to/file.ext');
You need to specify the Content-Length header:
header("Content-Length: " . filesize($filename));
Also, you shouldn't send a Content-Transfer-Encoding header. Both of the HTTP/1.0 and HTTP/1.1 specs state that "HTTP does not use the Content-Transfer-Encoding (CTE) field of RFC 1521".
This problem as same as my website project. This code I've used:
<?php
$file = $_SERVER["DOCUMENT_ROOT"].'/.../.../'.$_GET['file'];
if(!file)
{
// File doesn't exist, output error
die('file not found');
}
else
{
//$file_extension = strtolower(substr(strrchr($file,"."),1));
$file_extension = end(explode(".", $file));
switch( $fileExtension)
{
case "pdf": $ctype="application/pdf"; break;
case "exe": $ctype="application/octet-stream"; break;
case "zip": $ctype="application/zip"; break;
case "doc": $ctype="application/msword"; break;
case "xls": $ctype="application/vnd.ms-excel"; break;
case "ppt": $ctype="application/vnd.ms-powerpoint"; break;
case "gif": $ctype="image/gif"; break;
case "png": $ctype="image/png"; break;
case "jpeg":
case "jpg": $ctype="image/jpg"; break;
default: $ctype="application/force-download";
}
nocache_headers();
// Set headers
header("Pragma: public"); // required
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public"); // required for certain browsers
header("Content-Description: File Transfer");
header("Content-Type: $ctype");
header("Content-Disposition: attachment; filename=".$file.";" );
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($file));
readfile($file);
}
?>
I think the problem is on the server setting like PHP setting or cache setting, but I don't have any idea to do this my opinion.
i am doing this to download a PDF ...
$filename = 'Application.pdf';
header("Content-Type: application/pdf");
header("Content-Disposition: attachment; filename=$filename");
echo $pdf;
i think you are missing the last row, where you actually send the file contents of whatever you have in $file.
Pablo
The file opened ok for me when I changed the directory to the file location.
$reportLocation = REPORTSLOCATION;
$curDir = getcwd();
chdir($reportLocation);
if (file_exists($filename)) {
header('Content-Disposition: attachment; filename="' . $filename . '"');
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Length: ' . filesize($filename));
header('Content-Transfer-Encoding: binary');
header('Cache-Control: must-revalidate');
header('Pragma: public');
ob_clean();
flush();
readfile($filename);
}
chdir($curDir);
The trick is to check with file_exists to confirm the correct path.
The big confusion is that for PHP paths you don't need to start with '/' to say your website start path.
'/folder/file.ext' #bad, needs to know the real full path
in php / is the website main path already, you don't need to mention it. Just:
'folder/file.ext' #relative to the / website
This will work with file_exists, header filename, readfile, etc...
if script work work for small files but for huge files return 0 byte file. you must increate memory_limit via php.ini
also you can add the following line before your code
ini_set('memory_limit','-1');

Categories