1

I am new to this and I am having problems trying to get my website to count the number of times a files has been downloaded. The website has download buttons linking to the files which are stored on my database, and I would like to be able to count the amount of downloads per file to display as a statistic, ideally once they click the link to download, the column in the files table should be incremented, but I cannot wrap my head around it. please help?

    <?php 
error_reporting(E_ALL ^ E_NOTICE); 
session_start(); 
$userid = $_SESSION['userid']; 
$username= $_SESSION['username']; 
?>

<?php

// Make sure an ID was passed
if(isset($_GET['id'])) {
// Get the ID
$id = ($_GET['id']);

// Make sure the ID is in fact a valid ID
if($id <= 0) {
    die('The ID is invalid!');
}
else {
    // Connect to the database
    $dbLink = new mysqli('dragon.kent.ac.uk', 'repo', '3tpyril', 'repo');
    if(mysqli_connect_errno()) {
        die("MySQL connection failed: ". mysqli_connect_error());
    }

    // Fetch the file information
    $query = "
        SELECT `mime`, `name`, `size`, `data`
        FROM `files`
        WHERE `id` = {$id}";
    $result = $dbLink->query($query);

    if($result) {
        // Make sure the result is valid
        if($result->num_rows == 1) {
        // Get the row
            $row = mysqli_fetch_assoc($result);



            // Print headers
            header("Content-Type: ". $row['mime']);
            header("Content-Length: ". $row['size']);
            header("Content-Disposition: attachment; filename=". $row['name']);

            // Print data
            echo $row['data'];


        }
        else {
            echo 'Error! No files exists with that ID.';
        }


    }
    else {
        echo "Error! Query failed: <pre>{$dbLink->error}</pre>";
    }
    @mysqli_close($dbLink);


    }
    }
  else {
    echo 'Error! No ID was passed.';
   }
    ?>
  • 1
    `update yourtable set downloads=downloads+1 where id=XXX` whenever the download script is triggered. – Marc B Mar 18 '14 at 19:29
  • code? attempts? just keep a count field, and add 1 to it on each download –  Mar 18 '14 at 19:30
  • @MarcB I have added my code for the file that contains the download script, where is best in that code to place the sql query to update the table as i have tried a few places but it doesn't work :/ –  Mar 18 '14 at 19:44
  • You are also vulnerable to [SQL injection attack](http://bobby-tables.com). Fix that before you start worrying about counting the downloads. – Marc B Mar 18 '14 at 19:44
  • @MarcB thanks but i do not need to worry about sql injections as this is just a test website and am trying to get the functions working, any extra help? –  Mar 18 '14 at 19:51

1 Answers1

2

The download link would point to a php file, such as download.php?id=123 -- this file would then take the ID and check the downloads database. If the ID exists, you run a query such as UPDATE files SET downloads = downloads + 1 WHERE id = 123.

Afterwards, you set the headers using header() to set content-type. Then use readfile().

See How to force file download with PHP on how to set headers and force a download.

Cheers!

Community
  • 1
  • 1
Rob W
  • 9,134
  • 1
  • 30
  • 50
  • ...making sure to use prepared statements/PDO. Doing `download.php?id=123'` could open up a can of worms ;-) – Funk Forty Niner Mar 18 '14 at 19:31
  • Hey, thanks for your answer, i have added my php file code which contains most of what you said but i have tried the update queries but still nothing, am i missing something? –  Mar 18 '14 at 19:45
  • 1) You should remove the excess spaces before the first ` – Rob W Mar 18 '14 at 19:49
  • @HalfCrazed the ids are definitely integers and yes the file download does work lol, is this the code i should put into the //get the row area then? –  Mar 18 '14 at 20:08
  • @HalfCrazed $sql = "UPDATE files SET count=count+1 WHERE id='$id'"; –  Mar 18 '14 at 20:08
  • Yes, you'll need to form the query, then execute it. After the execution, you offer the file for download. – Rob W Mar 18 '14 at 20:10
  • @HalfCrazed Thanks for your help! Sorry for the late reply i have been on holiday, It now works thankfully, however I am trying to restrict the amount the count increments to by session, so the count only increments once per file stopping people constantly downloading to boost their stats. I need to do this via publication ID as opposed to webpage in the session, any ideas? –  Mar 27 '14 at 19:19
  • Then you should probably have a child table, such as `download_log` or whatever, then have the rows `download_id, download_date, ip` .. then you need to have logic in your code that queries this table and checks the date (or timeframe). If there's no row, add it and offer the download. If there is a row that matches your criteria (such as X amount of downloads in Y timeframe) then you deny the file download and show an error message of some sort. – Rob W Mar 28 '14 at 14:04