注:本文只做教學目的,而在實際的應用場景中,大型的電商網站的訪問量較大,將瀏覽數據存儲於redis中並不可行,望讀者知悉。
關於使用redis保存最近瀏覽的商品數據,之前沒想到的是,cookie和redis存在本質上的區別。如果使用如本文中所述的方法存儲該數據,所有用戶共享的是一份數據,爲了解決這個問題,必須在設置key時帶上用戶的id值或是其他可以區分用戶的數據,不過又存在另一個問題,那便是用戶未登錄的時候怎麼處理,本文並未做深入討論,讀者權當溫習了一遍redis的list的操作吧。。。
在我們網上購物時,經常能看到那些電商網站通常都有一個叫做“最近瀏覽過的商品”這樣的功能模塊,如果你曾經接觸過ecshop,應該很容易就想到這樣的功能可以用cookie進行實現。
實現的思路是:用戶點擊商品詳情鏈接時,在該頁面植入一段代碼,將該商品在數據庫中對應的id號存儲到cookie中,此時需要做的邏輯判斷有:
1、cookie中是否已經存在該商品id,存在則刪除,將該商品編號添加到cookie末尾
2、cookie中存儲的商品id是否已經有5個了,如果是則刪除最早添加的一個,將該商品編號添加到cookie末尾
具體的實現代碼:
商品列表頁:
<a href="detail.php?p=a">a</a><br />
<a href="detail.php?p=b">b</a><br />
<a href="detail.php?p=c">c</a><br />
<a href="detail.php?p=d">d</a><br />
<a href="detail.php?p=e">e</a><br />
<a href="detail.php?p=f">f</a><br />
您最近瀏覽過的商品:<br />
<?php
require_once "functions.php";
echo getResentViews();
商品詳情頁:
<?php
require_once "functions.php";
echo $_GET['p'];
setResentViews($_GET['p']);
公用函數類庫:
<?php
//設定最近瀏覽過的商品
function setResentViews($product){
$resentViews = isset($_COOKIE['resentViews']) ? explode(',', $_COOKIE['resentViews']) : array();
//如果已經存在,則刪除之前的記錄
$temp = array_flip($resentViews);
unset($temp[$product]);
$resentViews = array_flip($temp);
if(count($resentViews) == 5){ // 超過了需要展示的最大數量,刪除最早添加的記錄
array_shift($resentViews);
}
array_push($resentViews, $product);
setcookie ( "resentViews" , implode(',', $resentViews) , time ()+ 3600 );
}
//獲取最近瀏覽過的商品
function getResentViews(){
$strToBeReturned = '';
$resentViews = isset($_COOKIE['resentViews']) ? explode(',', $_COOKIE['resentViews']) : array();
foreach($resentViews as $resentView){
$strToBeReturned.= $resentView."<br />";
}
return $strToBeReturned;
}
測試頁面截圖:
好,接下來我們來看看使用redis如何實現同樣的功能:
使用redis實現該功能與使用cookie實現類似,不同之處在於我們使用了redis的list數據類型來存儲數據,主要邏輯如下:
1、判斷列表中是否存在該商品,存在則刪除(lrem),並將該商品追加到列表末尾(rpush);
2、判斷列表中的商品是否已經大於或者等於5個(llen),滿足該條件時則將列表頭部的商品刪除(lpop),將該商品追加到列表末尾(rpush)
主要是functions.php文件的修改,具體實現代碼如下:
<?php
//設定最近瀏覽過的商品
function setResentViews($product){
$resentViews = isset($_COOKIE['resentViews']) ? explode(',', $_COOKIE['resentViews']) : array();
//如果已經存在,則刪除之前的記錄
$temp = array_flip($resentViews);
unset($temp[$product]);
$resentViews = array_flip($temp);
if(count($resentViews) == 5){ // 超過了需要展示的最大數量,刪除最早添加的記錄
array_shift($resentViews);
}
array_push($resentViews, $product);
setcookie ( "resentViews" , implode(',', $resentViews) , time ()+ 3600 );
}
function getResentViews(){
$strToBeReturned = '';
$resentViews = isset($_COOKIE['resentViews']) ? explode(',', $_COOKIE['resentViews']) : array();
foreach($resentViews as $resentView){
$strToBeReturned.= $resentView."<br />";
}
return $strToBeReturned;
}
function setResentViewsIntoRedis($product){
require_once 'iredis.php';
$redis = new iredis();
$key = "resentViewedItems";
//如果已經存在,則刪除之前的記錄
$redis->lrem($key, $product, 0);
//超過了需要展示的最大數量,刪除最早添加的記錄
if($redis->llen($key) >= 5){
$redis->lpop($key);
}
$redis->rpush($key, $product);
}
function getResentViewsFromRedis(){
require_once 'iredis.php';
$redis = new iredis();
$key = "resentViewedItems";
$resentViews = $redis->lrange($key, 0,-1);
$strToBeReturned = '';
foreach($resentViews as $resentView){
$strToBeReturned.= $resentView."<br />";
}
return $strToBeReturned;
}
iredis.php
<?php
class iredis extends Redis
{
public function __construct(){
parent::__construct();
$this->connect('127.0.0.1', '6379');
}
}
然後分別將list.php和detail.php中的getResentViews和setResentViews改成getResentViewsFromRedis和setResentViewsIntoRedis即可。