#1
  1. Back and Forth.
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2003
    Location
    Earth
    Posts
    491
    Rep Power
    0

    Delete File After One Download


    Hi guys,

    I'm working on this small web application which needs to delete a file after it has been downloaded once. Not sure if this is possible or not....

    An example....

    http://www.example.com/3039023930/download.zip

    After this file has been downloaded (completely. i.e. Not just started and then connection broke. But file has been fully downloaded successfully by the user), the file needs to be deleted to stop user downloading again.

    Any ideas on what the best way to do this would be.

    Thanks!!
  2. #2
  3. It
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Sep 2003
    Location
    UK
    Posts
    1,222
    Rep Power
    372
    If you don't mind a script running for every active download (and can be sure of enough control over PHP settings to stop script timeouts) you could just send the whole download through an intermediate script. Having ensured it's streamed the whole thing via fread(), stream_get_contents() in PHP5, or something along those lines, the script can safely assume it's done, close the file pointer, and then unlink() away (assuming it has write permission).

    Actually, I don't see any other very easy way to do this, without carefully tracking Apache's every move.
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2005
    Location
    Sydney
    Posts
    174
    Rep Power
    36
    I use this nifty script that i found somewhere it will tell you if the file has been downloaded, i use if for a downloads page where each person can only download the file once...

    PHP Code:
    function send_file($name) {
      
    ob_end_clean();
      
    $path "protected/".$name;
      if (!
    is_file($path) or connection_status()!=0) return(FALSE);
      
    header("Cache-Control: no-store, no-cache, must-revalidate");
      
    header("Cache-Control: post-check=0, pre-check=0"false);
      
    header("Pragma: no-cache");
      
    header("Expires: ".gmdate("D, d M Y H:i:s"mktime(date("H")+2date("i"), date("s"), date("m"), date("d"), date("Y")))." GMT");
      
    header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
      
    header("Content-Type: application/octet-stream");
      
    header("Content-Length: ".(string)(filesize($path)));
      
    header("Content-Disposition: inline; filename=$name");
      
    header("Content-Transfer-Encoding: binary\n");
      if (
    $file fopen($path'rb')) {
       while(!
    feof($file) and (connection_status()==0)) {
         print(
    fread($file1024*8));
         
    flush();
       }
       
    fclose($file);
      }
      return((
    connection_status()==0) and !connection_aborted());
    }


    if (!
    send_file("platinumdemo.zip")) {
    die (
    "file transfer failed");
    // either the file transfer was incomplete
    // or the file was not found
    } else {
    // the download was a success
    // log, or do whatever else

    and then just use an unlink function or a my own delete function
    PHP Code:
    function delete($path){
        if(
    file_exists($path)){
            if(
    is_writable($path)){
                if(
    unlink($path))
                    
    $output true;
                else
                    
    $output false;
            }else
                
    $output false;
        }else
            
    $output false;
        return 
    $output;

  6. #4
  7. Back and Forth.
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2003
    Location
    Earth
    Posts
    491
    Rep Power
    0
    I totally forgot about this thread!!

    Thank you for this code. I will definitely take a look into it and it looks like just what I am looking for.



    Originally Posted by tuesproof
    I use this nifty script that i found somewhere it will tell you if the file has been downloaded, i use if for a downloads page where each person can only download the file once...

    PHP Code:
    function send_file($name) {
      
    ob_end_clean();
      
    $path "protected/".$name;
      if (!
    is_file($path) or connection_status()!=0) return(FALSE);
      
    header("Cache-Control: no-store, no-cache, must-revalidate");
      
    header("Cache-Control: post-check=0, pre-check=0"false);
      
    header("Pragma: no-cache");
      
    header("Expires: ".gmdate("D, d M Y H:i:s"mktime(date("H")+2date("i"), date("s"), date("m"), date("d"), date("Y")))." GMT");
      
    header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
      
    header("Content-Type: application/octet-stream");
      
    header("Content-Length: ".(string)(filesize($path)));
      
    header("Content-Disposition: inline; filename=$name");
      
    header("Content-Transfer-Encoding: binary\n");
      if (
    $file fopen($path'rb')) {
       while(!
    feof($file) and (connection_status()==0)) {
         print(
    fread($file1024*8));
         
    flush();
       }
       
    fclose($file);
      }
      return((
    connection_status()==0) and !connection_aborted());
    }


    if (!
    send_file("platinumdemo.zip")) {
    die (
    "file transfer failed");
    // either the file transfer was incomplete
    // or the file was not found
    } else {
    // the download was a success
    // log, or do whatever else

    and then just use an unlink function or a my own delete function
    PHP Code:
    function delete($path){
        if(
    file_exists($path)){
            if(
    is_writable($path)){
                if(
    unlink($path))
                    
    $output true;
                else
                    
    $output false;
            }else
                
    $output false;
        }else
            
    $output false;
        return 
    $output;

  8. #5
  9. Back and Forth.
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2003
    Location
    Earth
    Posts
    491
    Rep Power
    0
    Originally Posted by BurningSnowman
    If you don't mind a script running for every active download (and can be sure of enough control over PHP settings to stop script timeouts) you could just send the whole download through an intermediate script. Having ensured it's streamed the whole thing via fread(), stream_get_contents() in PHP5, or something along those lines, the script can safely assume it's done, close the file pointer, and then unlink() away (assuming it has write permission).

    Actually, I don't see any other very easy way to do this, without carefully tracking Apache's every move.
    Yeah....I was thinking this would be the best way to do it. Are the problems with script timeouts a legitimate concern?

    I'm wondering how allofmp3.com does it. They actually link you straight to the file. After you have finished downloading the file - the mp3 is deleted and no longer exists. I'm thinking they have some type of cron job that can monitor such a thing or the .mp3 is a disguised .php script that is doing precisely what you said above.
  10. #6
  11. It
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Sep 2003
    Location
    UK
    Posts
    1,222
    Rep Power
    372
    Originally Posted by njcallen
    Yeah....I was thinking this would be the best way to do it. Are the problems with script timeouts a legitimate concern?
    If it's only for your own site and set_time_limit() is working for you (try it out with an infinite loop or something if you really don't know), then no, it's no problem at all. It's just not entirely portable.
    I'm wondering how allofmp3.com does it. They actually link you straight to the file. After you have finished downloading the file - the mp3 is deleted and no longer exists. I'm thinking they have some type of cron job that can monitor such a thing or the .mp3 is a disguised .php script that is doing precisely what you said above.
    mod_rewrite? You could easily make any .mp3 request actually call a script with the requested file as a parameter, which would stream the actual file as the response and then do its deletion stuff.
  12. #7
  13. Back and Forth.
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2003
    Location
    Earth
    Posts
    491
    Rep Power
    0
    Originally Posted by BurningSnowman
    If it's only for your own site and set_time_limit() is working for you (try it out with an infinite loop or something if you really don't know), then no, it's no problem at all. It's just not entirely portable.
    Okay....that's good to hear. Yeah - set_time_limit() works to a certain degree. However, after 10-15 minutes, it sometimes timeouts, even with set_time_limit(0) set. Could be a browser/server issue more than PHP?

    Originally Posted by BurningSnowman
    mod_rewrite? You could easily make any .mp3 request actually call a script with the requested file as a parameter, which would stream the actual file as the response and then do its deletion stuff.
    mod_rewrite - I hadn't thought of that. I was thinking of using the AddHandler within Apache and put .mp3 as an extension to be processed - the .mp3 would basically be the PHP file with the code in it and then would stream the real .mp3 and then delete.
  14. #8
  15. Back and Forth.
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2003
    Location
    Earth
    Posts
    491
    Rep Power
    0
    Oh yeah, I found this a few weeks ago and has been very useful for mod_rewrite.....

    http://www.ilovejackdaniels.com/mod_...heat_sheet.png

    Comments on this post

    • tuesproof agrees : Ive got a few cheat sheets from there, they have been quite helpful

IMN logo majestic logo threadwatch logo seochat tools logo