Create a Hit Counter with Redis Hash Map and PHP on Ubuntu 20.04

Updated on February 20, 2021
Create a Hit Counter with Redis Hash Map and PHP on Ubuntu 20.04  header image

Introduction

A Redis hash map is a data type that stores key-pair values as an associative array. By using Redis hash tables, you can benefit from fast lookups and flexible keys. These advantages make Redis the perfect NoSQL database for creating a hit counter for your applications or websites. The hit counter stores the number of visits made to a web resource in your server. Because Redis is an in-memory database, it is several times faster than even the fastest SSD in the market today and is suitable for this job.

You'll set up a web counter on Ubuntu 20.04 using a Redis hash map in this guide. When a PHP web resource on your server receives a visit, Redis will increment a counter based on each visitor's IP address. You'll also create a human-readable report to display hit counts for each user making visits to the resource on your server.

Prerequisites

This guide requires:

Install php-redis Extension

To begin, SSH to your server and install the php-redis library. This is an extension that allows you to use the Redis functionalities within the PHP code.

$ sudo apt update
$ sudo apt install -y php-redis

Restart Apache to load the php-redis module.

$ sudo systemctl restart apache2

Create a Sample Web Resource File

With the php-redis library in place, you'll create a sample_resource.php file. In this file, you'll determine the visitor's IP address and log the number of visits they've made to the server.

Open the file /var/www/html/sample_resource.php using nano.

$ sudo nano /var/www/html/sample_resource.php

Add the information below into the file.

<?php
    try {
            $redis = new Redis();
            $redis->connect('127.0.0.1', 6379);

            if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
                $client_ip_address = $_SERVER['HTTP_CLIENT_IP'];
            } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
                $client_ip_address = $_SERVER['HTTP_X_FORWARDED_FOR'];
            } else {
                $client_ip_address = $_SERVER['REMOTE_ADDR'];
            }

            if ($redis->hExists('visitor_stats', $client_ip_address)) {
               $my_array = $redis->hMget("visitor_stats",  array($client_ip_address));
               $total_counts = $my_array[$client_ip_address] + 1;
            } else {
               $total_counts = 1;
            }

            $redis->hSet('visitor_stats', $client_ip_address, $total_counts);

            echo "Welcome, your IP is " . $client_ip_address . ". You've visited this page ".  $total_counts . " times\n";

        } catch (Exception $e) {
            echo $e->getMessage();
        }
?>

Once you're through with editing, save the file by pressing Ctrl + X, then Y and Enter.

The sample_resource.php explained:

  • The below code connects to your local Redis server on port 6379.

      $redis = new Redis();
      $redis->connect('127.0.0.1', 6379);
  • You've used the code snippet below to retrieve the client's IP address.

      if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
          $client_ip_address = $_SERVER['HTTP_CLIENT_IP'];
      } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
          $client_ip_address = $_SERVER['HTTP_X_FORWARDED_FOR'];
      } else {
          $client_ip_address = $_SERVER['REMOTE_ADDR'];
      }
  • In the below code, you're using the Redis hMget method to check if the hash table visitor_stats contains a key identified by the client IP address variable ($client_ip_address). If the key exists, you're retrieving the total count of visits using the statement $total_counts = $my_array[$client_ip_address] + 1;. Otherwise, in case this is the first time a client is making a visit, you're initializing the counts to 1 using the PHP code $total_counts = 1;

      if ($redis->hExists('visitor_stats', $client_ip_address)) {
          $my_array = $redis->hMget("visitor_stats",  array($client_ip_address));
          $total_counts = $my_array[$client_ip_address] + 1;
      } else {
          $total_counts = 1;
      }
  • Finally, you're setting a new value for the client visiting the web resource using the Redis hSet function. You've also used the PHP echo command to display the number of visits a client has made to the web resource.

      $redis->hSet('visitor_stats', $client_ip_address, $total_counts);
    
      echo "Welcome, your IP is " . $client_ip_address . ". You've visited this page ".  $total_counts . " times\n";

Once you've coded and closed the /var/www/html/sample_resource.php, you'll test it in the next step to see if it is working as expected.

Testing the Resource File

Use Linux curl command to request the sample_resource.php resource file that you've created.

$ curl localhost/sample_resource.php

You should see the output below showing the number of times you've visited the resource because this is the first time. The total counts should be 1.

Welcome, your IP is 127.0.0.1. You've visited this page 1 times

Display Human Readable Stats

Create a detailed report file that shows the total visits made and group them by the IP addresses. Open /var/www/html/stats.php using nano.

$ sudo nano /var/www/html/stats.php

Then, add the information below into the file.

<?php
    try {
         $redis = new Redis();
         $redis->connect('127.0.0.1', 6379);

         $stats = $redis->HGETALL("visitor_stats");

         echo "\nIP ADDRESS   VISITS\n";
         echo "---------    ------\n";

         foreach ($stats as $key => $value) {
             echo $key . "\t" . $value . "\n";
         }

        } catch (Exception $e) {
            echo $e->getMessage();
        }
?>

In the above file, you are using the Redis HGETALL function to create an array of IP addresses and their total visits registered to the Redis server. Then, you're using the PHP ...foreach(...){...}... statement to loop through the list and echo out each visitor's total visits in a new line.

After you've finished editing the file, save and close it. Next, run a curl command against the resource to get the report.

$ curl localhost/stats.php

You should see an output like the one shown below. Please note, this output may be different depending on the number of visits that you've made to the localhost/sample_resource.php page.

IP ADDRESS   VISITS
---------    ------
127.0.0.1       1
IP ADDRESS 2    1
IP ADDRESS 3    1

The output above confirms that the Redis hit counter is working as expected.

Conclusion

In this guide, you've used the Redis hash map to create a hit counter with PHP on Ubuntu 20.04. You may extend the code in this tutorial to suit your needs when implementing a web counter depending on your use-case.