TP6的事件系統(tǒng)和模型事件

以前用過hook吧腹尖,鉤子的作用和事件是一個(gè)性質(zhì)的柳恐,你可以把事件當(dāng)作一個(gè)閉包或者匿名函數(shù)來使用伐脖,就能得到自己想要的結(jié)果了。

閉包函數(shù)和匿名函數(shù)的作用域?qū)儆谧陨砝稚瑁ㄟ^反射可以bindTo當(dāng)前的方法或者類讼庇,進(jìn)而獲取其作用域。

事件event方法就是將before_select事件類綁定一個(gè)閉包函數(shù)近尚,當(dāng)觸發(fā)器調(diào)用before_select時(shí)也就執(zhí)行了閉包函數(shù)蠕啄,閉包內(nèi)部使用return返回的時(shí)當(dāng)前作用域內(nèi)的結(jié)果。也就是執(zhí)行before_select就是在執(zhí)行閉包函數(shù)function(){}戈锻,其返回值獲得了調(diào)用event類的那個(gè)類的作用域歼跟,按照框架的設(shè)計(jì),是獲得了當(dāng)前調(diào)用模型類的作用域格遭。

如果上邊我將的太生澀了哈街,都是文字能力太差的原因,建議你再看一下閉包函數(shù)和其作用域拒迅,另外模型事件的定義是可以參照源代碼骚秦,找到trigger('before_select)(一般都是用動(dòng)態(tài)調(diào)用的方式,你要跑一下xdebug)你就找到你要的結(jié)果了璧微。

另外作箍,再啰嗦一下框架的Model加載,前后敘述省略一些和你提出的問題不大的過程前硫,

首先胞得,Model是通過App容器內(nèi)make()實(shí)例后,經(jīng)過Service的register()注冊成ModelService被加載進(jìn)框架的屹电,查看app.php的initialize()最后的foreach就看到了阶剑。

????????date_default_timezone_set($this->config->get('app.default_timezone',?'Asia/Shanghai'));

????????//?初始化

????????foreach?($this->initializers?as?$initializer)?{

????????????$this->make($initializer)->init($this);

????????}

????????return?$this;

????}

????protected?$services?=?[

????????PaginatorService::class,

????????ValidateService::class,

????????ModelService::class,

????];

????public?function?init(App?$app)

????{

????????$file?=?$app->getRootPath()?.?'vendor/services.php';

????????$services?=?$this->services;

????????if?(is_file($file))?{

????????????$services?=?array_merge($services,?include?$file);

????????}

????????foreach?($services?as?$service)?{

????????????if?(class_exists($service))?{

????????????????$app->register($service);

????????????}

????????}

????}

其次,Model模型是在ModelService內(nèi)執(zhí)行boot()時(shí)被初始化的嗤详。

????public?function?boot()

????{

????????Model::setDb($this->app->db);

????????Model::setEvent($this->app->event);

????????Model::setInvoker([$this->app,?'invoke']);

????????Model::maker(function?(Model?$model)?{

????????????$config?=?$this->app->config;

????????????$isAutoWriteTimestamp?=?$model->getAutoWriteTimestamp();

????????????if?(is_null($isAutoWriteTimestamp))?{

????????????????//?自動(dòng)寫入時(shí)間戳

????????????????$model->isAutoWriteTimestamp($config->get('database.auto_timestamp',?'timestamp'));

????????????}

????????????$dateFormat?=?$model->getDateFormat();

????????????if?(is_null($dateFormat))?{

????????????????//?設(shè)置時(shí)間戳格式

????????????????$model->setDateFormat($config->get('database.datetime_format',?'Y-m-d?H:i:s'));

????????????}

????????});

????}

你可以看到通過靜態(tài)調(diào)用方法setEvent()將Event對象(也是整個(gè)框架底層結(jié)構(gòu)的事件系統(tǒng))加載進(jìn)來,其中當(dāng)然就包括模型事件瓷炮,因?yàn)槟P褪录谡麄€(gè)模型系統(tǒng)中只是一個(gè)子集(看作一個(gè)屬性)葱色。

在整個(gè)框架內(nèi)部的任意位置你隨時(shí)都可以執(zhí)行Db::event()或模型內(nèi)部靜態(tài)調(diào)用setEvent(),不過模型內(nèi)部的靜態(tài)調(diào)用setEvent()創(chuàng)建的任務(wù)是獨(dú)立于框架系統(tǒng)事件任務(wù)的娘香,但是框架系統(tǒng)事件可以隨時(shí)調(diào)用它苍狰,具體內(nèi)容自行看trait ModelEvent類這里不贅述了。

明白了以上的流程和邏輯關(guān)系之后烘绽,再回頭看你自己對模型事件的自定義內(nèi)容淋昭,事件系統(tǒng)本身就是通過綁定的方式進(jìn)行關(guān)聯(lián)。對于模型事件來說安接,也不例外

????public?function?event(string?$event,?callable?$callback):?void

????{

????????$this->event[$event][]?=?$callback;

????}

這也就是在模型事件trigger()觸發(fā)$event是翔忽,會(huì)執(zhí)行一個(gè)$callback,如果你沒有return就不存在任何返回值,只是執(zhí)行了函數(shù)體歇式,函數(shù)體也是你所有的預(yù)期操作和執(zhí)行驶悟,而加上return只有一種情況,就是不執(zhí)行當(dāng)前事件之后的事件了材失,給一個(gè)false就可以痕鳍。對于事件$event參與的執(zhí)行,無法給你任何的反饋龙巨,你只是進(jìn)行了一次hook而已笼呆。

另外附加一下trigger()的調(diào)用代碼

????public?function?trigger(string?$event,?$params?=?null)

????{

????????if?(isset($this->event[$event]))?{

????????????foreach?($this->event[$event]?as?$callback)?{

????????????????call_user_func_array($callback,?[$this]);

????????????}

????????}

????}

以上內(nèi)容沒有進(jìn)行二次校對,錯(cuò)別字和語病請擔(dān)待旨别。

補(bǔ)充一句诗赌,看trigger()里的if判斷,就是你不理解的return值昼榛,給了false后邊的循環(huán)就不進(jìn)行了境肾。注意,這里用的是isset判斷5ㄓ臁0掠鳌!只要定義過模型事件非迹,isset就是true环鲤,模型事件內(nèi)沒有return和return任何除false以外的值一樣可以執(zhí)行,即使你return 0憎兽;都沒關(guān)系冷离。

$this->event[$event]就是將所有模型事件的類型存到數(shù)組中的索引中,而模型事件的閉包結(jié)果存在$this->event[$event][]中纯命,后邊的循環(huán)就是遍歷整個(gè)數(shù)組西剥,完成所有事件的執(zhí)行。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末亿汞,一起剝皮案震驚了整個(gè)濱河市瞭空,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌疗我,老刑警劉巖咆畏,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異吴裤,居然都是意外死亡旧找,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進(jìn)店門麦牺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來钮蛛,“玉大人鞭缭,你說我怎么就攤上這事≡缸洌” “怎么了缚去?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長琼开。 經(jīng)常有香客問我易结,道長,這世上最難降的妖魔是什么柜候? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任搞动,我火速辦了婚禮,結(jié)果婚禮上渣刷,老公的妹妹穿的比我還像新娘鹦肿。我一直安慰自己,他們只是感情好辅柴,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布箩溃。 她就那樣靜靜地躺著,像睡著了一般碌嘀。 火紅的嫁衣襯著肌膚如雪涣旨。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天股冗,我揣著相機(jī)與錄音霹陡,去河邊找鬼。 笑死止状,一個(gè)胖子當(dāng)著我的面吹牛烹棉,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播怯疤,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼浆洗,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了集峦?” 一聲冷哼從身側(cè)響起伏社,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎少梁,沒想到半個(gè)月后洛口,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體矫付,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡凯沪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了买优。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片妨马。...
    茶點(diǎn)故事閱讀 40,102評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出谜嫉,到底是詐尸還是另有隱情返弹,我是刑警寧澤,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布滤淳,位于F島的核電站梧喷,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏脖咐。R本人自食惡果不足惜铺敌,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望屁擅。 院中可真熱鬧偿凭,春花似錦、人聲如沸派歌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽胶果。三九已至匾嘱,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間稽物,已是汗流浹背奄毡。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留贝或,地道東北人吼过。 一個(gè)月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像咪奖,于是被迫代替她去往敵國和親盗忱。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評論 2 355

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

  • 1.JQuery 基礎(chǔ) 改變web開發(fā)人員創(chuàng)造搞交互性界面的方式羊赵。設(shè)計(jì)者無需花費(fèi)時(shí)間糾纏JS復(fù)雜的高級特性趟佃。 1....
    LaBaby_閱讀 1,174評論 0 1
  • 1.JQuery 基礎(chǔ) 改變web開發(fā)人員創(chuàng)造搞交互性界面的方式。設(shè)計(jì)者無需花費(fèi)時(shí)間糾纏JS復(fù)雜的高級特性昧捷。 1....
    LaBaby_閱讀 1,341評論 0 2
  • 函數(shù)和對象 1闲昭、函數(shù) 1.1 函數(shù)概述 函數(shù)對于任何一門語言來說都是核心的概念。通過函數(shù)可以封裝任意多條語句靡挥,而且...
    道無虛閱讀 4,566評論 0 5
  • JavaScript語言精粹 前言 約定:=> 表示參考相關(guān)文章或書籍; JS是JavaScript的縮寫序矩。 本書...
    微笑的AK47閱讀 581評論 0 3
  • Laravel框架一:原理機(jī)制篇 Laravel作為在國內(nèi)國外都頗為流行的PHP框架,風(fēng)格優(yōu)雅跋破,其擁有自己的一些特...
    Mr_Z_Heng閱讀 3,697評論 0 13