Issue with file downloads

Discussion in 'PHP' started by rspenc29, Oct 19, 2007.

  1. #1
    I am serving files using a download.php class and its all working fine but the problem is that when the dialog box pops up and asks the user to save, open, or cancel, the feof($file) returns true even if the user cancels. I want to log downloads to the database and I don't want to log it if the user cancels. Below is the function I am having the trouble with.

    function getDownloadFile()
    {
    	$file = fopen($this->file_path,"rb");
    	if($file) {
    		while(!feof($file)) {
    		     print(fread($file, $this->fsize));
        		     flush();
        		     if (connection_status()!=0) {
          		          fclose($file);
    		          die();
        		     }
      	         }
    		 if(feof($file)) $this->data_sent = true; //My Problem
    		 fclose($file);
           }
    }
    Code (markup):
    feof($file) is returning true even when the user clicks cancel. I want to be able to tell if the user clicks cancel so I don't log the download. Anyone know how to do this?
     
    rspenc29, Oct 19, 2007 IP
  2. nico_swd

    nico_swd Prominent Member

    Messages:
    4,153
    Likes Received:
    344
    Best Answers:
    18
    Trophy Points:
    375
    #2
    Don't read the whole file at once. Read a only a few thousand bytes, then check for the connection status, and exit if necessary.

    Or count the bytes sent, and if they equal the file size, then store the data.
     
    nico_swd, Oct 19, 2007 IP
  3. rspenc29

    rspenc29 Peon

    Messages:
    256
    Likes Received:
    3
    Best Answers:
    0
    Trophy Points:
    0
    #3
    I have tried looping through and only reading parts of the file at a time but no matter what it seems that the entire file is still being sent to the browser before the user accepts the download.

    So if I do: print(fread($file, 1024)); so it only reads part of the file and then test it, if I click cancel right away then it wont log the download but if I wait a few seconds before clicking cancel then it appears to finish the loop and still logs it.
     
    rspenc29, Oct 20, 2007 IP
  4. nico_swd

    nico_swd Prominent Member

    Messages:
    4,153
    Likes Received:
    344
    Best Answers:
    18
    Trophy Points:
    375
    #4
    How big are the files? If they're small, they might be outputted faster than the user can download them.

    Perhaps you want to try sleep() a second or two after sending some bytes.
     
    nico_swd, Oct 20, 2007 IP
  5. rspenc29

    rspenc29 Peon

    Messages:
    256
    Likes Received:
    3
    Best Answers:
    0
    Trophy Points:
    0
    #5
    Some of the files are small and some are pretty large. I don't want to use sleep() because it will slow down the downloads. I just wish there was some way to actually see if the user is downloading or canceling. Right now it just seems that I can only count what is sent to the browser but not whats actually downloaded. I tried using bitwise operators to count the data but still the same problem. The entire file can be sent to the browser and counted in the loop but that doesn't mean the user actually downloaded it. I wonder if maybe I can use javascript to capture the cancel event from the dialog box then stop the log if necessary.
     
    rspenc29, Oct 20, 2007 IP
  6. nico_swd

    nico_swd Prominent Member

    Messages:
    4,153
    Likes Received:
    344
    Best Answers:
    18
    Trophy Points:
    375
    #6
    It doesn't necessarily slow down the download. Because it takes PHP just a very small amount of time to read and output the file. It's outputted way before the user has actually downloaded it. Therefore you can sleep() a bit after sending some data, and the user won't even (necessarily) notice.

    Or try usleep() to sleep only microseconds.
     
    nico_swd, Oct 20, 2007 IP