I am attempting to download MP3 files to the user computer located in a directory named "songs" on the server. I have been able to run a script which downloads these files through the browser. However, these files download strictly as text with .mp3 extension. I want these files to be playable mp3 files upon downloading from the server.
Here is my PHP script.
<?php
$link = mysqli_connect("...","...","....","...") or die("Error ".mysqli_error($link));
if(mysqli_connect_errno())
{echo nl2br("Failed to connect to MySQL:". mysqli_connect_error() . "\n");}
else
{echo nl2br("Established Database Connection \n");}
//Script currently downloads a list of all songs found on server
$target = "songs/";
if ($handle = opendir($target)) {
while (false !== ($entry = readdir($handle))) {
if ($entry != "." && $entry != "..") {
echo $entry."'>".$entry."</a>\n";
}
}
closedir($handle);
}
$file = basename($_GET['file']);
$file = 'Songs_From_Server'.$file;
if(!$file){ // file does not exist
die('file not found');
} else {
header("Cache-Control: private");
header("Content-type: audio/mpeg3");
header("Content-Transfer-Encoding: binary");
header("Content-Disposition: attachment; filename=".basename($file));
readfile($file);
}
?>
Here is an example of the result I get in a txt file.
Established Database Connection
01 In 1983 He Loved To Fly.mp3'>01 In 1983 He Loved To Fly.mp3
First, header()should be sent before any output which includes echo, print_r, any html, a blank space before the opening tag(eg. <?php). Refer
to the manual
Second, if you want to response with the content of a file to the browser, your script should not output anything else. Any output besides the content will be considered a part of the content. Unless you send it as multipart and your client is able to handle it.
So, an example
<?php
$fileName = $_GET['file'];
$path = '/directory/contains/mp3/';
$file = $path.$fileName;
if (!file_exists($file)) {
http_response_code(404);
die();
}
header("Cache-Control: private");
header("Content-type: audio/mpeg3");
header("Content-Transfer-Encoding: binary");
header("Content-Disposition: attachment; filename=".$fileName);
//So the browser can display the download progress
header("Content-Length: ".filesize($file));
readfile($file);
This worked for me
header("Content-type: application/mp3");
header("Content-Disposition: attachment; filename=".$s['song_name']);
header('Pragma: no-cache');
header('Expires: 0');
//So the browser can display the download progress
readfile('uploads/'.$s['song_mp3']);
exit;
Related
I am having an issue with the below code (it works fine on local).
I am using this for an image gallery to download a selection of images using a checkbox. Anyways, this is working fine on my localhost but when I execute this code on my live site it downloads a zip file with the correct file names but the the files are blank.
Any suggestions to why this may be happening?
<?php
function zipFilesAndDownload($file_names, $archive_file_name, $file_path)
{
$zip = new ZipArchive();
//create the file and throw the error if unsuccessful
if ($zip->open($archive_file_name, ZIPARCHIVE::CREATE) !== true) {
exit("cannot open <$archive_file_name>\n");
}
foreach ($file_names as $files) {
# download file
$download_file = file_get_contents($files);
#add it to the zip
$zip->addFromString(basename($files), $download_file);
}
$zip->close();
$zipped_size = filesize($archive_file_name);
header("Content-Description: File Transfer");
header("Content-type: application/zip");
header("Content-Type: application/force-download");// some browsers need this
header("Content-Disposition: attachment; filename=$archive_file_name");
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header("Content-Length:" . " $zipped_size");
ob_clean();
flush();
readfile("$archive_file_name");
unlink("$archive_file_name"); // Now delete the temp file on the server
exit;
}
if (isset($_POST['formSubmit'])) {
//$file_names=$_POST['files'];//
//$file_names = filter_var_array($_POST['files']);//works but it's the wrong method
$filter = filter_input_array(INPUT_POST, FILTER_SANITIZE_SPECIAL_CHARS); //sanitise files
$file_names = $filter['files'];
//Archive name
$archive_file_name = 'product-images.zip';
//Download Files path
$file_path = getcwd() . '';
//cal the function
zipFilesAndDownload($file_names, $archive_file_name, $file_path);
} else {
header("Refresh: 5; url= ./index.php ");
print '<h1 style="text-align:center">You you shouldn\'t be here ......</pre>
<p style="color: red;"><strong>redirection in 5 seconds</strong></p>
<pre>';
exit;
}
?>
edit: i see this in my php error log:
PHP message: PHP Warning: ZipArchive::close(): Failure to create temporary file: Permission denied in /var/www/html/wp-content/plugins/jig/download-product-images.php on line 19
In the website page contains many images with downloading options. If I click the download button it automatically downloaded on user system and it shows on browser downloadable page. I have PHP code like
$image = file_get_contents('http://website.com/images/logo.png');
file_put_contents('C:/Users/ASUS/Downloads/image.jpg', $image);
Above coding is working fine. But I need to provide the path name for image to save. In user side we don`t know the path.
I need the PHP code to use the browser download location and download images need to show the browser downloads.
not possible to store the image in particular user location due to security issues .you don't force user .you have to suggest him to store particular location .and also you don't know the what file system there in user system.and also downloading path can be setting up by user anywhere so your not able to get that.
$filename = '/images/'.basename($_POST['text']);
file_put_contents($filename, $content);
you have to save/download the image somewhere on your web serwer and next send the file to user using header function, for example:
$file = 'path_to_image';
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
}
else {
echo "file not exists";
}
manual
`<?php
$filename ='http://website.com/images/logo.png';
$size = #getimagesize($filename);
$fp = #fopen($filename, "rb");
if ($size && $fp)
{
header("Content-type: {$size['mime']}");
header("Content-Length: " . filesize($filename));
header("Content-Disposition: attachment; filename=$filename");
header('Content-Transfer-Encoding: binary');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
fpassthru($fp);
exit;
}
header("HTTP/1.0 404 Not Found");
?>`
I'm creating a website on my localhost that should let people download some .rar files.
In my index I've created some tags like this:
$filename = "Test001.rar";
'.$filename.'';
This is just an example of one single file, but in my php file 'download.php' I've got the problem when I want to download the .rar file
This is download.php
<?php
echo "Welcome to Knowledge!";
if (isset($_GET['file']) && basename($_GET['file']) == $_GET['file'])
{
$file = $_GET["file"];
$path = 'C:\xampp\htdocs\TestSite'."\\".$file;
}
$err = $path.'Sorry, the file you are requesting doesnt exist.';
if (file_exists($path) && is_readable($path))
{
//get the file size and send the http headers
$size = filesize($path);
header('Content-Type: application/x-rar-compressed, application/octet-stream');
header('Content-Length: '.$size);
header('Content-Disposition: attachment; filename='.$file);
header('Content-Transfer-Encoding: binary');
readfile($filename);
}
?>
It opens the stream in the right way, but I get that the file size is about 200 bytes and not the full length that is about 200MB.
How can I fix this problem?
Remove the echo statement, there should not be any output before the headers. Change readfile($filename) to readfile($file)
I am using the following function to download pdf file it is working fine when i download it from PC or laptop but when i click on download link using ipad it opens a page with lots of special chracters and I am unable to download the file.
My download function is
public function download() {
$download_path = $_SERVER['DOCUMENT_ROOT'] . "/import";
$filename = $_GET['file'];
$file = str_replace("..", "", $filename);
$file = "$download_path/$file";
if (!file_exists($file))
die("Sorry, the file doesn't seem to exist.");
$type = filetype($file);
header("Content-type: $type");
header("Content-Disposition: attachment;filename=$filename");
header('Pragma: no-cache');
header('Expires: 0');
readfile($file);
}
Any idea about this error ?
This is probably the issue:
$type = filetype($file);
header("Content-type: $type");
From the manual
Possible values are fifo, char, dir, block, link, file, socket and
unknown.
Which are not things you want to see in the header. You are probably looking for:
header('Content-type: application/pdf');
You probably want finfo_file() and not filetype().
I have set up a page using php and mysql that requires user to log in to download various paid for programs. They can click on a link as here and the program downloads and runs correctly.
$c3 = mysql_result($result,$i,"exe");
echo "<a href='$c3'>... etc
However, RT-click properties lets them see the path to that file, so I changed the above to:
$c3="downloads3.php?link=".mysql_result($result,$i,"exe");
Where downloads3.php is as follows:
<?php
$file = $_GET['link'];
$size = filesize($file);
$type = filetype($file);
$path = "../downloads/";
header('Content-Type: $type');
header("Content-Transfer-Encoding: Binary");
header("Content-Disposition: attachment; filename=$path.$file");
header("Content-Length: ".filesize($file));
readfile($file_url);?>
?>
It finds the correct file and I get a security warning but on clicking run anyway it immediately gives a windows error message that the file is not compatible with this version of windows. Must be something in the above header but can't figure out what. Tried various permutations.
Any brill ideas, either of getting the above to work or other ways of hiding the source path? Thanks.
It's far more likely that the EXE is getting corrupted due to unexpected output. Your downloads3.php file has some extra output that will appear in the download:
readfile($file_url);?> //PHP stops parsing here
?> //output "\n?>"
The PE header itself tells Windows what versions it can run on, so if any errors get generated before the file gets sent, they'll appear in the place Windows is expecting the header.
To mitigate this you can remove the extra newline and ?> at the end of the file and turn error reporting off with error_reporting(0) at the top of the file.
The Best solution for here to get download file with any name what do you have want
function force_download($filename = '', $data = '')
{
if ($filename == '' OR $data == '')
{
return FALSE;
}
// Try to determine if the filename includes a file extension.
// We need it in order to set the MIME type
if (FALSE === strpos($filename, '.'))
{
return FALSE;
}
// Grab the file extension
$x = explode('.', $filename);
$extension = end($x);
// Load the mime types
if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/mimes'.EXT))
{
include(APPPATH.'config/'.ENVIRONMENT.'/mimes'.EXT);
}
elseif (is_file(APPPATH.'config/mimes'.EXT))
{
include(APPPATH.'config/mimes'.EXT);
}
// Set a default mime if we can't find it
if ( ! isset($mimes[$extension]))
{
$mime = 'application/octet-stream';
}
else
{
$mime = (is_array($mimes[$extension])) ? $mimes[$extension][0] : $mimes[$extension];
}
// Generate the server headers
if (strpos($_SERVER['HTTP_USER_AGENT'], "MSIE") !== FALSE)
{
header('Content-Type: "'.$mime.'"');
header('Content-Disposition: attachment; filename="'.$filename.'"');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header("Content-Transfer-Encoding: binary");
header('Pragma: public');
header("Content-Length: ".strlen($data));
}
else
{
header('Content-Type: "'.$mime.'"');
header('Content-Disposition: attachment; filename="'.$filename.'"');
header("Content-Transfer-Encoding: binary");
header('Expires: 0');
header('Pragma: no-cache');
header("Content-Length: ".strlen($data));
}
exit($data);
}
$data = 'Here is some text!';
$name = 'mytext.txt';
force_download($name, $data);
DOH!!!!!!!!!!!!!!!! Too much cutting and pasting, that code has a really stupid error readfile($file_url) should be readfile($file), no wonder my 36Mb file was only 1KB after download, it was empty!
Thanks for all the comments, apologies for wasting your time.