Hi. At the moment I'm using something similar to the following code to download mp3s:

header("Content-type: audio/x-mp3");
header("Content-Disposition: attachment; filename=$file.mp3");
readfile("$file.mp3");

This works fine, but I have a problem if I want to password-protect the mp3s. If the php script is in the same directory as the mp3 (i.e. the password-protected directory), there's no problem, as only people with access to that directory can run it. If the php script is in a non-protected directory however, there is a problem, as anyone can run it - and download the mp3 by doing so.

What I want to know is if the above code can be extended in such a way as to prevent anyone and everyone from downloading the mp3. I don't want to put the script in the same directory as the file unless I really have to.

I've tried adding:

header("Content-location: $collection/");

but, unlike header("Location: $collection") - which I don't want because I don't want to redirect people - this doesn't prompt for username and password. Can anyone help?

    You'd have to have a login function that logs people in and on this page it would check if they are logged in...then

    readfile("./dir/to/mp3s/"$file.mp3");

      <?php
      define("PASSWORD","pw");
      if(!isset($_POST['password']) or $_POST['password'] != PASSWORD)
      {
          die("You need a password to access this page.<br>\n<form action='{$_SERVER['PHP_SELF']}' method='post'>\nPassword:<br>\n<input type='password' name='password'><br>\n<input type='submit' value='Enter'><br></form>");
      }
      header("Content-type: audio/x-mp3"); 
      header("Content-Disposition: attachment; filename=$file.mp3"); 
      readfile("$file.mp3");
      ?>
      

      or, if you are going to have a multi-page system:

      <?php
      define("PASSWORD","pw");
      define("MP3_PATH","path/to/mp3s");
      session_start();
      if(isset($_POST['password']) and $_POST['password'] == PASSWORD)
      {
          $_SESSION['mp3_loggedin'] = true;
      }
      if(isset($_POST['logout']))
      {
          $_SESSION['mp3_loggedin'] = false;
          unset($_SESSION['mp3_loggedin']);
      }
      if(!isset($_SESSION['mp3_loggedin']) or !$_SESSION['mp3_loggedin'])
      {
          die("You need a password to access this page.<br>\n
      <form action='{$_SERVER['PHP_SELF']}' method='post'>\nPassword:<br>\n<input type='password' name='password'><br>\n<input type='submit' value='Enter'><br></form>");
      }
      if(!isset($_POST['file']))
      {
          $dir = dir(MP3_PATH);
          while(($e = $dir->read()) !== false)
          {
              if(!is_file($e)) continue;
              $filelist .= "<option>$e</option>";
          }
          die("Please select a file:<br>
      <form action='{$_SERVER['PHP_SELF']}' method='post'>
      <select name='file'>{$filelist}</select><br>
      <input type='submit' value='Download'>
      </form>");
      }
      header("Content-type: audio/x-mp3"); 
      header("Content-Disposition: attachment; filename={$_POST['file']}.mp3"); 
      readfile(MP3_PATH."/{$_POST['file']}.mp3");
      ?>
      

      I might have screwed up the directory read syntax.

        Thanks guys/girls - nlhowell in particular!
        I'm using .htaccess to protect the directories with the mp3s in them at the moment - one directory per collection. Is this code compatible with using .htaccess for protection?
        Anyway, I'll be having a look at the code - trying to get my head around it, as I'm still completely new to PHP - and maybe testing it if it is compatible!
        Thanks again. Much appreciated (..whether it works with what I have already or not)!🙂

          This script actually doesn't have anything to do with the .htaccess. Regardless, the script will be able to display the files if the correct password is entered.

            Well, the passwords in the .htgroup file which my .htaccess files refer to are also stored in a database. Perhaps I could modify your code so that it referred to this database? Anyway, it would take me a while to figure out how to do this, as I'm new to PHP, and haven't even touched MySQL (as the database referred to was set up using commercially available scripts written by someone else). I'll just keep on using an alternative - yet less efficient - method for the moment.
            Thanks again!

              Write a Reply...