Como Configurar um Contador de Acessos ao Site com Redis e PHP no Ubuntu 20.04

O autor selecionou a Apache Software Foundation para receber uma doação como parte do programa Write for DOnations.

Introdução

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 rastrear as visitas, o aplicativo de contador de acessos requer uma forma de banco de dados. Enquanto os sistemas de gerenciamento de banco de dados baseados em disco, como o MySQL, podem funcionar, um banco de dados em memória é melhor em termos de velocidade, desempenho, escalabilidade, simplicidade e facilidade de uso. É aqui que entra o servidor Redis. O Redis armazena dados na RAM do seu computador em vez de acessar o disco toda vez que você executa uma operação de entrada/saída. Isso aumenta significativamente o throughput.

Para rastrear as visitas ao seu site, você precisa de um mapa de hash do Redis. Este é uma estrutura de dados que implementa um par de chave-valor. Um mapa de hash fornece uma tabela de hash que mapeia chaves para valores. Uma vez que um usuário visita sua página da web, você cria uma chave com base em seu endereço IP público ou nome de usuário (para usuários autenticados), e então você inicializa suas visitas totais para um valor de 1. Então, toda vez que o usuário revisita sua página da web, você verifica suas visitas totais a partir do mapa de hash do Redis com base em seu endereço IP/nome de usuário e incrementa o valor.

Neste guia, você configurará um contador de acessos ao site com Redis e PHP em seu servidor Ubuntu 20.04. Os scripts PHP neste guia usam os endereços IP públicos dos visitantes para rastrear suas visitas.

Pré-requisitos

Para seguir este guia, certifique-se de ter o seguinte:

Passo 1 — Instalando a Extensão PHP Redis

Neste passo, você instalará uma extensão Redis que permite ao PHP se comunicar com o servidor Redis. Você também criará uma página web de teste que implementa o mapa de hash do Redis para rastrear visitas à web.

Antes de instalar a extensão Redis, atualize o índice de informações de pacote do Ubuntu:

  1. sudo apt update

Em seguida, execute o seguinte comando para instalar o php-redis. A extensão fornece uma API para se comunicar com o armazenamento de chave-valor do servidor Redis:

  1. sudo apt install -y php-redis

Reinicie o Apache para carregar a nova extensão:

  1. sudo systemctl restart apache2

Agora você instalou uma extensão do PHP que se comunica com o seu servidor Redis. Em seguida, você criará uma página da web test.php no diretório raiz do servidor web Apache. Este é apenas um arquivo de exemplo que os visitantes solicitam quando acessam seu site com um navegador. Nos bastidores, o arquivo da página test.php carrega um script hit_counter.php que você criará posteriormente para rastrear as visitas à página usando o servidor Redis.

Em um cenário real, seu site pode ter dezenas ou até centenas de páginas da web. Para este guia, você configurará uma única página da web para fins de demonstração.

Na janela do terminal, use o nano para criar um novo arquivo test.php no diretório raiz do seu servidor web /var/www/html/:

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

Em seguida, insira as seguintes informações no arquivo 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>

Salve e feche o arquivo quando terminar de editar. Neste passo, você criou uma página da web HTML simples que carrega um arquivo hit_counter.php quando visitado. Em seguida, você codificará o arquivo hit_counter.php para rastrear as visitas à página de teste.

Passo 2 — Criando um Script de Contador de Visitas do Redis

Quando se trabalha em um ambiente de produção, é muito convencional separar arquivos PHP reutilizáveis. Isso permite que você implemente a lógica nesses arquivos em diferentes partes do projeto apenas incluindo seus caminhos, em vez de copiar e colar o código. Isso facilita a manutenção, pois você só precisa editar um único arquivo caso precise alterar a lógica. Isso economiza muito tempo.

Você vai aplicar a mesma estratégia neste guia. Você criará um único arquivo hit_counter.php que pode incluir em qualquer página da web que exija o rastreamento de visitantes.

Neste arquivo, você usará a biblioteca php-redis para se conectar ao servidor Redis a partir do PHP. Em seguida, você criará um mapa de hash Redis para armazenar o número de visitas que um visitante fez ao seu site. Você usará os endereços IP únicos dos visitantes como chaves Redis para distinguir as contagens de visitas de cada visitante no servidor Redis.

Na janela do terminal, abra um novo arquivo hit_counter.php usando nano para fins de edição:

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

Com o arquivo hit_counter.php agora criado, abra uma nova tag PHP <?php. Em seguida, dentro de um bloco try {, insira o seguinte código para se conectar ao seu servidor Redis local na porta 6379. Substitua EXAMPLE_PASSWORD pela senha de autenticação do servidor Redis:

/var/www/html/hit_counter.php

<?php

    try {

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

Em seguida, dê um nome ao mapa de hash Redis ($siteVisitsMap) de sua escolha. Este guia usa siteStats para fins de demonstração:

/var/www/html/hit_counter.php

        $siteVisitsMap = 'siteStats';

Depois de definir o mapa de hash do Redis, agora você inicializará uma chave Redis vazia ($visitorHashKey). Em seguida, você irá populá-la com os endereços IP dos visitantes. Você usará o valor da variável $visitorHashKey para identificar de forma única cada visitante solicitando sua página da 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'];
        }

Neste código, você está usando a instrução PHP if para determinar o endereço IP do visitante verificando se as variáveis $_SERVER['HTTP_CLIENT_IP'], $_SERVER['HTTP_X_FORWARDED_FOR'] ou $_SERVER['REMOTE_ADDR'] estão populadas.

Após isso, inicialize uma variável $totalVisits para armazenar o total de visitas para cada endereço IP e atribua a ela um valor de 0. Em seguida, utilize as instruções PHP if (...) {...} else {...} e $redis->hExists($siteVisitsMap, $visitorHashKey) para verificar se o endereço IP possui alguma entrada no servidor Redis.

Você usará a instrução if ($redis->hExists($siteVisitsMap, $visitorHashKey)) {...} para verificar se um $visitorHashKey existe em um mapa chamado $siteVisitsMap.

Caso o mapa e a chave com o endereço IP nomeado existam no servidor Redis, recupere-os com a instrução $visitorData = $redis->hMget($siteVisitsMap, array($visitorHashKey)); e use $totalVisits = $visitorData[$visitorHashKey] + 1; para incrementar a variável $totalVisits. Você está utilizando a instrução $redis->hMget para obter dados de contagem de acessos associados a um endereço IP. A função hMget aceita o nome do seu mapa ($siteVisitsMap) e um array das chaves que você deseja recuperar do servidor Redis. Neste caso, você tem apenas uma chave ($visitorHashKey), mas deve convertê-la em um array usando a instrução array($visitorHashKey).

Caso o seu script encontre o endereço IP pela primeira vez, defina a variável $totalVisits como 1. Por fim, use $redis->hSet($siteVisitsMap, $visitorHashKey, $totalVisits); para definir o valor do $visitorHashKey de acordo com os resultados da declaração if (...) {...} else {...} anterior. A instrução $redis->hSet($siteVisitsMap, $visitorHashKey, $totalVisits) cria um mapa de hash $siteVisitsMap no servidor Redis com uma chave chamada $visitorHashKey e um valor de $totalVisits.

Em seguida, dê as boas-vindas ao visitante ecoando o total de visitas e feche o bloco } 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();
    }

Depois de concluído, seu arquivo /var/www/html/hit_counter.php deve ser semelhante ao seguinte 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();
    }

Salve e feche o arquivo quando terminar de editar. Você agora codificou um script hit_counter.php. Em seguida, você criará outro script PHP que gera um relatório a partir dos dados coletados no mapa hash do Redis.

Passo 3 — Criando um Script de Relatório de Estatísticas do Site

Depois de coletar dados em um mapa hash do Redis, pode não fazer sentido se você não puder recuperar e representar as informações em um relatório. Neste passo, você criará um relatório de log para mostrar os diferentes visitantes do site e as visitas totais que eles fizeram na página de teste.

Para criar o script de relatório de log, execute nano na sua janela do terminal e crie um novo arquivo /var/www/html/log_report.php:

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

Em seguida, insira as informações abaixo no arquivo. Substitua EXAMPLE_PASSWORD pela senha correta do 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>

Salve e feche o arquivo quando terminar de editar. No script acima, você está conectando ao servidor Redis e está usando a instrução $redis->HGETALL($siteVisitsMap); para recuperar o mapa de hash das visitas à sua página da web. Em seguida, você está usando o comando PHP foreach ($siteStats as $visitor => $totalVisits) { para fazer um loop e exibir os endereços IP dos visitantes e o número de visitas que fizeram ao seu site. Você está usando o comando Redis HGETALL para recuperar todos os campos (endereços IP) e valores (total de visitas para cada endereço IP) do mapa siteVisitsMap.

Agora você tem uma página de teste, um script de contador de acessos e uma página de relatório para verificar as estatísticas do seu site. Em seguida, você testará as funcionalidades do seu contador de acessos para ver se tudo funciona.

Passo 4 — Testando o Contador de Acessos do Redis

Neste passo, você testará toda a lógica do seu contador de acessos. Navegue até a seguinte URL no seu navegador da web. Substitua your-server-IP pelo endereço IP público ou nome de domínio do seu servidor.

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

Atualize a página várias vezes usando dispositivos diferentes para gerar estatísticas suficientes. Após cada visita, você deve receber a seguinte saída.

Em seguida, visite a seguinte URL para obter o relatório de visitas ao seu site exibido em uma tabela HTML

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

Agora você deve ver um relatório semelhante à seguinte saída.

Seu contador de acessos está funcionando conforme o esperado.

Conclusão

Neste guia, você configurou um contador de acessos ao site com Redis e PHP no seu servidor Ubuntu 20.04.

Como você pode ver no código-fonte de exemplo neste guia, o Redis fornece métodos mais limpos para criar e atualizar mapas de hash.

Como mencionado no início deste guia, usar um sistema de gerenciamento de banco de dados relacional ainda pode funcionar, mas você terá que escrever toneladas de código para inserir e atualizar dados nas tabelas subjacentes. Além disso, os bancos de dados baseados em disco podem enfrentar problemas de escalabilidade conforme seu site cresce.

Para obter mais informações sobre o uso do banco de dados em memória Redis, siga os guias abaixo:

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