Helo I'm trying to create download script in PHP... Upload form is ok and it stores file in folder 'upload/' but and file name is stored in DB, but when I download, it downloads file e.g. some image, when I want to see image it's only red X like here: image....any ideas?
<?php
include 'connect.php';
$query = "SELECT * FROM topics WHERE topic_id = '". $_GET['topic_id'] ."' ";
$result = mysql_query($query);
$row = mysql_fetch_array($result);
$name = $row['topic_subject'];
$file = $row['topic_file'];
header('Pragma: public');
header('Content-Description: File Transfer');
header("Content-Disposition: attachment; filename='".$file . "'");
header("Content-Type: ".mime_content_type($file)."");
header("Content-Length: " . filesize($file) ." ");
header('Content-Transfer-Encoding: binary');
readfile('uploads/',$file);
ob_clean();
flush();
?>
Looks like the issue could be in your call to readfile. You need to use a . to concatenate the file path to the file name, so replace;
readfile('uploads/',$file);
with
readfile('uploads/'.$file);
I’m using my own script for file download. Its best i find ever. You can also modify it as user requirement.
function download_file($Source_File, $Download_Name, $file_extension = '') {
/*
$Source_File = path to a file to output
$Download_Name = filename that the browser will see
$file_extension = MIME type of the file (Optional)
*/
if (!is_readable($Source_File))
die('File not found or inaccessible!');
$size = filesize($Source_File);
$Download_Name = rawurldecode($Download_Name);
/* Figure out the MIME type (if not specified) */
$known_mime_types = array(
"pdf" => "application/pdf",
"csv" => "application/csv",
"txt" => "text/plain",
"html" => "text/html",
"htm" => "text/html",
"exe" => "application/octet-stream",
"zip" => "application/zip",
"doc" => "application/msword",
"xls" => "application/vnd.ms-excel",
"ppt" => "application/vnd.ms-powerpoint",
"gif" => "image/gif",
"png" => "image/png",
"jpeg" => "image/jpg",
"jpg" => "image/jpg",
"php" => "text/plain"
);
if ($file_extension == '') {
// $file_extension = strtolower(substr(strrchr($Source_File,"."),1));
if (array_key_exists($file_extension, $known_mime_types)) {
$mime_type = $known_mime_types[$file_extension];
} else {
$mime_type = "application/force-download";
};
};
#ob_end_clean(); //off output buffering to decrease Server usage
// if IE, otherwise Content-Disposition ignored
if (ini_get('zlib.output_compression'))
ini_set('zlib.output_compression', 'Off');
header('Content-Type: ' . $mime_type);
header('Content-Disposition: attachment; filename="' . $Download_Name . '"');
header("Content-Transfer-Encoding: binary");
header('Accept-Ranges: bytes');
header("Cache-control: private");
header('Pragma: private');
header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', time() + 3600));
// multipart-download and download resuming support
if (isset($_SERVER['HTTP_RANGE'])) {
list($a, $range) = explode("=", $_SERVER['HTTP_RANGE'], 2);
list($range) = explode(",", $range, 2);
list($range, $range_end) = explode("-", $range);
$range = intval($range);
if (!$range_end) {
$range_end = $size - 1;
} else {
$range_end = intval($range_end);
}
$new_length = $range_end - $range + 1;
header("HTTP/1.1 206 Partial Content");
header("Content-Length: $new_length");
header("Content-Range: bytes $range-$range_end/$size");
} else {
$new_length = $size;
header("Content-Length: " . $size);
}
/* output the file itself */
$chunksize = 1 * (1024 * 1024); //you may want to change this
$bytes_send = 0;
if ($Source_File = fopen($Source_File, 'r')) {
if (isset($_SERVER['HTTP_RANGE']))
fseek($Source_File, $range);
while (!feof($Source_File) &&
(!connection_aborted()) &&
($bytes_send < $new_length)
) {
$buffer = fread($Source_File, $chunksize);
print($buffer); //echo($buffer); // is also possible
flush();
$bytes_send += strlen($buffer);
}
fclose($Source_File);
} else
die('Error - can not open file.');
die(1); // A response code other than 0 is a failure
}
I hope this will help you.
Cheers!
Mudassar Ali
You have to give the full path of an image to the readfile() function.
Related
I have got this code from one of the site for file downloads.
Did implemented this code but it only gets download but when I tried to view the file it shows me error in the file.
I did downloaded various file formats like pdf, docx ,doc but it always showed the error.
I have stored my uploads or say file in database. Its not in a directory.
Please suggest me some ideas over this.
The ERROR IS -
Warning: fopen(files/JAVAPROGRAMS.doc) [function.fopen]: failed to open stream: No
such file or directory in
C:\wamp\www\pages\candidate\download.php on line 75 Error - can not open file.
mysql_connect('localhost','root','') or die(mysql_error());
//echo "connected";
mysql_select_db('talent') or die(mysql_error());
function output_file($file, $name, $mime_type='')
{
$size = filesize($file);
$name = rawurldecode($name);
$known_mime_types=array(
"htm" => "text/html",
"exe" => "application/octet-stream",
"zip" => "application/zip",
"doc" => "application/msword",
"jpg" => "image/jpg",
"php" => "text/plain",
"xls" => "application/vnd.ms-excel",
"ppt" => "application/vnd.ms-powerpoint",
"gif" => "image/gif",
"pdf" => "application/pdf",
"txt" => "text/plain",
"html"=> "text/html",
"png" => "image/png",
"jpeg"=> "image/jpg"
);
if($mime_type==''){
$file_extension = strtolower(substr(strrchr($file,"."),1));
if(array_key_exists($file_extension, $known_mime_types)){
$mime_type=$known_mime_types[$file_extension];
}
else
{
$mime_type="application/force-download";
};
};
//turn off output buffering to decrease cpu usage
#ob_end_clean();
// required for IE, otherwise Content-Disposition may be ignored
if(ini_get('zlib.output_compression'))
ini_set('zlib.output_compression', 'Off');
header('Content-Type: ' . $mime_type);
header('Content-Disposition: attachment; filename="'.$name.'"');
header("Content-Transfer-Encoding: binary");
header('Accept-Ranges: bytes');
// multipart-download and download resuming support
if(isset($_SERVER['HTTP_RANGE']))
{
list($a, $range) = explode("=",$_SERVER['HTTP_RANGE'],2);
list($range) = explode(",",$range,2);
list($range, $range_end) = explode("-", $range);
$range=intval($range);
if(!$range_end)
{
$range_end=$size-1;
}
else
{
$range_end=intval($range_end);
}
$new_length = $range_end-$range+1;
header("HTTP/1.1 206 Partial Content");
header("Content-Length: $new_length");
header("Content-Range: bytes $range-$range_end/$size");
}
else
{
$new_length=$size;
header("Content-Length: ".$size);
}
/* Will output the file itself */
$chunksize = 1*(1024*1024); //you may want to change this
$bytes_send = 0;
if ($file = fopen($file, 'r'))
{
if(isset($_SERVER['HTTP_RANGE']))
fseek($file, $range);
while(!feof($file) && (!connection_aborted()) && ($bytes_send<$new_length))
{
$buffer = fread($file, $chunksize);
echo($buffer);
flush();
$bytes_send += strlen($buffer);
}
fclose($file);
} else
//If no permissiion
die(mysql_error());
//die
die();
}
//Set the time out
set_time_limit(0);
//path to the file
$file_path='files/'.$_REQUEST['filename'];
//Call the download function with file path,file name and file type
output_file($file_path, ''.$_REQUEST['filename'].'', 'text/plain');
Try this one. Just mention the proper file path. Hope it works for you.
ignore_user_abort(true);
set_time_limit(0); // disable the time limit for this script
$path = "/YOUR_FILE_PATH/"; // 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;
Try this
output_file($file_path, ''.$_REQUEST['filename'].'', '');
I have a php script to be downloading a file from a remote server (the website is hosted on bluehost), but when I click on the download link (button), the following stuff which I don't really get opens in my browser:
����ELRYgnu|����������������&/8AKT]gqz������������!-8COZfr~���������� -;HUcq~��������� +:IXgw��������'7HYj{�������+=Oat�������2FZn������� % : O d y � � � � � � ' = T j � � � � � �"9Qi������*C\u����� & # Z t � � � � �.Id���� %A^z���� &Ca~����1Om����&Ed����#Cc����'Ij����4Vx���&Il����Ae����#e���� Ek���*Qw���;c���*R{���Gp���#j���>i��� A l � � �!!H!u!�!�!�"'"U"�"�"�# #8#f#�#�#�$$M$|$�$�% %8%h%�%�%�&'&W&�&�&�''I'z'�'�( (?(q(�(�))8)k)�)�**5*h*�*�++6+i+�+�,,9,n,�,�--A-v-�-�..L.�.�.�/$/Z/�/�/�050l0�0�11J1�1�1�2*2c2�2�3 3F33�3�4+4e4�4�55M5�5�5�676r6�6�7$77�7�88P8�8�99B99�9�:6:t:�:�;-;k;�;�<' >`>�>�?!?a?�?
Below is the code I'm using
function output_file($file_id=0)
{
/*
This function takes a path to a file to output ($file), the filename that the browser will see ($name) and the MIME type of the file ($mime_type, optional).
*/
//get filepath, filename and mime type from db
$mysql_file = "SELECT filename, file_format
FROM order_files
WHERE order_files.fileID ={$file_id}";
$myresult_file = mysql_query($mysql_file);
if($myresult_file){
while($myrow_file = mysql_fetch_array($myresult_file)){
$filename = $myrow_file['filename'];
$mimeType =$myrow_file['file_format'] ;
}
}
$file = '/home6/xxxxx/public_html/wp-content/themes/twentythirteen/inc/orderfiles/'.$filename;
$name = $filename;
$mime_type=$mimeType;
//Check the file premission
if(!is_readable($file)) die('File not found or inaccessible!');
$size = filesize($file);
$name = rawurldecode($name);
/* Figure out the MIME type | Check in array */
$known_mime_types=array(
"pdf" => "application/pdf",
"txt" => "text/plain",
"html" => "text/html",
"htm" => "text/html",
"exe" => "application/octet-stream",
"zip" => "application/zip",
"doc" => "application/msword",
"xls" => "application/vnd.ms-excel",
"ppt" => "application/vnd.ms-powerpoint",
"gif" => "image/gif",
"png" => "image/png",
"jpeg"=> "image/jpg",
"jpg" => "image/jpg",
"php" => "text/plain"
);
if($mime_type==''){
$file_extension = strtolower(substr(strrchr($file,"."),1));
if(array_key_exists($file_extension, $known_mime_types)){
$mime_type=$known_mime_types[$file_extension];
} else {
$mime_type="application/force-download";
};
};
//turn off output buffering to decrease cpu usage
#ob_end_clean();
// required for IE, otherwise Content-Disposition may be ignored
if(ini_get('zlib.output_compression'))
ini_set('zlib.output_compression', 'Off');
header('Content-Type: ' . $mime_type);
header('Content-Disposition: attachment; filename="'.$name.'"');
header("Content-Transfer-Encoding: binary");
header('Accept-Ranges: bytes');
/* The three lines below basically make the
download non-cacheable */
header("Cache-control: private");
header('Pragma: private');
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
// multipart-download and download resuming support
if(isset($_SERVER['HTTP_RANGE']))
{
list($a, $range) = explode("=",$_SERVER['HTTP_RANGE'],2);
list($range) = explode(",",$range,2);
list($range, $range_end) = explode("-", $range);
$range=intval($range);
if(!$range_end) {
$range_end=$size-1;
} else {
$range_end=intval($range_end);
}
/*
------------------------------------------------------------------------------------------------------
//This application is developed by www.webinfopedia.com
//visit www.webinfopedia.com for PHP,Mysql,html5 and Designing tutorials for FREE!!!
------------------------------------------------------------------------------------------------------
*/
$new_length = $range_end-$range+1;
header("HTTP/1.1 206 Partial Content");
header("Content-Length: $new_length");
header("Content-Range: bytes $range-$range_end/$size");
} else {
$new_length=$size;
header("Content-Length: ".$size);
}
/* Will output the file itself */
$chunksize = 1*(1024*1024); //you may want to change this
$bytes_send = 0;
if ($file = fopen($file, 'r'))
{
if(isset($_SERVER['HTTP_RANGE']))
fseek($file, $range);
while(!feof($file) &&
(!connection_aborted()) &&
($bytes_send<$new_length)
)
{
$buffer = fread($file, $chunksize);
print($buffer); //echo($buffer); // can also possible
flush();
$bytes_send += strlen($buffer);
}
fclose($file);
} else
//If no permissiion
die('Error - can not open file.');
//die
die();
}
//Set the time out
set_time_limit(0);
What does this mean and how do I debug it?
I'm new to php, your assistance is highly appreciated.
make sure you force file to download instead of display in browser
http://hiryu.byethost7.com/2013/06/force-file-download-in-php/
try this
add these headers
header("Content-Type: " . $file_head['Content-Type']);
header("Content-Transfer-Encoding: Binary");
header("Accept-Ranges: bytes");
header("Content-Disposition: attachment; filename=" . basename($url) . ";");
header("Content-Description: File Transfer");
header("Expires: 0");
header("Pragma: public");
header("Content-Length: " . $file_head['Content-Length']);
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Connection: close");
I have generated csv file on link click. But I am unable to download file from browser.
Here is my code.
$filename="Payment_Received.csv";
header( 'Content-Description: File Transfer' );
header( 'Content-Disposition: attachment; filename=' . $filename );
header('Content-Type: text/csv; charset=UTF-8');
print_r($output);
// output is string comma separated if i remove die and then execute
// then csv append html data also, so I keep die
ob_flush();
die();
CSV is downloading but for it is with no content.
Please help me out.
If your script outputs this: "1","asd","asds" \n "2","sqda","asds", I believe you will have a hard time generating .csv from that my friend. For CSV output, make sure your data is quoted and escaped properly, I'm sorry to send you to php.net but this comment is the only example I could land that mentions clearly at this issue. There are some code examples on that page for csv output.
Good-luck
Function to force download a file from browser.
function output_file($file, $name, $mime_type='')
{
/*
This function takes a path to a file to output ($file),
the filename that the browser will see ($name) and
the MIME type of the file ($mime_type, optional).
If you want to do something on download abort/finish,
register_shutdown_function('function_name');
*/
if(!is_readable($file)) die('File not found or inaccessible!');
$size = filesize($file);
$name = rawurldecode($name);
/* Figure out the MIME type (if not specified) */
$known_mime_types=array(
"pdf" => "application/pdf",
"txt" => "text/plain",
"html" => "text/html",
"htm" => "text/html",
"exe" => "application/octet-stream",
"zip" => "application/zip",
"doc" => "application/msword",
"xls" => "application/vnd.ms-excel",
"ppt" => "application/vnd.ms-powerpoint",
"gif" => "image/gif",
"png" => "image/png",
"jpeg"=> "image/jpg",
"jpg" => "image/jpg",
"php" => "text/plain"
);
if($mime_type==''){
$file_extension = strtolower(substr(strrchr($file,"."),1));
if(array_key_exists($file_extension, $known_mime_types)){
$mime_type=$known_mime_types[$file_extension];
} else {
$mime_type="application/force-download";
};
};
#ob_end_clean(); //turn off output buffering to decrease cpu usage
// required for IE, otherwise Content-Disposition may be ignored
if(ini_get('zlib.output_compression'))
ini_set('zlib.output_compression', 'Off');
header('Content-Type: ' . $mime_type);
header('Content-Disposition: attachment; filename="'.$name.'"');
header("Content-Transfer-Encoding: binary");
header('Accept-Ranges: bytes');
/* The three lines below basically make the
download non-cacheable */
header("Cache-control: private");
header('Pragma: private');
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
// multipart-download and download resuming support
if(isset($_SERVER['HTTP_RANGE']))
{
list($a, $range) = explode("=",$_SERVER['HTTP_RANGE'],2);
list($range) = explode(",",$range,2);
list($range, $range_end) = explode("-", $range);
$range=intval($range);
if(!$range_end) {
$range_end=$size-1;
} else {
$range_end=intval($range_end);
}
$new_length = $range_end-$range+1;
header("HTTP/1.1 206 Partial Content");
header("Content-Length: $new_length");
header("Content-Range: bytes $range-$range_end/$size");
} else {
$new_length=$size;
header("Content-Length: ".$size);
}
/* output the file itself */
$chunksize = 1*(1024*1024); //you may want to change this
$bytes_send = 0;
if ($file = fopen($file, 'r'))
{
if(isset($_SERVER['HTTP_RANGE']))
fseek($file, $range);
while(!feof($file) &&
(!connection_aborted()) &&
($bytes_send<$new_length)
)
{
$buffer = fread($file, $chunksize);
print($buffer); //echo($buffer); // is also possible
flush();
$bytes_send += strlen($buffer);
}
fclose($file);
} else die('Error - can not open file.');
die();
}
/*********************************************
Example of use
**********************************************/
/*
Make sure script execution doesn't time out.
Set maximum execution time in seconds (0 means no limit).
*/
set_time_limit(0);
$file_path='that_one_file.txt';
output_file($file_path, 'some file.txt', 'text/plain');
Please check code at:
http://w-shadow.com/blog/2007/08/12/how-to-force-file-download-with-php/
I'm using the following download script to download files uploaded on my server. The files are uploaded fine its just that when they are downloaded instead of getting downloaded the entire contents of the file to be downloaded are spilled out. Click on teh following url to see the problem:
http://iqtechworld.com/demo/download.php?id=28
The following is my download script i.e the entire file itself:
<?php
set_time_limit(0);
ini_set('display_errors', false);
include_once('includes.php');
ini_set('display_errors', false);
function output_file($file, $name, $mime_type='')
{
/*
This function takes a path to a file to output ($file),
the filename that the browser will see ($name) and
the MIME type of the file ($mime_type, optional).
If you want to do something on download abort/finish,
register_shutdown_function('function_name');
*/
if(!is_readable($file)) die('File not found or inaccessible!');
$size = filesize($file);
$name = rawurldecode($name);
/* Figure out the MIME type (if not specified) */
$known_mime_types=array(
"pdf" => "application/pdf",
"txt" => "text/plain",
"html" => "text/html",
"htm" => "text/html",
"exe" => "application/octet-stream",
"zip" => "application/zip",
"doc" => "application/msword",
"xls" => "application/vnd.ms-excel",
"ppt" => "application/vnd.ms-powerpoint",
"gif" => "image/gif",
"png" => "image/png",
"jpeg"=> "image/jpg",
"jpg" => "image/jpg",
"php" => "text/plain"
);
if($mime_type==''){
$file_extension = strtolower(substr(strrchr($file,"."),1));
if(array_key_exists($file_extension, $known_mime_types)){
$mime_type=$known_mime_types[$file_extension];
} else {
$mime_type="application/force-download";
};
};
#ob_end_clean(); //turn off output buffering to decrease cpu usage
// required for IE, otherwise Content-Disposition may be ignored
if(ini_get('zlib.output_compression'))
ini_set('zlib.output_compression', 'Off');
header('Content-Type: ' . $mime_type);
header('Content-Disposition: attachment; filename="'.$name.'"');
header("Content-Transfer-Encoding: binary");
header('Accept-Ranges: bytes');
/* The three lines below basically make the
download non-cacheable */
header("Cache-control: private");
header('Pragma: private');
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
// multipart-download and download resuming support
if(isset($_SERVER['HTTP_RANGE']))
{
list($a, $range) = explode("=",$_SERVER['HTTP_RANGE'],2);
list($range) = explode(",",$range,2);
list($range, $range_end) = explode("-", $range);
$range=intval($range);
if(!$range_end) {
$range_end=$size-1;
} else {
$range_end=intval($range_end);
}
$new_length = $range_end-$range+1;
header("HTTP/1.1 206 Partial Content");
header("Content-Length: $new_length");
header("Content-Range: bytes $range-$range_end/$size");
} else {
$new_length=$size;
header("Content-Length: ".$size);
}
/* output the file itself */
$chunksize = 1*(1024*1024); //you may want to change this
$bytes_send = 0;
if ($file = fopen($file, 'r'))
{
if(isset($_SERVER['HTTP_RANGE']))
fseek($file, $range);
while(!feof($file) &&
(!connection_aborted()) &&
($bytes_send<$new_length)
)
{
$buffer = fread($file, $chunksize);
print($buffer); //echo($buffer); // is also possible
flush();
$bytes_send += strlen($buffer);
}
fclose($file);
} else die('Error - can not open file.');
die();
}
global $FILE_OBJECT;
$one_file = $FILE_OBJECT->get($_GET['id']);
output_file(_config('files_path').$_GET['id'], $one_file['filename'], $one_file['type']);
exit;
#alex +1, check your web server settings, and also code, maybe there is another header('Content-type text/html');
Try use this
$file_extension = pathinfo($file, PATHINFO_EXTENSION);
instead of this
$file_extension = strtolower(substr(strrchr($file,"."),1));
Don't enclose the filename in quotes for Content-Disposition.
I have a website that has a downloads section. I need for the files not to be accessed directly by an annonymous user, so I am putting them in a directory not accessable to users, but is accessible to the web server. When the user clicks the link to download the file, I need it to redirect to a download page that will stream the file to the user without him knowing the location of the directory or the file and it will ask him to save it to his computer. I found the following code on a previous post, but I can't get it to work correctly. Could be that I don't know the correct names of the variables that it wants to be passed to it. Please include an explanation of how to use your code.
$filename='Firefox%20Setup%203.6.13.exe';
$file_path='http://ftp.byfly.by/pub/mozilla.org/firefox/releases/3.6.13/win32/fr';
$file= $file_path."/".$filename;
$len=filesize($file);
header("content-type: application/save");
header("content-length: $len");
header("content-disposition: attachment; filename=$filename");
$fp=fopen($file, "r");
fpassthru($fp);
This is how I would do it.
<?php
function getFile($file_location) {
header('Content-Description: File Transfer');
header('Content-type: application/exe');
header('Content-Disposition: attachment; filename="supercoolFF.exe"');
header('Content-Transfer-Encoding: binary');
ob_end_clean();
$url_info = parse_url($file_location);
if (!isset($url_info['query'])) $url_info['query'] = '';
$http = fsockopen($url_info['host'],$url_info['port']);
$req = "GET " . $url_info['path'] . "?" . $url_info['query'] . " HTTP/1.1\r\n";
$req .= "Host: " . $url_info['host'] . ":" . $url_info['port'] . "\r\n";
$req .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
$req .= "User-Agent Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8\r\n";
$req .= "Accept-Language: en-us,en;q=0.5\r\n";
$req .= "Accept-Encoding: gzip,deflate\r\n";
$req .= "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n";
if ($len = strlen($url_info['query']) {
$req .= 'Content-Length: ' . $len . "\r\n";
$req .= "Connection: Close\r\n\r\n";
$req .= $query . "\r\n\r\n";
} else {
$req .= "Connection: Keep-Alive\r\n\r\n";
}
fputs($http, $req);
$content = "";
$content_encountered = FALSE;
ob_end_clean();
while(strlen($part = fgets($http, 4096))) {
if ($content_encountered) {
echo $part;
$content .= $part;
}
if ($part == "\r\n") {
$content_encountered = TRUE;
}
}
fclose($http);
exit;
}
$filename='Firefox%20Setup%203.6.13.exe?';
$file_path='http://ftp.byfly.by:80/pub/mozilla.org/firefox/releases/3.6.13/win32/fr';
getFile($file_path . '/' . $filename);
Of course, it would be better to do a HEAD request first to get the filesize and include a Content-Length header in the response so the user can have some idea about how long it is going to take. Or, you can hardcode that number, if you are always going to be serving up the same file.
Let's say you have a file in a directory called "hiddenaccess" and the file name is "test.mp3" you can load the path in php variable and let it for download
<?php
$file = "./hiddenaccess/test.mp3";
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($file));
#readfile($file);
?>
Note: Do NOT have any other echo or print statements in this file.
Here's a function I (Apparently Others?!!?) developed to do just that, it's a meaty function but it checks and does everything. To call it is simple though, the important part. I have this inside a class but you can just make it a php function as there is no other class functions it depends on. Hope this helps you.
public static function output_file($path, $filename, $mime_type='') {
$err = 'Sorry, the file you are requesting is unavailable.';
$filename = rawurldecode($filename);
// check that file exists and is readable
if (file_exists($path) && is_readable($path)) {
/* Figure out the MIME type (if not specified) */
$known_mime_types=array(
"pdf" => "application/pdf",
"txt" => "text/plain",
"html" => "text/html",
"htm" => "text/html",
"exe" => "application/octet-stream",
"zip" => "application/zip",
"doc" => "application/msword",
"xls" => "application/vnd.ms-excel",
"ppt" => "application/vnd.ms-powerpoint",
"gif" => "image/gif",
"png" => "image/png",
"jpeg"=> "image/jpg",
"jpg" => "image/jpg",
"php" => "text/plain"
);
if($mime_type==''){
$file_extension = strtolower(substr(strrchr($filename,"."),1));
if(array_key_exists($file_extension, $known_mime_types)){
$mime_type=$known_mime_types[$file_extension];
} else {
$mime_type="application/force-download";
};
};
#ob_end_clean(); //turn off output buffering to decrease cpu usage
if(ini_get('zlib.output_compression')) { //otherwise the filesize is way off
ini_set('zlib.output_compression', 'Off');
}
// get the file size and send the http headers
$size = filesize($path);
header("Content-Type: $mime_type");
header('Content-Disposition: attachment; filename="'.$filename.'"');
header('Content-Transfer-Encoding: binary');
header('Accept-Ranges: bytes');
header('Cache-control: private');
header('Pragma: private');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
// multipart-download and download resuming support
if(isset($_SERVER['HTTP_RANGE'])) {
list($a, $range) = explode("=", $_SERVER['HTTP_RANGE'], 2);
list($range) = explode(",", $range, 2);
list($range, $range_end) = explode("-", $range);
$range=intval($range);
if(!$range_end) {
$range_end = $size-1;
} else {
$range_end = intval($range_end);
}
$new_length = $range_end-$range+1;
header("HTTP/1.1 206 Partial Content");
header("Content-Length: $new_length");
header("Content-Range: bytes $range-$range_end/$size");
} else {
$new_length = $size;
header("Content-Length: " . $size);
}
/* output the file itself */
$chunksize = 1*(1024*1024); //may want to change this
$bytes_send = 0;
if ($file = fopen($path, 'r')) {
if(isset($_SERVER['HTTP_RANGE'])) {
fseek($file, $range);
}
while(!feof($file) && (!connection_aborted()) && ($bytes_send<$new_length)) {
$buffer = fread($file, $chunksize);
print($buffer); //echo($buffer); // is also possible
flush();
$bytes_send += strlen($buffer);
}
fclose($file);
} else {
die($err);
}
} else {
die($err);
}
die();
}
To use it would be something like this.
$path = '/var/www/site/httpdocs/upload/private/myfile.txt';
$dl_filename = 'NDA_'.time();
$mime_type = 'doc';
output_file($path,$dl_filename,$mime_type);