如何在 Ubuntu 20.04 上使用 Redis 和 PHP 设置网站点击计数器

作者选择了 Apache Software Foundation作为 Write for Donations计划的一部分接受捐款。

介绍

攻击计数是一个应用程序,记录并表示您的网页接收的访问次数. 计数从1开始,每次访问网页时增加一次。

为了跟踪访问,攻击计数应用程序需要一种形式的数据库。虽然基于磁盘的数据库管理系统如MySQL可以工作,但内存数据库在速度,性能,可扩展性,简单性和易用性方面更好。

要跟踪您的网站访问,您需要一个 Redis 哈希地图. 这是一个数据结构,实现一个关键值对。 哈希地图提供了一个哈希表,将密钥绘制为值。 一旦用户访问了您的网页,您将基于他们的公共 IP 地址或用户名创建一个密钥(对于已验证的用户),然后将他们的访问总数初始化为 1。

在本指南中,您将在 Ubuntu 20.04 服务器上设置 Redis 和 PHP 的网站攻击计,本指南中的 PHP 脚本使用访问者的公共 IP 地址来跟踪访问。

前提条件

要跟随这个指南,请确保您有以下内容:

使用Ubuntu 20.04 的初始服务器设置( )指南。 具有sudo特权的非根用户。 遵循我们的 [How To Create a New Sudo-enabled User on Ubuntu 20.04 Quickstart指南来设置一个非根 sudo 用户。

步骤1:安装 PHP Redis 扩展

在此步骤中,您将安装一个Redis扩展,允许PHP与Redis服务器交谈,您还将创建一个测试网页,该网页实现Redis哈希地图来跟踪网页访问。

在安装 Redis 扩展之前,请更新您的 Ubuntu 包信息索引:

1sudo apt update

然后运行以下命令来安装php-redis. 该扩展提供了与 Redis 服务器密钥值存储进行通信的 API:

1sudo apt install -y php-redis

重新启动 Apache 以加载新扩展:

1sudo systemctl restart apache2

您现在已经安装了一个PHP扩展,它会与您的Redis服务器进行交谈。接下来,您将创建一个test.php网页,在Apache网页服务器的根目录下。这只是访问者在使用浏览器访问您的网站时请求的样本文件。在封面下,test.php网页文件将加载一个hit_counter.php脚本,您将后来创建以跟踪使用Redis服务器的网页访问。

在真实情况下,您的网站可能有数十个甚至数百个网页,对于本指南,您将为演示目的设置一个单一网页。

在您的终端窗口中,使用nano创建一个新的test.php文件,在您的 Web 服务器的 root 目录中:

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

然后,在test.php文件中输入以下信息:

 1[label /var/www/html/test.php]
 2<?php
 3  require_once 'hit_counter.php';
 4?>
 5
 6<!DOCTYPE html>
 7<html>
 8
 9  <head>
10    <title>Sample Test Page</title>
11  </head>
12
13  <body>
14    <h1>Sample test page</h1>
15    <p>This is a sample test page.</p>
16  </body>
17
18</html>

当你完成编辑时,保存并关闭文件. 在这个步骤中,你创建了一个简单的HTML网页,在访问时加载一个hit_counter.php文件。

步骤 2 — 创建一个 Redis 打击反对脚本

在生产环境中工作时,分离可重复使用的PHP文件非常常见,这允许您将这些文件中的逻辑应用于项目的不同部分,只需将它们的路径列入,而不是复制代码。

您将创建一个单一的hit_counter.php文件,您可以在任何需要访问者跟踪的网页上添加。

在此文件中,您将使用php-redis库连接到PHP的Redis服务器,然后,您将创建一个Redis哈希地图,以存储访问者访问您的网站的次数。

在您的终端窗口中,打开一个新的 hit_counter.php 文件,使用 nano 进行编辑:

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

使用现在创建的 hit_counter.php 文件,打开一个新的 PHP 标签 <?php. 然后,在一个 try { 块中输入以下代码以连接到您的本地 Redis 服务器在端口 6379. 用 Redis 服务器的身份验证密码代替 `EXAMPLE_PASSWORD:

1[label /var/www/html/hit_counter.php]
2
3<?php
4
5    try {
6
7        $redis = new Redis();
8        $redis->connect('127.0.0.1', 6379);
9        $redis->auth('EXAMPLE_PASSWORD');

接下来,给 Redis 哈希地图(‘$siteVisitsMap’)一个你选择的名称.本指南使用‘siteStats’进行演示:

1[label /var/www/html/hit_counter.php]
2
3        $siteVisitsMap = 'siteStats';

定义 Redis 哈希地图后,您现在将初始化一个空的 Redis 密钥 (‘$visitorHashKey’)。

 1[label /var/www/html/hit_counter.php]
 2
 3        $visitorHashKey = '';           
 4
 5        if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
 6
 7            $visitorHashKey = $_SERVER['HTTP_CLIENT_IP'];
 8
 9        } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
10
11            $visitorHashKey = $_SERVER['HTTP_X_FORWARDED_FOR'];
12
13        } else {
14
15            $visitorHashKey = $_SERVER['REMOTE_ADDR'];
16        }

在此代码中,您正在使用PHP的如果语句来确定访问者的IP地址,通过检查$_SERVER[‘HTTP_CLIENT_IP’]$_SERVER[‘HTTP_X_FORWARDED_FOR’]$_SERVER[‘REMOTE_ADDR’]变量是否包含。

接下来,初始化一个$totalVisits变量来存储每个IP地址的总访问量,并为其分配一个值 0。然后,使用PHPif (...) {...} else {...}$redis->hExists($siteVisitsMap, $visitorHashKey)的陈述来检查IP地址是否在Redis服务器中有任何条目。

您将使用if ($redis->hExists($siteVisitsMap, $visitorHashKey)) {...} 语句来检查在名为$siteVisitsMap的地图上是否存在$visitorHashKey

如果在 Redis 服务器中存在名为 IP 地址的地图和密钥,请以声明 $visitorData = $redis->hMget($siteVisitsMap, array($visitorHashKey));和使用 $totalVisits = $visitorData[$visitorHashKey] + 1;来增加 $totalVisits 变量。您正在使用 $redis->hMget 声明来获取与 IP 地址相关的击数数据。 hMget 函数接受您的地图($siteVisitsMap)的名称和您想要从 Redis 服务器中获取的密钥的数组。在这种情况下,您只有一个密钥(`$visitorHashKey

如果您的脚本第一次遇到 IP 地址,请将$totalVisits变量设置为 1. 最后,使用$redis->hSet($siteVisitsMap, $visitorHashKey, $totalVisits);以根据前面的if (...) {...} else {...}声明的结果设置$visitorHashKey值。

接下来,通过回响总参观,欢迎访问者,并关闭捕获 (...) {...}块:

 1[label /var/www/html/hit_counter.php]
 2
 3        $totalVisits = 0;
 4
 5        if ($redis->hExists($siteVisitsMap, $visitorHashKey)) {
 6
 7            $visitorData = $redis->hMget($siteVisitsMap, array($visitorHashKey));
 8            $totalVisits = $visitorData[$visitorHashKey] + 1;
 9
10        } else {
11
12            $totalVisits = 1;
13
14        }
15
16        $redis->hSet($siteVisitsMap, $visitorHashKey, $totalVisits);
17
18        echo "Welcome, you've visited this page " .  $totalVisits . " times\n";
19
20    } catch (Exception $e) {
21        echo $e->getMessage();
22    }

一旦完成,您的 /var/www/html/hit_counter.php 文件应该与以下代码相似:

 1[label /var/www/html/hit_counter.php]
 2
 3<?php
 4
 5    try {
 6
 7        $redis = new Redis();
 8        $redis->connect('127.0.0.1', 6379);
 9        $redis->auth('EXAMPLE_PASSWORD');
10
11        $siteVisitsMap  = 'siteStats';
12        $visitorHashKey = '';           
13
14        if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
15
16           $visitorHashKey = $_SERVER['HTTP_CLIENT_IP'];
17
18        } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
19
20           $visitorHashKey = $_SERVER['HTTP_X_FORWARDED_FOR'];
21
22        } else {
23
24           $visitorHashKey = $_SERVER['REMOTE_ADDR'];
25        }
26
27        $totalVisits = 0;
28
29        if ($redis->hExists($siteVisitsMap, $visitorHashKey)) {
30
31            $visitorData = $redis->hMget($siteVisitsMap, array($visitorHashKey));
32            $totalVisits = $visitorData[$visitorHashKey] + 1;
33
34        } else {
35
36            $totalVisits = 1;
37
38        }
39
40        $redis->hSet($siteVisitsMap, $visitorHashKey, $totalVisits);
41
42        echo "Welcome, you've visited this page " .  $totalVisits . " times\n";
43
44    } catch (Exception $e) {
45        echo $e->getMessage();
46    }

当你完成编辑时,保存并关闭文件. 你现在编码了一个hit_counter.php脚本. 接下来,你将创建另一个PHP脚本,从Redis哈希地图中收集的数据中生成报告。

步骤 3 — 创建网站统计报告脚本

一旦您在 Redis 哈希地图中收集了数据,如果您无法在报告中获取和表示信息,则可能没有任何意义。

要创建日志报告脚本,在终端窗口运行nano,并创建一个新的/var/www/html/log_report.php文件:

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

然后,将下面的信息输入到文件中,以对 Redis 服务器的正确密码代替 EXAMPLE_PASSWORD:

 1[label /var/www/html/log.php]
 2
 3<!DOCTYPE html>
 4<html>
 5
 6  <head>
 7    <title>Site Visits Report</title>
 8  </head>
 9
10  <body>
11
12      <h1>Site Visits Report</h1>
13
14      <table border = '1'>
15        <tr>
16          <th>No.</th>
17          <th>Visitor</th>
18          <th>Total Visits</th>
19        </tr>
20
21        <?php
22
23            try {
24
25                $redis = new Redis();
26                $redis->connect('127.0.0.1', 6379);
27                $redis->auth('EXAMPLE_PASSWORD');
28
29                $siteVisitsMap = 'siteStats';                          
30
31                $siteStats = $redis->HGETALL($siteVisitsMap);
32
33                $i = 1; 
34
35                foreach ($siteStats as $visitor => $totalVisits) {
36
37                    echo "<tr>";
38                      echo "<td align = 'left'>"   . $i . "."     . "</td>";
39                      echo "<td align = 'left'>"   . $visitor     . "</td>";
40                      echo "<td align = 'right'>"  . $totalVisits . "</td>";
41                    echo "</tr>";
42
43                    $i++;
44                }
45
46            } catch (Exception $e) {
47                echo $e->getMessage();
48            }
49
50        ?>
51
52      </table>
53  </body>
54
55</html>

在上面的脚本中,你正在连接到Redis服务器,你正在使用声明$redis->HGETALL($siteVisitsMap);来获取你的网页访问的哈希地图。然后,你正在使用PHPforeach($siteStats as $visitor => $totalVisits) {声明来环绕和显示访问者的IP地址和他们对你的网站的访问数量。你正在使用RedisHGETALL命令来获取所有字段(IP地址)和值(每个IP地址的总访问)从网站VisitsMap地图。

你现在有一个测试页面,一个攻击计数脚本和一个报告页面来检查你的网站统计数据,接下来,你会测试你的攻击计数的功能,看看一切是否奏效。

步骤 4 – 测试 Redis 打击计数器

在此步骤中,您将测试您的打击计的整个逻辑。在您的 Web 浏览器上导航到下面的 URL。用您的服务器的公共 IP 地址或域名替换您的服务器-IP

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

使用不同的设备更新页面几次,以生成足够的统计数据. 每次访问后,您应该收到以下输出。

others/a5ab45e33a0bd5ebee4b897b3dec1517_test.png

接下来,访问以下URL,以在HTML表中显示您的网站访问报告

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

您现在应该看到类似于下面的输出的报告。

others/2b70aba22f8917652ffb72447c7934db_report.png

您的打击计现在按预期运作。

结论

在本指南中,您已在 Ubuntu 20.04 服务器上设置了使用 Redis 和 PHP 的网站攻击计数。

正如您可以从本指南的样本源代码中看到的,Redis为创建和更新哈希地图提供了更清洁的方法。

正如本指南开始时所提到的,使用关系式数据库管理系统可能仍然可以工作,但您将编写大量代码来插入和更新底层表中的数据。

有关使用 Redis 内存数据库的更多信息,请遵循下面的指南:

Published At
Categories with 技术
comments powered by Disqus