Cómo configurar un contador de visitas de sitio web con Redis y PHP en Ubuntu 20.04

El autor seleccionó la Fundación Apache Software para recibir una donación como parte del programa Write for DOnations.

Introducción

A hit counter is an application that records and indicates the number of visits your web page has received. The counter starts from 1 and is incremented once every time a web page is visited.

Para llevar un registro de las visitas, la aplicación de contador de visitas requiere una forma de base de datos. Si bien los sistemas de gestión de bases de datos basados en disco como MySQL pueden funcionar, una base de datos en memoria es mejor en cuanto a velocidad, rendimiento, escalabilidad, simplicidad y facilidad de uso. Aquí es donde entra en juego el servidor Redis. Redis almacena datos en la RAM de tu computadora en lugar de acceder al disco cada vez que se realiza una operación de entrada/salida. Esto aumenta significativamente el rendimiento.

Para realizar un seguimiento de las visitas a tu sitio, necesitas un mapa de hash de Redis. Esta es una estructura de datos que implementa un par clave-valor. Un mapa de hash proporciona una tabla hash que asigna claves a valores. Una vez que un usuario visita tu página web, creas una clave basada en su dirección IP pública o nombre de usuario (para usuarios autenticados), y luego inicializas sus visitas totales a un valor de 1. Luego, cada vez que el usuario vuelva a visitar tu página web, verificas sus visitas totales en el mapa de hash de Redis según su dirección IP/nombre de usuario e incrementas el valor.

En esta guía, configurarás un contador de visitas de sitio web con Redis y PHP en tu servidor Ubuntu 20.04. Los scripts de PHP en esta guía utilizan las direcciones IP públicas de los visitantes para realizar un seguimiento de sus visitas.

Requisitos previos

Para seguir esta guía, asegúrate de tener lo siguiente:

Paso 1 — Instalación de la extensión PHP Redis

En este paso, instalarás una extensión de Redis que permite a PHP comunicarse con el servidor Redis. También crearás una página web de prueba que implementa el mapa hash de Redis para rastrear las visitas web.

Antes de instalar la extensión de Redis, actualiza el índice de información de paquetes de Ubuntu:

  1. sudo apt update

Luego, ejecuta el siguiente comando para instalar php-redis. La extensión proporciona una API para comunicarse con el almacén de datos clave-valor del servidor Redis:

  1. sudo apt install -y php-redis

Reinicia Apache para cargar la nueva extensión:

  1. sudo systemctl restart apache2

Ahora has instalado una extensión de PHP que se comunica con tu servidor Redis. A continuación, crearás una página web test.php en el directorio raíz del servidor web Apache. Este es solo un archivo de muestra que los visitantes solicitan cuando visitan tu sitio web con un navegador. En el fondo, el archivo de página test.php carga un script hit_counter.php que crearás más tarde para rastrear las visitas a la página utilizando el servidor Redis.

En un escenario real, tu sitio web podría tener decenas o incluso cientos de páginas web. Para esta guía, configurarás una sola página web con fines de demostración.

En tu ventana de terminal, usa nano para crear un nuevo archivo test.php en el directorio raíz de tu servidor web /var/www/html/:

  1. sudo nano /var/www/html/test.php

Luego, introduce la siguiente información en el archivo test.php:

/var/www/html/test.php
<?php
  require_once 'hit_counter.php';
?>

<!DOCTYPE html>
<html>

  <head>
    <title>Sample Test Page</title>
  </head>

  <body>
    <h1>Sample test page</h1>
    <p>This is a sample test page.</p>
  </body>

</html>

Guarda y cierra el archivo cuando hayas terminado de editar. En este paso, has creado una página web HTML simple que carga un archivo hit_counter.php cuando se visita. A continuación, programarás el archivo hit_counter.php para rastrear las visitas a la página de prueba.

Paso 2 — Creación de un Script de Contador de Visitas de Redis

Cuando trabajas en un entorno de producción, es muy convencional separar archivos PHP reutilizables. Esto te permite implementar la lógica en estos archivos en diferentes partes del proyecto simplemente incluyendo sus rutas en lugar de copiar y pegar el código. Esto hace que el mantenimiento sea más fácil, ya que solo necesitas editar un solo archivo en caso de que necesites cambiar la lógica. Esto te ahorra mucho tiempo.

Vas a aplicar la misma estrategia en esta guía. Crearás un único archivo hit_counter.php que podrás incluir en cualquier página web que requiera el seguimiento de visitantes.

En este archivo, usarás la biblioteca php-redis para conectarte al servidor Redis desde PHP. Luego, crearás un mapa hash de Redis para almacenar el número de visitas que un visitante ha realizado en tu sitio web. Utilizarás las direcciones IP únicas de los visitantes como claves de Redis para distinguir el número de visitas de cada visitante en el servidor Redis.

En tu ventana de terminal, abre un nuevo archivo hit_counter.php usando nano con fines de edición:

  1. sudo nano /var/www/html/hit_counter.php

Con el archivo hit_counter.php ahora creado, abre una nueva etiqueta PHP <?php. Luego, dentro de un bloque try {, ingresa el siguiente código para conectarte a tu servidor Redis local en el puerto 6379. Reemplaza EXAMPLE_PASSWORD con la contraseña de autenticación para el servidor Redis:

/var/www/html/hit_counter.php

<?php

    try {

        $redis = new Redis();
        $redis->connect('127.0.0.1', 6379);
        $redis->auth('EXAMPLE_PASSWORD');

A continuación, asigna un nombre al mapa hash de Redis ($siteVisitsMap) a tu elección. Esta guía utiliza siteStats con fines de demostración:

/var/www/html/hit_counter.php

        $siteVisitsMap = 'siteStats';

Después de definir el mapa hash de Redis, ahora inicializarás una clave Redis vacía ($visitorHashKey). Luego, lo poblarás con las direcciones IP de los visitantes. Utilizarás el valor de la variable $visitorHashKey para identificar de manera única a cada visitante que solicite tu página web:

/var/www/html/hit_counter.php


        $visitorHashKey = '';           

        if (!empty($_SERVER['HTTP_CLIENT_IP'])) {

            $visitorHashKey = $_SERVER['HTTP_CLIENT_IP'];

        } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {

            $visitorHashKey = $_SERVER['HTTP_X_FORWARDED_FOR'];

        } else {

            $visitorHashKey = $_SERVER['REMOTE_ADDR'];
        }

En este código, estás utilizando la declaración PHP if para determinar la dirección IP del visitante comprobando si las variables $_SERVER['HTTP_CLIENT_IP'], $_SERVER['HTTP_X_FORWARDED_FOR'] o $_SERVER['REMOTE_ADDR'] están pobladas.

Siguiendo esto, inicializa una variable $totalVisits para almacenar las visitas totales para cada dirección IP y asígnale un valor de 0. Luego, utiliza las declaraciones PHP if (...) {...} else {...} y $redis->hExists($siteVisitsMap, $visitorHashKey) para verificar si la dirección IP tiene alguna entrada en el servidor Redis.

Usarás la declaración if ($redis->hExists($siteVisitsMap, $visitorHashKey)) {...} para verificar si un $visitorHashKey existe en un mapa llamado $siteVisitsMap.

En caso de que el mapa y la clave con la dirección IP nombrada existan en el servidor Redis, recupéralos con la instrucción $visitorData = $redis->hMget($siteVisitsMap, array($visitorHashKey)); y usa $totalVisits = $visitorData[$visitorHashKey] + 1; para incrementar la variable $totalVisits. Estás utilizando la instrucción $redis->hMget para obtener datos de recuento de visitas asociados con una dirección IP. La función hMget acepta el nombre de tu mapa ($siteVisitsMap) y una matriz de las claves que deseas recuperar del servidor Redis. En este caso, solo tienes una clave ($visitorHashKey), pero debes convertirla en una matriz usando la instrucción array($visitorHashKey).

En caso de que tu script encuentre la dirección IP por primera vez, establece la variable $totalVisits en 1. Finalmente, usa $redis->hSet($siteVisitsMap, $visitorHashKey, $totalVisits); para establecer el valor del $visitorHashKey de acuerdo con los resultados de la declaración if (...) {...} else {...} anterior. La instrucción $redis->hSet($siteVisitsMap, $visitorHashKey, $totalVisits) crea un mapa hash $siteVisitsMap en el servidor Redis con una clave llamada $visitorHashKey con un valor de $totalVisits.

Luego, da la bienvenida al visitante imprimiendo el total de visitas y cierra el bloque } catch (...) {...}:

/var/www/html/hit_counter.php

        $totalVisits = 0;

        if ($redis->hExists($siteVisitsMap, $visitorHashKey)) {

            $visitorData = $redis->hMget($siteVisitsMap, array($visitorHashKey));
            $totalVisits = $visitorData[$visitorHashKey] + 1;

        } else {

            $totalVisits = 1;

        }

        $redis->hSet($siteVisitsMap, $visitorHashKey, $totalVisits);

        echo "Welcome, you've visited this page " .  $totalVisits . " times\n";

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

Una vez completado, tu archivo /var/www/html/hit_counter.php debería ser similar al siguiente código:

/var/www/html/hit_counter.php

<?php

    try {

        $redis = new Redis();
        $redis->connect('127.0.0.1', 6379);
        $redis->auth('EXAMPLE_PASSWORD');

        $siteVisitsMap  = 'siteStats';
        $visitorHashKey = '';           

        if (!empty($_SERVER['HTTP_CLIENT_IP'])) {

           $visitorHashKey = $_SERVER['HTTP_CLIENT_IP'];

        } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {

           $visitorHashKey = $_SERVER['HTTP_X_FORWARDED_FOR'];

        } else {

           $visitorHashKey = $_SERVER['REMOTE_ADDR'];
        }
      
        $totalVisits = 0;

        if ($redis->hExists($siteVisitsMap, $visitorHashKey)) {

            $visitorData = $redis->hMget($siteVisitsMap,  array($visitorHashKey));
            $totalVisits = $visitorData[$visitorHashKey] + 1;

        } else {

            $totalVisits = 1;

        }

        $redis->hSet($siteVisitsMap, $visitorHashKey, $totalVisits);

        echo "Welcome, you've visited this page " .  $totalVisits . " times\n";

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

Guarde y cierre el archivo cuando haya terminado de editar. Ahora ha codificado un script hit_counter.php. A continuación, creará otro script PHP que genere un informe a partir de los datos recopilados en el mapa hash de Redis.

Paso 3 — Creación de un Script de Informe de Estadísticas del Sitio

Una vez que haya recopilado datos en un mapa hash de Redis, puede que no tenga sentido si no puede recuperar y representar la información en un informe. En este paso, creará un informe de registro para mostrar los diferentes visitantes del sitio y las visitas totales que han realizado en la página web de prueba.

Para crear el script del informe de registro, ejecute nano en la ventana de su terminal y cree un nuevo archivo /var/www/html/log_report.php:

  1. sudo nano /var/www/html/log_report.php

Luego, ingrese la siguiente información en el archivo. Reemplace EXAMPLE_PASSWORD con la contraseña correcta para el servidor Redis:

/var/www/html/log.php

<!DOCTYPE html>
<html>

  <head>
    <title>Site Visits Report</title>
  </head>

  <body>

      <h1>Site Visits Report</h1>

      <table border = '1'>
        <tr>
          <th>No.</th>
          <th>Visitor</th>
          <th>Total Visits</th>
        </tr>

        <?php

            try {

                $redis = new Redis();
                $redis->connect('127.0.0.1', 6379);
                $redis->auth('EXAMPLE_PASSWORD');

                $siteVisitsMap = 'siteStats';                          

                $siteStats = $redis->HGETALL($siteVisitsMap);

                $i = 1; 

                foreach ($siteStats as $visitor => $totalVisits) {

                    echo "<tr>";
                      echo "<td align = 'left'>"   . $i . "."     . "</td>";
                      echo "<td align = 'left'>"   . $visitor     . "</td>";
                      echo "<td align = 'right'>"  . $totalVisits . "</td>";
                    echo "</tr>";
                    
                    $i++;
                }

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

        ?>

      </table>
  </body>

</html>

Guarda y cierra el archivo cuando hayas terminado de editar. En el script anterior, te estás conectando al servidor Redis y estás utilizando la declaración $redis->HGETALL($siteVisitsMap); para recuperar el mapa hash de las visitas a tu página web. Luego, estás utilizando el bucle foreach ($siteStats as $visitor => $totalVisits) { de PHP para recorrer y mostrar las direcciones IP de los visitantes y el número de visitas que han realizado a tu sitio. Estás utilizando el comando Redis HGETALL para recuperar todos los campos (direcciones IP) y valores (visitas totales por cada dirección IP) del mapa siteVisitsMap.

Ahora tienes una página de prueba, un script de contador de visitas y una página de informe para verificar las estadísticas de tu sitio. A continuación, probarás las funcionalidades de tu contador de visitas y verás si todo funciona.

Paso 4 — Probando el Contador de Visitas de Redis

En este paso, probarás toda la lógica de tu contador de visitas. Ve a la siguiente URL en tu navegador web. Reemplaza tu-dirección-IP-del-servidor con la dirección IP pública o el nombre de dominio de tu servidor.

http://your-server-IP/test.php

Actualiza la página varias veces usando diferentes dispositivos para generar suficientes estadísticas. Después de cada visita, deberías recibir la siguiente salida.

A continuación, visita la siguiente URL para obtener tu informe de visitas al sitio mostrado en una tabla HTML

http://your-server-IP/log_report.php

Ahora deberías ver un informe similar a la siguiente salida.

El contador de visitas ahora funciona como se esperaba.

Conclusión

En esta guía, has configurado un contador de visitas de sitio web con Redis y PHP en tu servidor Ubuntu 20.04.

Como puedes ver en el código fuente de muestra en esta guía, Redis proporciona métodos más limpios para crear y actualizar mapas hash.

Como se mencionó al principio de esta guía, el uso de un sistema de gestión de bases de datos relacionales aún puede funcionar, pero escribirás un montón de código para insertar y actualizar datos en las tablas subyacentes. Además, las bases de datos basadas en disco pueden experimentar problemas de escalabilidad cuando tu sitio crezca.

Para obtener más información sobre el uso de la base de datos en memoria Redis, sigue las guías a continuación:

Source:
https://www.digitalocean.com/community/tutorials/how-to-set-up-a-website-hit-counter-with-redis-and-php-on-ubuntu-20-04