Welcome Guest, Not a member yet? Register   Sign In
File Download Counter

Morning All

Any chance anyone would know how i can count how many times a file has been downloaded.

I know how to update the mysql side of things to add 1 to a field.
the issue i'm having is using the anchor tags in my foreach function (Which loops through and finds all the files in my doc management system).
What i need to do is attach a function to the anchor that allows you to view/download the document, to trigger off the mysql function.

I've tried a few things like changing the anchor to a function to trigger off to a controller to download the file, but in doing that it downloads an empty file.

The file link
echo "<td>" . " " . anchor(base_url() . 'uploads/'.$files['doc_location'], 'ViewFile')."</td>";

i tried this but had no luck at all by changing the link function to
echo "<td>" . " " . anchor('download/downdoc/'.$files['doc_location'], 'Download')."</td>";
Controller - Download
function downdoc() {
$data = file_get_contents("uploads/".$this->uri->segment(3));
$name= $this->uri->segment(3);

my mysql would be triggered to do something like this, but rather than the revision number being updated the no_of_times_downloaded column would be updated

$this->db->set('revision_number', 'revision_number + 1', FALSE)

any help would be great

OK, i know this post is old but i'll use it for a related question after i gave my solution to the download counter.

Here is what i use to count the number of download in my app :

Class Myclass {

   * docs download counter
   * call me with : site.com/myclass/get_document/##
   * file params are passed as url segments
   * @param <str> segment(1) : myclass =controller
   * @param <str> segment(2) : get_document =method
   * @param <str> segment(3) : ## =doc id
   * @param <str> segment(any) : /remove_error =include in url to hide any error while processing download
   * @param <str> segment(any) : /remove_count =include in url to disable count for the current file
  function get_document() {


    //look for the settings in url
    $current_url  = current_url();
    $remove_error = (bool)strrpos($current_url,'/noerror');
    $remove_count = (bool)strrpos($current_url,'/nocount');

    //getting doc id from url
    $this->doc_id = (int)$this->uri->segment(3, 0);

    // check doc id is ok
    // -------------------------------
    if( ! $this->doc_id ) {
      if (!$remove_error)
        log_error('error','jno file selected');
      return false;

    $f = $this->docs_model->get_by_id( $this->doc_id );

    // found in db
    if ( count($f)>0 ) {

      //1 unique row returned
      $doc = $f[0];

      // create full path and read file into a string
      // -------------------------------

      // complete url to file
      $download_url  = './storage/mydocs/' . $doc->doc_filename;
      $filecontent   = @file_get_contents( $download_url ); // Read the file's contents, false if error

      if ( $filecontent ) { //FILE READ SUCCESS

        // COUNT ENABLED
        if (!$remove_count) {

          // update the number of downloads in db
          // -------------------------------
          $update = array(
              'doc_id'    => $this->doc_id,
              'doc_count' => $doc->doc_count + 1 //current + 1



        // force download and auto exit/close
        // -------------------------------
        force_download($doc->doc_filename, $filecontent);

      else { //ERROR READING FILE
        if (!$remove_error)
          log_error('error','unattended error!')
        return false;


    }//row exist
    else { // doc not found in db
      if (!$remove_error)
        log_error('error','file not found in db!')
      return false;



* note: you can use config/routes.php to have a more user friendly url
* something like :
* $route['dodownload/(:any)']  = "myapp/get_document/$1";
* then when you type ".com/dodownload/##/nocount" will call ".com/myapp/get_document/##/nocount"

All your download links must come by get_document() first, it count +1 every time the link is clicked (even if download is cancelled).
for this example the file are all stored in the same dir (/storage/mydocs/).

hope it can help someone.

Now, my related problem is :

how to avoid counting a unique user multiple times for the same download (or a short time redownload) ?

In short I use a Download Manager in addition to firefox that brings 2 cases with wrong counts :

case 1 :
1. click the download link
2. It counts +1 and open the Download Manager
3. when i cancel it, it auto switches to the firefox default downloader windows
4. that counts +1 again when it open the FF default downloader.
So i clicked it once but i now got 2 views Sad

But here's the worst case :
1. click the download link and accept to download using the Download Manager
2. as it uses and opens multiple connexions to the same file, it'll bring X more views for the single click !
(as it split the download in several parralel connections, it count as many connections that were opened by the Download manager)

So I wondered if someone already met or fixed this kind of problem.
I was thinking in monitoring the user IP / time / to avoid the multiple count but i'm not sure if it could work.

Any idea ?

It's probably the most common way to check for the IP and see, if there's already an active download. If none is found, you can update the download count, otherwise you don't. That's most likely the way file-hosters do it, too.
You may also want to set a cookie instead of just some session information, because they are more reliable (i.e. they last longer). The TTL of you cookie can be set to some 10 seconds to "block" download count updates.

I think, if I were to write such a download manager I'd go with the cookie based no download count update routine.

thanx for your reply
i'll go with cookie as it seems to be a good way to monitor new downloads from a same ip Wink


Theme © iAndrew 2016 - Forum software by © MyBB