1. 程式人生 > >redis實戰之使用redis儲存最近瀏覽的商品資料

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即可。