成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

Laravel學(xué)習(xí)筆記之Model Observer模型觀察者

Crazy_Coder / 2159人閱讀

摘要:說(shuō)明本文主要學(xué)習(xí)下的模型觀察者,把一點(diǎn)點(diǎn)經(jīng)驗(yàn)分享出來(lái)希望對(duì)別人能有幫助。模型觀察者這個(gè)功能能做很多事情,比如模型更新時(shí)發(fā)個(gè)通知。總結(jié)本篇文章主要學(xué)了下的模型觀察者,發(fā)現(xiàn)這個(gè)功能也能使代碼結(jié)構(gòu)更清晰,覺(jué)得挺好的。

說(shuō)明:本文主要學(xué)習(xí)下Laravel的Model Observer模型觀察者,把一點(diǎn)點(diǎn)經(jīng)驗(yàn)分享出來(lái)希望對(duì)別人能有幫助。同時(shí),作者會(huì)將開(kāi)發(fā)過(guò)程中的一些截圖和代碼黏上去,提高閱讀效率。

備注:上一篇文章:Laravel學(xué)習(xí)筆記之Redis保存頁(yè)面瀏覽量,作者在開(kāi)發(fā)的時(shí)候有個(gè)邏輯有點(diǎn)在意:那篇文章再用Redis保存瀏覽量后,當(dāng)瀏覽量達(dá)到設(shè)置的次數(shù)后刷到MySQL里,同時(shí)把Redis里該瀏覽量鍵抹掉,還有Post的內(nèi)容鍵抹掉,以便下一次請(qǐng)求從MySQL里請(qǐng)求到新的數(shù)據(jù)并緩存。研究時(shí),發(fā)現(xiàn)可以使用Model Observer來(lái)實(shí)現(xiàn)Model的事件變化來(lái)自動(dòng)刷新flush下Redis,個(gè)人覺(jué)得有點(diǎn)像是定義了一個(gè)事件監(jiān)聽(tīng)器監(jiān)聽(tīng)模型事件一樣。這篇文章就用下Model Observer重新組織下代碼。可以大概看下上篇文章的基本邏輯

開(kāi)發(fā)環(huán)境:Laravel5.1+MAMP+PHP7+MySQL5.5

沒(méi)有Model Observer邏輯

看下最主要的瀏覽量達(dá)到一定量后刷到MySQL里的邏輯:

 /**
     * 不同用戶訪問(wèn),更新緩存中瀏覽次數(shù)
     * @param $id
     * @param $ip
     */
    public function updateCacheViewCount($id, $ip)
    {
        $cacheKey        = "post:view:".$id;
        //這里以Redis哈希類型存儲(chǔ)鍵,就和數(shù)組類似,$cacheKey就類似數(shù)組名,$ip為$key.HEXISTS指令判斷$key是否存在$cacheKey中
        if(Redis::command("HEXISTS", [$cacheKey, $ip])){
            //哈希類型指令HINCRBY,就是給$cacheKey[$ip]加上一個(gè)值,這里一次訪問(wèn)就是1
            $incre_count = Redis::command("HINCRBY", [$cacheKey, $ip, 1]);
            //redis中這個(gè)存儲(chǔ)瀏覽量的值達(dá)到30后,就往MySQL里刷下,這樣就不需要每一次瀏覽,來(lái)一次query,效率不高
            if($incre_count == self::postViewLimit){
                $this->updateModelViewCount($id, $incre_count);
                //本篇post,redis中瀏覽量刷進(jìn)MySQL后,把該篇post的瀏覽量鍵抹掉,等著下一次請(qǐng)求重新開(kāi)始計(jì)數(shù)

                Redis::command("HDEL", [$cacheKey, $ip]);//瀏覽量這個(gè)刪除key操作也可以在Model Observer里做,不過(guò)要把Redis改成Cache的方法,這里就不寫了

                //同時(shí),抹掉post內(nèi)容的緩存鍵,這樣就不用等10分鐘后再更新view_count了,
                //如該篇post在100秒內(nèi)就達(dá)到了30訪問(wèn)量,就在3分鐘時(shí)更新下MySQL,并把緩存抹掉,下一次請(qǐng)求就從MySQL中請(qǐng)求到最新的view_count,
                //當(dāng)然,100秒內(nèi)view_count還是緩存的舊數(shù)據(jù),極端情況300秒內(nèi)都是舊數(shù)據(jù),而緩存里已經(jīng)有了29個(gè)新增訪問(wèn)量
                //實(shí)際上也可以這樣做:在緩存post的時(shí)候,可以把view_count多帶帶拿出來(lái)存入鍵值里如single_view_count,每一次都是給這個(gè)值加1,然后把這個(gè)值傳入視圖里
                //或者平衡設(shè)置下postViewLimit和ipExpireSec這兩個(gè)參數(shù),對(duì)于view_count這種實(shí)時(shí)性要求不高的可以這樣做來(lái)著
                //加上laravel前綴,因?yàn)镃ache::remember會(huì)自動(dòng)在每一個(gè)key前加上laravel前綴,可以看cache.php中這個(gè)字段:"prefix" => "laravel"
               
                //使用Model Observer后注銷這句
//                Redis::command("DEL", ["laravel:post:cache:".$id]);//利用Model Observer,這里就不用刷掉這個(gè)key,邏輯可在模型觀察器里做
            }
        }else{
            //哈希類型指令HSET,和數(shù)組類似,就像$cacheKey[$ip] = 1;
            Redis::command("HSET", [$cacheKey, $ip, "1"]);
        }
    }

這里在瀏覽量達(dá)到self::postViewLimit后把view_count刷到MySQL里并刷新下Redis,使用這個(gè)邏輯:

Redis::command("DEL", ["laravel:post:cache:".$id]);
有Model Observer邏輯

可以注冊(cè)一個(gè)模型觀察者,在觀察者類里做一些模型對(duì)應(yīng)事件的邏輯,這里就是刷掉一些緩存鍵值。
在app/Observers/PostObserver.php(模型觀察類放在哪里可以自定義)里:

flush();
    }

    public function saving()
    {

    }

    public function deleted()
    {

    }
}

這里使用flush()方法只刷指定tag的緩存鍵,免得把別的key也刷了。這里打的標(biāo)簽其實(shí)是:["posts", "model"],Post::table()定義返回Model關(guān)聯(lián)的表名,看下Post這個(gè)Model:

class Post extends Model
{
    public function category()
    {
        return $this->belongsTo(Category::class);
    }

    public function comments()
    {
        return $this->hasMany(Comment::class);
    }

    public function tags()
    {
        return $this->belongsToMany(Tag::class)->withTimestamps();
    }

    /**
     * 在boot()方法里注冊(cè)下模型觀察類
     * boot()和observe()方法都是從Model類繼承來(lái)的
     * 主要是observe()來(lái)注冊(cè)模型觀察類,可以用Post::observe(new PostObserve())
     * 并放在代碼邏輯其他地方如路由都行,這里放在這個(gè)Post Model的boot()方法里自啟動(dòng)。
     */
    public static function boot()
    {
        parent::boot(); // TODO: Change the autogenerated stub
        static::observe(new PostObserver());
    }

    /**
     * 返回該Model關(guān)聯(lián)的表
     * @return string
     */
    public static function table()
    {
        $model = new static;
        //調(diào)用Model類的public function getTable()
        return $model->getTable();
    }
}

還有別忘了在PostController里緩存Post Model的時(shí)候打上標(biāo)簽:

public function showPostCache(Request $request, $id)
    {
        //Redis緩存中沒(méi)有該post,則從數(shù)據(jù)庫(kù)中取值,并存入Redis中,該鍵值key="post:cache".$id生命時(shí)間10分鐘
        //在把內(nèi)容緩存進(jìn)Redis里,加上tag標(biāo)簽以便于識(shí)別和分別操作,個(gè)人覺(jué)得這是一個(gè)好習(xí)慣實(shí)際上.這里加個(gè)該post對(duì)應(yīng)的表名標(biāo)簽,保持唯一性
        $post = Cache::tags([Post::table(), "model"])->remember("post:cache:".$id, self::modelCacheExpires, function () use ($id) {
            return Post::whereId($id)->first();
        });

        //獲取客戶端IP
        $ip   = $request->ip();
        //觸發(fā)瀏覽量計(jì)數(shù)器事件
        event(new PostViewCount($post, $ip));

        return view("browse.post", compact("post"));
    }

現(xiàn)在測(cè)試下當(dāng)view_count被刷進(jìn)MySQL時(shí),即saved()事件后,模型觀察類有沒(méi)有把["posts", "model"]這個(gè)標(biāo)簽的鍵給刷掉。這里設(shè)置下:

class PostEventListener
{
    /**
     * 同一post最大訪問(wèn)次數(shù),再刷新數(shù)據(jù)庫(kù)
     */
    const postViewLimit = 3;

    ...    
}    

不同IP刷下3次后緩存的Post Model有沒(méi)有被刷掉。
第一個(gè)IP訪問(wèn)時(shí)Post Model已經(jīng)被刷到Redis里了:

第三個(gè)IP訪問(wèn)時(shí),Post Model已經(jīng)被從Redis里刷掉了:

it is working!!!
這證明了view_count被save()進(jìn)MySQL時(shí),模型觀察類邏輯起作用了。當(dāng)然第四個(gè)IP訪問(wèn)后頁(yè)面就會(huì)顯示最新的瀏覽量了。

模型觀察者這個(gè)功能能做很多事情,比如Model Update模型更新時(shí)發(fā)個(gè)通知?;蛘呔拖褚黄恼碌膬?nèi)容重新編輯保存后,把原來(lái)緩存內(nèi)的該篇文章內(nèi)容刷新下,這樣下一個(gè)請(qǐng)求來(lái)的時(shí)候讀的就是最新的文章內(nèi)容了。作者以后會(huì)繼續(xù)研究研究,發(fā)現(xiàn)挺好玩的東西到時(shí)候分享出來(lái)吧。

總結(jié):本篇文章主要學(xué)了下Laravel的Model Observer模型觀察者,發(fā)現(xiàn)這個(gè)功能也能使代碼結(jié)構(gòu)更清晰,覺(jué)得挺好的。最近一直在瞎研究,有遇到好玩的再分享出來(lái)吧。

歡迎關(guān)注Laravel-China。

RightCapital招聘Laravel DevOps

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/21686.html

相關(guān)文章

  • Laravel 中的模型事件與 Observer

    摘要:模型事件在的世界中你對(duì)大多數(shù)操作都會(huì)或多或少的觸發(fā)一些模型事件今天就來(lái)看一下模型事件的使用。事先已經(jīng)定義好了個(gè)模型事件以供我們使用它們分別是。和會(huì)在數(shù)據(jù)庫(kù)中的真值修改前后觸發(fā)。監(jiān)聽(tīng)數(shù)據(jù)即將保存的事件。監(jiān)聽(tīng)數(shù)據(jù)從軟刪除狀態(tài)恢復(fù)后的事件。 模型事件 在 Laravel 的世界中,你對(duì) Eloquent 大多數(shù)操作都會(huì)或多或少的觸發(fā)一些模型事件,今天就來(lái)看一下模型事件的使用。 Laravel...

    Yuanf 評(píng)論0 收藏0
  • Laravel核心解讀--察者模式

    摘要:模式定義觀察者模式定義對(duì)象間的一種一對(duì)多依賴關(guān)系,使得每當(dāng)一個(gè)對(duì)象狀態(tài)發(fā)生改變時(shí),其相關(guān)依賴對(duì)象皆得到通知并被自動(dòng)更新。 觀察者模式 Laravel的Event事件系統(tǒng)提供了一個(gè)簡(jiǎn)單的觀察者模式實(shí)現(xiàn),能夠訂閱和監(jiān)聽(tīng)?wèi)?yīng)用中發(fā)生的各種事件,在PHP的標(biāo)準(zhǔn)庫(kù)(SPL)里甚至提供了三個(gè)接口SplSubject, SplObserver, SplObjectStorage來(lái)讓開(kāi)發(fā)者更容易地實(shí)現(xiàn)觀...

    lei___ 評(píng)論0 收藏0
  • Laravel學(xué)習(xí)筆記Redis保存頁(yè)面瀏覽量

    摘要:說(shuō)明本文主要講述使用作為緩存加快頁(yè)面訪問(wèn)速度。何不用來(lái)做緩存,等到該達(dá)到一定瀏覽頁(yè)面后再刷新下,效率也很高。可作緩存系統(tǒng)隊(duì)列系統(tǒng)。 說(shuō)明:本文主要講述使用Redis作為緩存加快頁(yè)面訪問(wèn)速度。同時(shí),作者會(huì)將開(kāi)發(fā)過(guò)程中的一些截圖和代碼黏上去,提高閱讀效率。 備注:作者最近在學(xué)習(xí)github上別人的源碼時(shí),發(fā)現(xiàn)好多在計(jì)算一篇博客頁(yè)面訪問(wèn)量view_count時(shí)都是這么做的:利用Laravel...

    z2xy 評(píng)論0 收藏0
  • Laravel學(xué)習(xí)筆記Demo2——用Ajax來(lái)做個(gè)ToDoList(待更新)

    摘要:抱歉,最近忙,本篇等有時(shí)間更新。引言本文基于框架做的一個(gè)生成和存儲(chǔ),主要目的是學(xué)習(xí)使用框架。書籍基于的,學(xué)習(xí)時(shí)使用框架開(kāi)發(fā)。開(kāi)發(fā)環(huán)境備注一直想把這本書的個(gè)作為系列分享出來(lái),供初學(xué)者學(xué)習(xí)玩玩。 抱歉,最近忙,本篇等有時(shí)間更新。 引言 本文基于Laravel框架做的一個(gè)URL生成和存儲(chǔ)demo,主要目的是學(xué)習(xí)使用Laravel框架。內(nèi)容基于英文書籍《Packt.Laravel.Applic...

    luck 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<