I have an issue while downloading an mp3 file in PHP. I need to download the file, also rename it. Below is the download.php file which contains the following code:
$file = $_GET['file'];
$flname = explode("/",$file);
$num = sizeof($flname);
$filenme = $flname[$num-1];
$name_of_file = $filenme;
header('Content-Description: File Transfer');
header('Content-type: application/mp3');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Content-Length: '.filesize($name_of_file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
readfile_chunked($file);
function readfile_chunked($file)
{
$chunksize = 1*(1024*1024); // how many bytes per chunk
$buffer = '';
$handle = fopen($filename, 'rb');
if ($handle === false)
{
return false;
}
while (!feof($handle))
{
$buffer = fread($handle, $chunksize);
print $buffer;
}
return fclose($handle);
}
I am getting the file path in $file:
$file = $_GET['file'];
where $file becomes:
$file = "localhost/project/mp3 file path";
Then I am exploding it to get the mp3 file name only (thus removing the path).
I don't know what the problem is, but it's always showing some 490 bytes in the download dialogue of Firefox even if file is of 1-2MB. Can someone explain what I'm doing wrong?
Thank you in advance.
Open the downloaded file in a text editor. It probably contains php errors that will tell you what exactly is going on. It might be an issue with the path or permissions of the file you are trying to download.
Related
I am trying to download large zip files (800MB to 1GB) containing audio files to the browser. As I have seen so far, chunking seems to be the most popular approach, but I am having zero luck. The code I have been working with is
$filename = $_SERVER['DOCUMENT_ROOT'] . $filepath;
$download_rate = 5000;
$progress = 0;
if (file_exists($filename)) {
header('Cache-control: private');
header('Content-Type: application/octet-stream');
header('Content-Length: '.filesize($filename));
header('Content-Disposition: filename='.basename($filename));
flush();
$file = fopen($filename, "r");
while(!feof($file)) {
// send the current file part to the browser
print fread($file, round($download_rate * 1024));
// flush the content to the browser
flush();
// sleep one second
sleep(1);
}
fclose($file);
} else echo 'File does not exist!';
This works for a wide variety of file types and sizes up to a certain point -- I have no problem downloading typical PDFs, etc. But the browser just spins and spins when I try to download large zip files, and eventually dies (around 2 minutes). I am really needing some help here. I've tried a number of code variants for chucking, but something always seems to die and I'm not sure what I'm doing wrong. Perhaps there's a better approach to chunking?
Consider change change for readfile will not present any memory issues, your lost download rate and progress show in browser. your limit download rate in .httaccess.
$filename = $_SERVER['DOCUMENT_ROOT'] . $filepath;
if (file_exists($filename)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($filename).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: '.filesize($filename));
readfile($filename);
} else echo 'File does not exist!';
https://www.php.net/manual/en/function.readfile.php
i have website for storing large zip file and upload it to ftp server in php
now i want to download the file from ftp and limiting download speed
and be able to resuming and pause download i have this code :
$file_path = 'ftp://'.$ftp_username.':'.$ftp_password.'#'.$ftp_server.'/'.$ftp_filename_withDiR ;
$filesize_ftp = filesize($file_path);
ob_clean();
$download_rate = $Mbspeed;
header('Content-Description: File Transfer');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Type: application/octet-stream');
header("Content-Length:".$filesize_ftp);
header('Content-Disposition: filename='.$filenamea);
flush();
$file = fopen($file_path, "r");
while(!feof($file)) {echo fread($file, round($download_rate * 1024));flush();usleep(200); }
But i can't pause the download ! any ideas to solve this problem?
The task is to create a controller to count the number of file downloads. It also must be able to account for failed or cancelled downloads. I was wondering if anyone knew the best way to go about accomplishing this.
$file = $_GET['download'];
if (ob_get_level()) {
ob_end_clean();
}
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));
return filesize($file);`
$size = filesize($file);
Then if the number of bytes given is approximately equal to the file size:
if ( $size < given bytes) {
$handle = fopen("counter.txt", "r");
while (!feof($handle)) {
$buffer = fgets($handle, 4096);
$buffer=$buffer+1;
}
fclose($handle);
$fp = fopen("counter.txt", "w");
$test = fwrite( $fp, $buffer);
fclose($fp);
}
How to know the number of bytes sent by server to the user after clicking on link?
I'll start with what should be comments:
You've tagged this as javascript, but your quesiotn appears to have nothing to do with javascript. Please don't do that.
I assume you are aware of the gaping security hole exposed by your script / that you are not concerned about it.
Your handling of output buffering is wrong.
return filesize($file);
What is this line of code supposed to do?
header('Expires: 0');
no.
header('Pragma: public');
again, no.
As to your question - its all covered in the manual:
<?php
ignore_user_abort(1);
$file = $_GET['download'];
if (!is_readable($file)) {
die "No such 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('Cache-Control: max-age=0; must-revalidate');
header('Content-Length: ' . filesize($file));
$count=0;
$ih=fopen($file, 'r');
while (CONNECTION_NORMAL==connection_status() && !feof($ih)) {
print fgets($ih, 4096);
}
log_completion(feof($ih));
BTW: This does not give an accurate record if the file was downloaded - you can only tell if the content has left PHP land.
I have gone through all articles on Stack Overflow and can't fix my issue. I am using following code:
$file = $_GET['url'];
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
The above mention code is downloading the file from the directly above the root and Yes it is downloading a PDF file but the file is only of 1KB size and not the original size. The $_GET['url'] is receiving ../dir/dir/filename.pdf in it. the filename is space in it as well. For security reason I cannot share the file name.
Please let me know where am I going wrong.
Please make sure you are using the web server path to access the file - for instance your path could be: /home/yourusername/public/sitename/downloads/<filename>, you should check first - to help you can run this at the top of your PHP script to find out the full path for the current script:
echo '<pre>FILE PATH: '.print_r(__FILE__, true).'</pre>';
die();
Only send the filename with the url using urlencode() and on the receiving PHP script use urldecode() to handle any character encoding issues.
See here: http://php.net/manual/en/function.urlencode.php
and here: http://php.net/manual/en/function.urldecode.php
So where you create your url:
Download File
And in your php script:
$file_base_path = '/home/yourusername/public/sitename/downloads/';
$file = urldecode($_GET['url']);
$file = $file_base_path . $file;
$file = $_GET['url'];
if (file_exists($file))
{
if (FALSE!== ($handler = fopen($file, 'r')))
{
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: chunked'); //changed to chunked
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
//header('Content-Length: ' . filesize($file)); //Remove
//Send the content in chunks
while(false !== ($chunk = fread($handler,4096)))
{
echo $chunk;
}
}
exit;
}
echo "<h1>Content error</h1><p>The file does not exist!</p>";
I hope this helps you!
I have gotten a problem about downloading .jpg and .avi files from a server using PHP
I have the following code:
$fileName = "Koala.jpg";
$filePath = "./Koala.jpg";
if (!file_exists($filePath)){
echo "No file";
return;
}
$fp = fopen($filePath, "r");
$fileSize = filesize($filePath);
header("Content-type: application/octet-stream");
header("Accept-Ranges: bytes");
header("Content-Length: $fileSize");
header("Content-Disposition: attachment;filename=".$fileName);
$buffer = 1024;
while(!feof($fp)){
$data = fread($fp, $fileSize);
echo $data;
}
fclose($fp);
The code downloads .txt file successfully and the downloaded file can be read.
However, when it comes to .jpg, the downloaded .jpg file cannot be read.
Can anyone give a helping hand? Thanks
Have just tried another method and it works fine
$file = 'Koala.jpg';
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;
}
But just wonder what reason causes the first method fail, even though using fopen("xxx", "rb") instead. Thank you
Try replacing application/octet-stream for image/jpeg .
Regards
I'm no php expert (sorry to say) but I remember having a similar problem when using php on a Windows server. It stemmed from opening the file without the binary-flag (should be fopen($filePath, "rb"); in your sample). If you don't set that flag your data might be altered when you read it from the stream which could break your files (and you wouldn't notice it on textfiles).
See http://www.php.net/manual/en/function.fopen.php for more info on the different modes available.
Try using this --
<?php
$filename = "MyImage.jpg";
$handle = fopen($filename, "rb");
$contents = fread($handle, filesize($filename));
fclose($handle);
?>
Instead of the following code that you are using,
$buffer = 1024;
while(!feof($fp)){
$data = fread($fp, $fileSize);
echo $data;
}
Just use readfile method
readfile($filePath);