Jump to content

Unique MP3 download link


tomhoad

Recommended Posts

Can anybody recommend a way (or a bit of existing software/code) to create a unique mp3 download link for a registered email address? i.e. So that the user can only download that file once in exchange for their email address, and not distribute the link once they have signed up as it has 'expired'?

 

Regards,

 

Tom

Link to comment
Share on other sites

Create yourself a directory named "MP3FILES" out of your root directory (that way users can't access the files directly through their browser but the PHP file can).

 

When someone gives you their email address salt and md5 encrypt the email (Example: http://www.example.com/dl.php?email=ex@ample.com&verify=7DG876SDF897SDF87SFDKSDJHFSDK <- salt'ed & MD5 encrypted email to ensure you sent that link) and send the link to their email using the php mail function. Then use a function like this to serve the file once you confirm their email (and perhaps store their email in MySQL or text file to ensure they can't download again).

 

function send_download($filename)
{ 
   $file_path = '../MP3FILES/' . $filename; 
   $file_size=@filesize($file_path); 
   header("Content-Type: application/x-zip-compressed"); 
   header("Content-disposition: attachment; filename=$filename"); 
   header("Content-Length: $file_size"); 
   readfile($file_path); 
   exit; 
}

Link to comment
Share on other sites

  • 2 weeks later...

Ok, so I'm getting there with this, here's my code so far:

 

submit.php

<?php

//open database
include 'config.php';
include 'opendb.php';
    
//get email from form
$email=$_POST['email'];

//salt
$salt="H67R";

//encrypt email using md5 hash
$enc_email=md5($email.$salt);

if ( the token doesnt already exist in the database )
{
$query = " INSERT INTO records (email, used) ". 
" VALUES ('$enc_email', 0)"; 
mysql_query($query) or die('Error ,query failed'); 


print "Download link:<br><br>\n";
print "<a href='download.php?token=$enc_email'>here</a>\n";
}
else
{
print "You already downloaded!"
}

//close database
include 'closedb.php';

?>

 

download.php

<?php

//get token
$token = $_GET['token'];

//path to file
$secretfile = "../music.mp3";

//if valid, output
if( the token exists in the database and the used value is 0)
{
        readfile($secretfile);
	$query = "UPDATE records SET used = '1' WHERE email = '$token'";
           mysql_query($query) or die('Error : ' . mysql_error());
}
else
{
        print "Your token is bad!";
}

?>

 

I just need to replace the 'if' statements pseudo code with actual code, but I'm not sure how to query the database to check if it already exists etc. Very simple but I'm just starting out here and appreciate your patience.

 

The 'used' value is a boolean that updates to 1 once the url has been used, so when we check the token we can see if it's been used or not.

 

Thank you for your help thus far!

Link to comment
Share on other sites

$query = "SELECT used FROM records WHERE email = '$enc_email'";
$result = mysql_query($query) or trigger_error('Error: ' . mysql_error());
if ($result && mysql_num_rows($query)) {
    list($used) = mysql_fetch_row($result);//$used if you need it.

 

But you may have a problem: is there only one mp3 file that can be downloaded once? Or do you want to be able to add multiple mp3 files?

Link to comment
Share on other sites

At the moment I am focusing on one-email, one-download.

 

However, there is the potential for more mp3s to be added - would that be a problem?

 

Yes because if you would have a second mp3 file then how would you know which a user has already downloaded?

 

INSERT INTO records VALUES (email, used)

 

You could ofcourse expand it with:

 

INSERT INTO records VALUES (email, mp3, used)

 

But IMO it would be better if you had something like:

 

CREATE TABLE users (
  #table definition
);

CREATE TABLE songs (
  #table definition
);

CREATE TABLE users_downloads (
  users_downloads_users_id INTEGER NOT NULL,
  users_downloads_songs_id INTEGER NOT NULL,
  PRIMARY KEY (users_downloads_users_id, users_downloads_songs_id)
);

 

If a record exists for the users_id with the given songs_id in the users_downloads table then the user has already downloaded that song. This has a great advantage over:

 

INSERT INTO records VALUES (email, mp3, used)

 

Because the user's details are contained within the users table and the songs details are contained in the songs table thus making it possible to update either without having to worry the user might be able to download a song two times as would happen with the previous method (records table) when you update a song's name.

Link to comment
Share on other sites

Chances are the download will feature artwork, lyrics, mp3 etc. so I may just bundle that all into a zip file. I know if I was the user I would rather download a single zip file than 4 or 5 seperate files. This would also keep the application as simple as possible.

Link to comment
Share on other sites

Chances are the download will feature artwork, lyrics, mp3 etc. so I may just bundle that all into a zip file. I know if I was the user I would rather download a single zip file than 4 or 5 seperate files. This would also keep the application as simple as possible.

 

My original question then still applies. What if you again have multiple songs, lyrics, artwork are you going to keep them in that single file (even if it gets over 100 megs)?

Link to comment
Share on other sites

Cool, thanks Ignace, I will definitely bear that in mind when building this thing! Just want to get it up and running for the moment.

 

I am having some problems actually serving the mp3 now. I have tried:

 

function send_download($filename)
{ 
   $file_path = '../MP3FILES/' . $filename; 
   $file_size=@filesize($file_path); 
   header("Content-Type: application/x-zip-compressed"); 
   header("Content-disposition: attachment; filename=$filename"); 
   header("Content-Length: $file_size"); 
   readfile($file_path); 
   exit; 
}

 

... but all I get is a load of jargon in the browser window and the browser hanging. Have looked into fread() but not sure how to use it. Any ideas on best way to force the download?

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.