redis實戰之使用redis儲存最近瀏覽的商品資料
注:本文只做教學目的,而在實際的應用場景中,大型的電商網站的訪問量較大,將瀏覽資料儲存於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即可。