Q:

php- How to record which user clicked on a link to download a file

I am trying to record which user has downloaded a file in an SQL database. Every file uploaded has its path displayed as a link on the site, allowing the user to download that file from a folder on the server. I am having trouble figuring out how to record which user has downloaded a file though. How can I query my database that a specific user has clicked a specific link? I have the user id stored as a session variable, so possessing the user id is not a problem. My code to display the downloadable files are as follows:
<?php
      session_start();

        $servername = "localhost";
            $username = "root";
            $password = "";
            $dbname = "project_website1";
            $user_id = $_SESSION[ 'user_id' ];

        // Create connection
            $conn = new mysqli($servername, $username, $password, $dbname);
        // Check connection
            if ($conn->connect_error) {
                die("Connection failed: " . $conn->connect_error);
            } 

            $sql = "SELECT task_id,file, description, title, deadline_claim FROM task";
                $result = $conn->query($sql);

            if ($result->num_rows > 0) {
                    echo "<table><tr><th>TITLE</th><th>DESCRIPTION</th><th>DEADLINE</th><th>TASK</th></tr>";
                // output data of each row
            while($row = $result->fetch_assoc()) {
                    //echo "<tr><td>" . $row["file"]. "</td><td>" . $row["title"]. "</td><td>" . $row["deadline_claim"]. "</td></tr>";
                    echo "<tr><td>".$row["title"]."</td><td>".$row["description"]."</td><td>".$row["deadline_claim"]."<td><a href='" .$row["file"]. "'>CLAIM</td></a>";

                }
                    echo "</table>";
            } else {
                    echo "0 results";
        }

            $conn->close();
?>  

A:

If you want it to be purely PHP, as suggested, just use the task_id of the row in your file table. Here is a basic example, noting I have reorganized some elements to help keep your script cleaner. Ideally you will want to keep the functions on a different page and include them when you want to use them. Keeps your script cleaner and more easily readable.:
# Better to make a function/class to do your database so you can reuse it easily.
function getConnection( $servername = "localhost", $username = "root",$password = "",$dbname = "project_website1")
    {
        # Create connection
        $conn = new mysqli($servername, $username, $password, $dbname);
        # Check connection
        if ($conn->connect_error) {
            die("Connection failed: " . $conn->connect_error);
        }

        return $conn;
    }

# Make a task retrieval function/class that will deal with getting the rows only
function getTasks($con,$id=false)
    {
        $sql = "SELECT task_id,file, description, title, deadline_claim FROM task";
        # I am assuming your task_id values are numeric, so I don't sanitize here
        if ($id) {
            if(is_numeric($id))
                # Append sql
                $sql .= " WHERE `task_id` = '{$id}'";
            else
                # You shouldn't get this exception unless someone is trying to
                # Manually put something else here via injection attempt
                throw new Exception("Id must be numeric!");
        }

        $result = $con->query($sql);

        if ($result->num_rows > 0) {
            while($row = $result->fetch_assoc()) {
                $new[] = $row;
            }
        }
        # Send back rows
        return (!empty($new))? $new : array();
    }

# This is more of a listener, but it will cut down on some redundant check-script
function getFileId()
    {
        if(!empty($_GET['file']) && is_numeric($_GET['file']))
            return (!empty($_GET['action']) && $_GET['action'] == 'download')? $_GET['file'] : false;

        return false;
    }

# As noted, you would include the functions here...
session_start();
# Get session id
$user_id = $_SESSION[ 'user_id' ];
# Get the database connection
$conn    = getConnection();
# If there is a download
if(!empty($_GET['action']) && $_GET['action'] == 'download') {
    # Get the tasks, could be based on id or all
    $tasks   = getTasks($conn, getFileId());
    # Save to the database, make sure that you either bind parameters, or
    # check that the values are numeric (if they are supposed to be numeric)
    # Also check the count here first for the task before inserting. Make an error if not.
    # Usually means user is trying to manipulate the request
    $conn->query("INSERT into downloads (`fileid`,`userid`) VALUES('".$tasks[0]['task_id']."','".$user_id."')");
    # Download file. If you want to obfuscate the file, you would use
    # download headers instead:
    # http://php.net/manual/en/function.readfile.php
    header('Location: '.$tasks[0]['file']);
    # Stop execution
    exit;
}

# Get all tasks
$tasks   = getTasks($conn);
# If there are rows, output them
if (!empty($tasks)) {
    echo "<table><tr><th>TITLE</th><th>DESCRIPTION</th><th>DEADLINE</th><th>TASK</th></tr>";
    # output data of each row
    foreach($tasks as $row) {
        echo "<tr><td>".$row["title"]."</td><td>".$row["description"]."</td><td>".$row["deadline_claim"]."<td><a href='?action=download&file=" .$row["task_id"]. "'>CLAIM</td></a>";
    }
    echo "</table>";
} else {
    echo "0 results";
}

$conn->close();

Final note, I have not tested this, so be aware of that.

