Skip to content
Advertisement

PHP Download MP3 files from directory on server

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

Advertisement

Answer

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);
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement