Jump to content

Recommended Posts

On PHP 5.2.14.

 

I want to make files downloadable from my website. This seems easy enough:

<?php
$file = "downloads/someFile.txt";
// Set headers
header( "Content-Description: File Transfer" );
header( "Content-Type: application/force-download");
header( "Content-Length: " . filesize( $filename ) );
header( "Content-Disposition: attachment; filename=$file");
//	header( "Content-Transfer-Encoding: binary");
readfile( $file );
unlink( $file );
?>

You'll notice, however, that I have "unlink" at the end of this file. That's exactly what I want: to remove the file from the server once it has been downloaded, to prevent anyone else from downloading it.

 

Here's the conundrum: When the user navigates to this URL, browsers offer the choice of Open/Save/Cancel. I don't want users to "open", and if the user presses "cancel", well then I probably don't really want the file deleted.

 

In short: I want the file SAVED, only. And I want to delete the file immediately after it has been downloaded.

 

Thoughts?

Link to comment
https://forums.phpfreaks.com/topic/212206-download-file-question/
Share on other sites

You cannot control how the browsers asks the users what they want to do. You cannot tell if the user "truly" downloaded the file either. So yea, you are stuck between a hardspot and a rock. Sorry mate. 

 

EDIT:

However, using a Java or Flash application, this may be possible, but I am not 100% on that (or at least a bandwidth monitor for the current connections should be possible). I would suggest looking into that route.

I know how you can do it.

 

You could write some simple CLI PHP that hooks into the Apache logs (assuming you're using that) to see what the per-file / per-IP activity was and make a decision about what to do with the file that way. Just setup your logs with %B:

 

http://httpd.apache.org/docs/2.0/mod/mod_log_config.html#formats

 

You can compare how many bytes were transferred with the actual bytes to see if the file was downloaded or not. Just use exec() (or its cousins) with cat and grep to find the lines of the log you need.

 

I bet you could do it in less than 50-100 lines. Let me know if I can clarify further.

This comment from the PHP Manual seems to address your second question:

 

To anyone that's had problems with Readfile() reading large  files  into memory the problem is not Readfile() itself, it's because you have output buffering on. Just turn off output buffering immediately before the call to Readfile(). Use something like ob_end_flush().

Addressing the readfile question, aside from jayarsee's information on the output buffering, another option is a custom user function: here http://us.php.net/manual/en/function.readfile.php#88549

 

Which is:

 

    function readfile_chunked ($filename,$type='array') { 
      $chunk_array=array(); 
      $chunksize = 1*(1024*1024); // how many bytes per chunk 
      $buffer = ''; 
      $handle = fopen($filename, 'rb'); 
      if ($handle === false) { 
       return false; 
      } 
      while (!feof($handle)) { 
          switch($type) 
          { 
              case'array': 
              // Returns Lines Array like file() 
              $lines[] = fgets($handle, $chunksize); 
              break; 
              case'string': 
              // Returns Lines String like file_get_contents() 
              $lines = fread($handle, $chunksize); 
              break; 
          } 
      } 
       fclose($handle); 
       return $lines; 
    } 

 

I have used this and it has worked for me. It may be able to be optimized a bit, but yea.

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.