作者選擇Apache Software Foundation作為Write for DOnations計畫的捐贈對象。
介紹
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.
為了追踪訪問次數,點擊計數器應用程序需要一種形式的數據庫。儘管基於磁盤的數據庫管理系統如MySQL可以工作,但內存數據庫在速度、性能、可擴展性、簡潔性和易用性方面更好。這就是Redis服務器發揮作用的地方。Redis將數據存儲在計算機的RAM中,而不是每次執行輸入/輸出操作時都要擊中磁盤。這顯著提高了吞吐量。
為了追踪您網站的訪問,您需要一個Redis哈希映射。這是一種實現鍵值對的數據結構。哈希映射提供了一個將鍵映射到值的哈希表。一旦用戶訪問您的網頁,您就根據他們的公共IP地址或用戶名(對於已驗證的用戶)創建一個鍵,然後將他們的總訪問次數初始化為值為1。然後,每次用戶重新訪問您的網頁時,您都可以根據他們的IP地址/用戶名從Redis哈希映射中檢查他們的總訪問次數並增加該值。
在本指南中,您將在Ubuntu 20.04服務器上使用Redis和PHP設置網站點擊計數器。本指南中的PHP腳本使用訪問者的公共IP地址來追踪他們的訪問。
先決條件
要跟隨本指南,請確保您擁有以下內容:
-
使用使用 Ubuntu 20.04 的初始伺服器設定指南配置的 Ubuntu 20.04 伺服器。
-
具有
sudo
權限的非根用戶。按照我們的在 Ubuntu 20.04 上創建新的 Sudo 啟用用戶 [快速入門]指南設置非根 sudo 用戶。 - Apache 和 PHP。要設置這些,請使用我們的在 Ubuntu 20.04 上安裝 Linux、Apache、MySQL、PHP(LAMP)堆棧的方法教程。您可以跳過第 2 步 — 安裝 MySQL和第 4 步 — 為您的網站創建虛擬主機,因為您不需要 MySQL 數據庫或虛擬主機來測試此指南。
-
Redis 服務器。閱讀我們的 在 Ubuntu 20.04 上安裝和保護 Redis [快速入門] 教程以安裝和保護 Redis 服務器。
第 1 步 — 安裝 PHP Redis 擴展
在此步驟中,您將安裝一個允許 PHP 與 Redis 服務器通信的 Redis 擴展。您還將創建一個測試網頁,該網頁實現了 Redis 哈希映射以跟踪網頁訪問。
在安裝 Redis 擴展之前,刷新您的 Ubuntu 軟件包信息索引:
然後,執行以下命令來安裝 php-redis
。此擴展提供了與 Redis 服務器鍵值存儲通信的 API:
重新啟動 Apache 以加載新的擴展:
您現在已安裝了一個 PHP 擴展,可與您的 Redis 服務器通信。接下來,您將在 Apache Web 伺服器的根目錄下創建一個 test.php
網頁。這只是一個範例文件,當訪客使用瀏覽器訪問您的網站時會請求它。在幕後,test.php
頁面文件加載一個 hit_counter.php
腳本,稍後您將創建以使用 Redis 服務器來跟蹤網頁訪問的 hit_counter.php
文件:
在現實情況下,您的網站可能有幾十甚至幾百個網頁。對於本指南,您將為演示目的設置一個單獨的網頁:
在終端窗口中,使用 nano
在您的 Web 伺服器的根目錄 /var/www/html/
下創建一個新的 test.php
文件:
然後,將以下信息輸入到 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>
當您編輯完成後保存並關閉文件。在此步驟中,您已創建了一個簡單的 HTML 網頁,當訪問時加載一個 hit_counter.php
文件。接下來,您將編寫 hit_counter.php
文件來跟蹤測試頁面的訪問。
步驟 2 — 創建一個 Redis 點擊計數器腳本
在生產環境中工作時,將可重褐使用的 PHP 文件分開是非常常見的。這使您可以通過包含它們的路徑而不是複製粘貼代碼,在項目的不同部分實施這些文件中的邏輯。這樣做可以使維護變得更容易,因為您只需要在需要更改邏輯的情況下編輯單個文件。這樣可以節省大量時間。
您將在本指南中應用相同的策略。您將創建一個單獨的 hit_counter.php
文件,可以包含在任何需要追蹤訪問者的網頁中。
在此文件中,您將使用 php-redis
库來從 PHP 連接到 Redis 服務器。然後,您將創建一個 Redis 哈希映射,用於存儲訪問者對您的網站的訪問次數。您將使用訪問者的唯一 IP 地址作為 Redis 鍵來區分每個訪問者在 Redis 服務器中的點擊次數。
在您的終端窗口中,使用 nano
打開一個新的 hit_counter.php
文件以進行編輯:
現在已經創建了 hit_counter.php
文件,打開一個新的 PHP 標籤 <?php
。然後,在 try {
塊內部輸入以下代碼來連接到端口 6379
上的本地 Redis 服務器。將 EXAMPLE_PASSWORD
替換為 Redis 服務器的身份驗證密碼:
<?php
try {
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis->auth('EXAMPLE_PASSWORD');
接下來,給 Redis 哈希映射($siteVisitsMap
) 一個您選擇的名稱。本指南使用 siteStats
作為演示目的:
$siteVisitsMap = 'siteStats';
定義了 Redis 哈希映射後,現在要初始化一個空的 Redis 金鑰($visitorHashKey
)。然後,您將用訪問者的 IP 地址填充它。您將使用 $visitorHashKey
變數的值來唯一標識每個請求您網頁的訪問者:
$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'];
}
在此代碼中,您使用 PHP 的 if
陳述來通過檢查是否填充了 $_SERVER['HTTP_CLIENT_IP']
、$_SERVER['HTTP_X_FORWARDED_FOR']
或 $_SERVER['REMOTE_ADDR']
變數來確定訪問者的 IP 地址。
隨後,初始化一個 $totalVisits
變數來存儲每個 IP 地址的總訪問次數,並將其賦值為 0。然後,使用 PHP 的 if (...) {...} else {...}
和 $redis->hExists($siteVisitsMap, $visitorHashKey)
陳述來檢查 Redis 服務器中是否存在該 IP 地址的任何項目。
您將使用語句 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
),但您必须使用语句 array($visitorHashKey)
将其转换为数组。
如果您的脚本首次遇到 IP 地址,则将 $totalVisits
变量设置为 1。最后,使用 $redis->hSet($siteVisitsMap, $visitorHashKey, $totalVisits);
根据上一个 if (...) {...} else {...}
语句的结果设置 $visitorHashKey
的值。 $redis->hSet($siteVisitsMap, $visitorHashKey, $totalVisits)
语句在 Redis 服务器中创建一个名为 $visitorHashKey
的键的 $siteVisitsMap
散列映射,其值为 $totalVisits
。
然后,通过回显总访问次数来欢迎访客,并关闭 } catch (...) {...}
块:
$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();
}
完成后,您的 /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();
}
完成編輯後,儲存並關閉檔案。現在,您已經編寫了一個 hit_counter.php
腳本。接下來,您將創建另一個 PHP 腳本,從 Redis 哈希映射中收集的數據生成報告。
第 3 步 — 創建站點統計報告腳本
一旦您在 Redis 哈希映射中收集了數據,如果無法檢索並以報告形式呈現信息,則這些數據可能毫無意義。在此步驟中,您將創建一個日誌報告,顯示不同的網站訪問者以及他們在測試網頁上總共的訪問次數。
要創建日誌報告腳本,請在終端窗口上運行 nano
並創建一個新的 /var/www/html/log_report.php
檔案:
然後,將以下信息輸入到檔案中。將 EXAMPLE_PASSWORD
替換為 Redis 伺服器的正確密碼:
<!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>
當您完成編輯時,請保存並關閉文件。在上述腳本中,您正在連接到 Redis 伺服器,並使用語句 $redis->HGETALL($siteVisitsMap);
檢索網頁訪問的哈希映射。然後,您使用 PHP foreach ($siteStats as $visitor => $totalVisits) {
語句循環並顯示訪問者的 IP 地址以及他們對您的站點所做的訪問次數。您使用 Redis HGETALL
命令從 siteVisitsMap
映射檢索所有字段(IP 地址)和值(每個 IP 地址的總訪問次數)。
您現在有一個測試頁面、一個點擊計數器腳本和一個報告頁面來檢查您的站點統計信息。接下來,您將測試您的點擊計數器的功能,並查看一切是否正常運作。
步驟 4 — 測試 Redis 點擊計數器
在這一步中,您將測試點擊計數器的整個邏輯。在您的 Web 瀏覽器中導航到以下 URL。將 your-server-IP
替換為您服務器的公共 IP 地址或域名。
http://your-server-IP/test.php
使用不同的設備刷新頁面幾次以生成足夠的統計信息。每次訪問後,您應該收到以下輸出。
接下來,訪問以下 URL 以在 HTML 表格中顯示您的站點訪問報告
http://your-server-IP/log_report.php
您現在應該會看到類似以下輸出的報告。
您的點擊計數器現在按預期運行。
結論
在本指南中,您已經在Ubuntu 20.04伺服器上使用Redis和PHP設置了網站點擊計數器。
從本指南中的示例源代碼可以看出,Redis提供了更清晰的方法來創建和更新哈希映射。
正如本指南開頭所提到的,使用關聯式數據庫管理系統可能仍然有效,但您將需要撰寫大量代碼來插入和更新底層表中的數據。此外,基於磁盤的數據庫在您的網站增長時可能會遇到擴展性問題。
有關在內存中使用Redis的更多信息,請參閱以下指南: