User Tools

Site Tools


a_simple_php_sqlite_download_counter

This is an old revision of the document!


A Simple PHP/SQLite Download Counter

Summary

If you host downloadable content on SDF, you may want to get an idea of how many people have downloaded things and which are the most popular. In this tutorial, I will focus on an example of tracking PDF formatted ebooks. After completing this tutorial, you should be able to modify things to suit your needs, even if your downloads are not ebooks. You will need to have PHP access to do this, so check your membership level before you get started.

The Download Script

For the impatient and the PHP gurus in the audience, I will show the entire script first. After that, I'll pick it apart and explain each section.

<?php

  // Set the location holding the download content.
  $content_dir = basename(__FILE__) . "/download";

  // The query string passed indicates the filename.
  if (isset($_SERVER['QUERY_STRING'])) {
    $file = rawurldecode($_SERVER['QUERY_STRING']);
    $path = $content_dir . DIRECTORY_SEPARATOR . $file;

    // Deliver the file if it exists, otherwise error.
    if (file_exists($path)) {
      header("Content-type: application/pdf");
      header("Cache-Control: no-store, no-cache");
      header("Content-Disposition: inline; filename=\"$file\"");
      echo file_get_contents($path);

      // Record the download in the hit count database.
      $pdo = new PDO("sqlite:download.sl3");
      if ($pdo) {
        $create = "CREATE TABLE IF NOT EXISTS tally (datetime VARCHAR(32), filename VARCHAR(256))";
        $pdo->exec($create);
        $insert = "INSERT INTO tally (datetime, filename) VALUES (datetime('now'), :filename)";
        $prepared_sql = $pdo->prepare($insert);
        $prepared_sql->bindValue("filename", $file);
        $prepared_sql->execute();
      }
    }
    else {
      http_response_code(404);
      header("Content-type: text/plain");
      header("Cache-Control: no-store, no-cache");
      echo "404: Not Found";
    }
  }

?>

Explanation of Parts

For a better understanding of how this works, I'll dissect the parts of the script one by one and explain each bit.

Where to Find the Files

First, there is the $content_dir variable.

  // Set the location holding the download content.
  $content_dir = basename(__FILE__) . "/download";

This needs to be set to where the downloadable files are kept. The way things are set up by default assumes you have a directory hierarchy that looks like this:

html/
|-- download.php
|-- download/
    |-- ebook.pdf

In other words, your downloadable content is all kept in a directory called download and it is a subdirectory residing next to the download.php script we're putting together.

$content_dir = basename(__FILE__) . "/download";

FILE in PHP means the filesystem path to the PHP script being executed. This is not the URL path, but the filesystem path. So it will not be http://login.sdf.org/download. It will look more like /sdf/arpa/tz/l/login/html and using the dot concatenation operator will tack /download to the end of it.

So now you know where to store you content and what to change if it's located somewhere else.

Knowing What's Being Requsted

Next, there is the section that decodes the query string.

  // The query string passed indicates the filename.
  if (isset($_SERVER['QUERY_STRING'])) {
    $file = rawurldecode($_SERVER['QUERY_STRING']);
    $path = $content_dir . DIRECTORY_SEPARATOR . $file;
a_simple_php_sqlite_download_counter.1593289203.txt.gz · Last modified: 2020/06/27 20:20 by waxphilosophic