Laravel 中操作 Redis

需求:

今天的開發(fā)需求是記錄web和pc端的訪問量腋颠。初步思路是在controller入口進(jìn)行記錄繁成。使用redis中的Hash數(shù)據(jù)類型。key為日期淑玫,value為次數(shù)巾腕,正好Hash提供了累加(hincrby)操作,可以滿足要求絮蒿。目前的時(shí)間粒度是按照天數(shù)尊搬,后期擴(kuò)展的時(shí)候可以將時(shí)間粒度進(jìn)行細(xì)分。

""

編碼:

在laravel中的那個(gè)地方進(jìn)行次數(shù)的統(tǒng)計(jì)呢土涝?有兩個(gè)地方佛寿,一個(gè)是BaseController,還有一個(gè)中間件但壮,所有的請(qǐng)求均經(jīng)過這里冀泻。在統(tǒng)計(jì)的時(shí)候需要注意的是進(jìn)行過濾一些請(qǐng)求,比如接口post請(qǐng)求蜡饵,來自后臺(tái)管理系統(tǒng)的請(qǐng)求等等弹渔。

//基類controller構(gòu)造函數(shù)
 public function __construct(Request $request) 
    {
        $requestParam = request()->route()->getAction(); //獲取訪問的url
        $domain = [env('WECHAT_SUB_ROUTE'), env('FRONTEND_SUB_ROUTE')];//參與次數(shù)統(tǒng)計(jì)的rul
        if (in_array($requestParam['domain'], $domain) && $request->isMethod('get')) {
            $hashKey = 'webVisits';
            Redis::hincrby($hashKey, date('Y-m-d'), 1);//存入redis的hash
        }
    }

//getAction方法可以取到的值
array:8 [▼
  "domain" => "www.laravelylw.com"
  "middleware" => array:5 [?]
  "as" => "xiong.test"
  "uses" => "App\Http\Controllers\Home\Main\XiongTestController@index"
  "controller" => "App\Http\Controllers\Home\Main\XiongTestController@index"
  "namespace" => "App\Http\Controllers\Home\Main"
  "prefix" => null
  "where" => []
]
redis中儲(chǔ)存的值

根據(jù)需求可以看到會(huì)按照月和周進(jìn)行比較。所以初步思路是獲取某個(gè)時(shí)間段的startTime和endTime溯祸,然后通過Redis::hgetall($key)獲取到哈希表中所有的key-value肢专,以數(shù)組的方式返回。


redis通過hgetall獲取的

然后遍歷數(shù)組焦辅,將每個(gè)值和startTime-endTime比較鸟召,是否在該范圍,若在就進(jìn)行累加氨鹏,即可得到這個(gè)時(shí)間段的訪問量總和。

    //本周訪問量
    $memberVisiyNum_week =$this->getVisit(Time::week());
    //date是一個(gè)數(shù)組包含startTIme和endTIme压状,獲取本周仆抵,上周跟继,本月,上個(gè)月等時(shí)間工具在后面附上镣丑。
    //還使用到Carbon工具類舔糖,用法見https://9iphp.com/web/laravel/php-datetime-package-carbon.html
    private function getVisit($date){
        $key = 'webVisits';//hash的key
        $lists = Redis::hgetall($key);//返回整個(gè)hash表元素
        $visit = 0;
        $Carbon = new Carbon();
        $startTime = $Carbon->create(date('Y',$date[0]),date('m',$date[0]),date('d',$date[0]),0,0,0);//用于后面使用Carbon種的日期比較方法
        $endTime = $Carbon->create(date('Y',$date[1]),date('m',$date[1]),date('d',$date[1]),0,0,0);
        foreach ($lists as $k => $v){
            $vTime = $Carbon->create(date('Y',strtotime($k)),date('m',strtotime($k)),date('d',strtotime($k)),0,0,0);//可以兼容細(xì)化時(shí)間粒度后。
            if($vTime->gte($startTime) && $vTime->lte($endTime)){
                $visit = $visit + Redis::hget($key,$k);
            }
        }
        return $visit;
    }

至此編碼結(jié)束莺匠。

優(yōu)化

可以優(yōu)化的地方有以下幾個(gè)金吗。
1、時(shí)間粒度的優(yōu)化趣竣,目前的業(yè)務(wù)是統(tǒng)計(jì)到天摇庙,沒準(zhǔn)哪天運(yùn)營(yíng)說我要看看每天那個(gè)時(shí)間段訪問量最多。如果將時(shí)間粒度細(xì)化了遥缕,是否還能兼容現(xiàn)在的getVisit方法呢卫袒,是可以的。
2单匣、通過Redis::hgetall($key)取值的時(shí)候夕凝,我們其實(shí)每次不需要都取出來,根據(jù)業(yè)務(wù)需求户秤,最多60天的數(shù)據(jù)就ok了码秉,如果每次都取出來,foreach的時(shí)候很浪費(fèi)時(shí)間鸡号。

Time()工具類

class Time
{
    /**
     * 返回今日開始和結(jié)束的時(shí)間戳
     *
     * @return array
     */
    public static function today()
    {
        return [
            mktime(0, 0, 0, date('m'), date('d'), date('Y')),
            mktime(23, 59, 59, date('m'), date('d'), date('Y'))
        ];
    }

    /**
     * 返回昨日開始和結(jié)束的時(shí)間戳
     *
     * @return array
     */
    public static function yesterday()
    {
        $yesterday = date('d') - 1;
        return [
            mktime(0, 0, 0, date('m'), $yesterday, date('Y')),
            mktime(23, 59, 59, date('m'), $yesterday, date('Y'))
        ];
    }

    /**
     * 返回本周開始和結(jié)束的時(shí)間戳
     *
     * @return array
     */
    public static function week()
    {
        $timestamp = time();
        return [
            strtotime(date('Y-m-d', strtotime("this week Monday", $timestamp))),
            strtotime(date('Y-m-d', strtotime("this week Sunday", $timestamp))) + 24 * 3600 - 1
        ];
    }

    /**
     * 返回上周開始和結(jié)束的時(shí)間戳
     *
     * @return array
     */
    public static function lastWeek()
    {
        $timestamp = time();
        return [
            strtotime(date('Y-m-d', strtotime("last week Monday", $timestamp))),
            strtotime(date('Y-m-d', strtotime("last week Sunday", $timestamp))) + 24 * 3600 - 1
        ];
    }

    /**
     * 返回本月開始和結(jié)束的時(shí)間戳
     *
     * @return array
     */
    public static function month($everyDay = false)
    {
        return [
            mktime(0, 0, 0, date('m'), 1, date('Y')),
            mktime(23, 59, 59, date('m'), date('t'), date('Y'))
        ];
    }

    /**
     * 返回上個(gè)月開始和結(jié)束的時(shí)間戳
     *
     * @return array
     */
    public static function lastMonth()
    {
        $begin = mktime(0, 0, 0, date('m') - 1, 1, date('Y'));
        $end = mktime(23, 59, 59, date('m') - 1, date('t', $begin), date('Y'));

        return [$begin, $end];
    }

    /**
     * 返回今年開始和結(jié)束的時(shí)間戳
     *
     * @return array
     */
    public static function year()
    {
        return [
            mktime(0, 0, 0, 1, 1, date('Y')),
            mktime(23, 59, 59, 12, 31, date('Y'))
        ];
    }

    /**
     * 返回去年開始和結(jié)束的時(shí)間戳
     *
     * @return array
     */
    public static function lastYear()
    {
        $year = date('Y') - 1;
        return [
            mktime(0, 0, 0, 1, 1, $year),
            mktime(23, 59, 59, 12, 31, $year)
        ];
    }

    public static function dayOf()
    {

    }

    /**
     * 獲取幾天前零點(diǎn)到現(xiàn)在/昨日結(jié)束的時(shí)間戳
     *
     * @param int $day 天數(shù)
     * @param bool $now 返回現(xiàn)在或者昨天結(jié)束時(shí)間戳
     * @return array
     */
    public static function dayToNow($day = 1, $now = true)
    {
        $end = time();
        if (!$now) {
            list($foo, $end) = self::yesterday();
        }

        return [
            mktime(0, 0, 0, date('m'), date('d') - $day, date('Y')),
            $end
        ];
    }

    /**
     * 返回幾天前的時(shí)間戳
     *
     * @param int $day
     * @return int
     */
    public static function daysAgo($day = 1)
    {
        $nowTime = time();
        return $nowTime - self::daysToSecond($day);
    }

    /**
     * 返回幾天后的時(shí)間戳
     *
     * @param int $day
     * @return int
     */
    public static function daysAfter($day = 1)
    {
        $nowTime = time();
        return $nowTime + self::daysToSecond($day);
    }

    /**
     * 天數(shù)轉(zhuǎn)換成秒數(shù)
     *
     * @param int $day
     * @return int
     */
    public static function daysToSecond($day = 1)
    {
        return $day * 86400;
    }

    /**
     * 周數(shù)轉(zhuǎn)換成秒數(shù)
     *
     * @param int $week
     * @return int
     */
    public static function weekToSecond($week = 1)
    {
        return self::daysToSecond() * 7 * $week;
    }

    private static function startTimeToEndTime()
    {

    }
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末转砖,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子膜蠢,更是在濱河造成了極大的恐慌堪藐,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,104評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件挑围,死亡現(xiàn)場(chǎng)離奇詭異礁竞,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)杉辙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門模捂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蜘矢,你說我怎么就攤上這事狂男。” “怎么了品腹?”我有些...
    開封第一講書人閱讀 168,697評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵岖食,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我舞吭,道長(zhǎng)泡垃,這世上最難降的妖魔是什么析珊? 我笑而不...
    開封第一講書人閱讀 59,836評(píng)論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮蔑穴,結(jié)果婚禮上忠寻,老公的妹妹穿的比我還像新娘。我一直安慰自己存和,他們只是感情好奕剃,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著捐腿,像睡著了一般纵朋。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上叙量,一...
    開封第一講書人閱讀 52,441評(píng)論 1 310
  • 那天倡蝙,我揣著相機(jī)與錄音,去河邊找鬼绞佩。 笑死寺鸥,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的品山。 我是一名探鬼主播胆建,決...
    沈念sama閱讀 40,992評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼肘交!你這毒婦竟也來了笆载?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,899評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤涯呻,失蹤者是張志新(化名)和其女友劉穎凉驻,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體复罐,經(jīng)...
    沈念sama閱讀 46,457評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡涝登,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評(píng)論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了效诅。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片胀滚。...
    茶點(diǎn)故事閱讀 40,664評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖乱投,靈堂內(nèi)的尸體忽然破棺而出咽笼,到底是詐尸還是另有隱情,我是刑警寧澤戚炫,帶...
    沈念sama閱讀 36,346評(píng)論 5 350
  • 正文 年R本政府宣布剑刑,位于F島的核電站,受9級(jí)特大地震影響双肤,放射性物質(zhì)發(fā)生泄漏施掏。R本人自食惡果不足惜层宫,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望其监。 院中可真熱鬧,春花似錦限匣、人聲如沸抖苦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)锌历。三九已至,卻和暖如春峦筒,著一層夾襖步出監(jiān)牢的瞬間究西,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工物喷, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留卤材,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,081評(píng)論 3 377
  • 正文 我出身青樓峦失,卻偏偏與公主長(zhǎng)得像扇丛,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子尉辑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 本文將從Redis的基本特性入手隧魄,通過講述Redis的數(shù)據(jù)結(jié)構(gòu)和主要命令對(duì)Redis的基本能力進(jìn)行直觀介紹卓练。之后概...
    kelgon閱讀 61,176評(píng)論 23 625
  • 超強(qiáng)、超詳細(xì)Redis入門教程 轉(zhuǎn)載2017年03月04日 16:20:02 16916 轉(zhuǎn)載自: http://...
    邵云濤閱讀 17,452評(píng)論 3 313
  • 本文將從Redis的基本特性入手,通過講述Redis的數(shù)據(jù)結(jié)構(gòu)和主要命令對(duì)Redis的基本能力進(jìn)行直觀介紹闸溃。之后概...
    團(tuán)長(zhǎng)plus閱讀 1,259評(píng)論 0 15
  • 文章已經(jīng)放到github上 整吆,如果對(duì)您有幫助 請(qǐng)給個(gè)star[https://github.com/qqxuanl...
    尼爾君閱讀 2,287評(píng)論 0 22
  • 老陸覺著可鬧心了。 原本想著最近幾天自己代理的儲(chǔ)蓄所主任就要轉(zhuǎn)正辉川,滿心歡喜地等待著按程序和上級(jí)領(lǐng)導(dǎo)談話表蝙,可誰(shuí)知系統(tǒng)...
    半半童鞋閱讀 196評(píng)論 0 2