小弟剛工作1個多月,也是初次寫博客,希望與大家分享分享,本文如有不對的地方、語句不通順的地方、不符合邏輯的地方、很二的地方、希望各位大神能夠多多包含並指出,謝謝!
初學Laravel框架 也是初學PHP 創建了一個羣 希望和大家一起學習討論 歡迎大家的加入羣號:296177986
大家都知道目前沒有哪一種語言的緩存技術能夠在緩存失效時進行捕捉,可能很多人都覺得沒有必要,或許是我的知識面還不夠廣,沒有發現實現點擊量統計更好的方法。
以新聞網站爲例,分析如下:
我們要緩存點擊量,肯定是將新聞ID和點擊次數存到(數組,集合...)等等,看大家習慣,如果你想沒30分鐘更新一次到數據庫,請問你怎麼判斷30分鐘一到就更新到數據庫呢?(那麼問題來了,敢問挖掘機技術哪家強?)大家別忘了 緩存沒有像類一樣的析構函數(表示沒用過 -_-!),無法讓他失效的時候執行更新點擊量的代碼代碼。
既然這樣我們可不可以自己判斷呢?
實現步驟(該具體步驟針對PHP):
網站首次上線,當第一個用戶點擊新聞的時候,我們新建一個永久性緩存 在緩存中存一個數組,數組的第一個值對就是 緩存起始時間 如:$cache_click['cache_time']=time();
當第N個用戶點擊時,判斷$cache_click['cache_time'] + 30分鐘 小於 當前時間時 我們就執行更新,更新完成後 將$cache_click 數組清空 並且 重新賦值$cache_click['cache_time']=time(); 然後存入緩存,好了不多說了,估計越說大家越亂(我也亂了),看代碼好了 PHP Laravel框架的代碼
//點擊量緩存
public function click($newsid)
{
//緩存多久 這裏是指30秒
$time_update = 30;
//用來存儲
$click_cache = array();
//判斷緩存是否存在
if(Cache::has("NewsCenter_click_cache"))
{
//如果存在取出緩存數據
$click_cache=Cache::get("NewsCenter_click_cache");
}
else//如果不存在
{
//存入首次緩存時間
$click_cache["cache_time"] = time();
//添加進緩存 永久性緩存
Cache::forever("NewsCenter_click_cache",$click_cache);
//終止執行
return;
}
//判斷緩存內是否已經存在$newsid的鍵值
if(array_key_exists($newsid,$click_cache))
{
//存在 就在值上面加 1
$click_cache[$newsid] = (int)$click_cache[$newsid]+1;
}
else
{
//不存在給默認值 1
$click_cache[$newsid] = 1;
}
//獲取上次緩存的時間
$last_cache_time = (int)$click_cache["cache_time"];
//如果上次緩存時間加上過期時間 小於當前時間 說明緩存要過期
if($last_cache_time+$time_update<time())
{
//緩存過期 將緩存的點擊量更新到數據庫 並且清除緩存
foreach($click_cache as $key_newid=>$val_click)
{
//這樣判斷是因爲數組中存的第一個是 cache_time的鍵值 必須排除掉
if($key_newid!="cache_time")
{
//通過新聞ID找到對應model
$news = HTNewsInfo::find($key_newid);
if($news!=null)
{
//用新聞原點擊量加上緩存的點擊量
$new_click_count = $news['attributes']['CLICK_COUNT']+$val_click;
//最新點擊量加上原點擊量 更新到數據庫
DB::update('update HT_NEWS_INFO set CLICK_COUNT = ? where NEWSID = ?', array($new_click_count,$key_newid));
}
}
}
//更新數據庫完成後清除數組中的數據 並填充到緩存
$click_cache=null;
$click_cache["cache_time"] = time();
Cache::forever("NewsCenter_click_cache",$click_cache);
}
else
{
Cache::forever("NewsCenter_click_cache",$click_cache);
}
}