3分鐘短文:Laravel表單驗(yàn)證的“指揮中心”:FormRequest

引言

上一章我們學(xué)習(xí)到琳水,Laravel控制器內(nèi)引入 ValidatesRequests trait,從而使得繼承了基類(lèi)控制器的類(lèi)擁有了驗(yàn)證器的所有方法芥吟。
但是無(wú)論在控制器內(nèi)進(jìn)行驗(yàn)證澎灸,還是前置到路由器內(nèi)驗(yàn)證,都會(huì)加重這些區(qū)域的代碼重量顿肺,特別是對(duì)于復(fù)雜的驗(yàn)證邏輯戏溺,甚至使得控制器或者路由功能不那么純粹渣蜗。

img

那么有沒(méi)有什么好的設(shè)計(jì)方法,把數(shù)據(jù)驗(yàn)證獨(dú)立出來(lái)于购,統(tǒng)一管理袍睡,重復(fù)利用,不要寫(xiě)那么多臃腫的代碼呢肋僧?這就是本文我們重點(diǎn)要介紹的 FormRequest 表單請(qǐng)求類(lèi)斑胜。

代碼時(shí)間

聲明一個(gè)表單請(qǐng)求類(lèi),使用命令行腳手架可以輕松完成:

php artisan make:request CreateCommentRequest

創(chuàng)建的文件位于 app/Http/Requests/CreateCommentRequest.php嫌吠。為了與修改后的代碼有個(gè)對(duì)比止潘,我們把默認(rèn)的文件內(nèi)容貼在下方:

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class CreateCommentRequest extends FormRequest
{
    public function authorize()
    {
        return false;
    }

    public function rules()
    {
        return [];
    }
}

注意表單請(qǐng)求類(lèi)默認(rèn)繼承了 FormRequest 類(lèi),默認(rèn)的方法有兩個(gè):

第一個(gè)是 authorize 用于驗(yàn)證是否有權(quán)限使用該驗(yàn)證器辫诅,示例中始終返回 false凭戴,也就是說(shuō)任何調(diào)用,都不被允許炕矮,系統(tǒng)返回 403 狀態(tài)碼么夫。

第二個(gè)方法是 rules,用于返回一個(gè)驗(yàn)證規(guī)則組成的數(shù)組肤视。這個(gè)規(guī)則的寫(xiě)法档痪,與上一章我們介紹的規(guī)則方法毫無(wú)二致。

下面我們根據(jù)業(yè)務(wù)邏輯邢滑,首先修改 authorize 方法腐螟,滿(mǎn)足以下兩個(gè)條件,才允許驗(yàn)證:

  • 必須登錄狀態(tài)
  • 用戶(hù)必須發(fā)布過(guò)帖子

下面是代碼的實(shí)現(xiàn):

public function authorize()
{
    $blogPostId = $this->route('blogPost');
    
    if (! auth()->check()) {
        return false;
    }
    
    $isExisted = BlogPost::where('id', $blogPostId)->exists();
    if (! $isExisted) {
        return false;
    }
        
    return true;
}

大家看到了吧困后,在驗(yàn)證器內(nèi)可以橫向使用模型數(shù)據(jù)查詢(xún)乐纸,來(lái)進(jìn)行數(shù)據(jù)一致性判斷。其中還有一個(gè)潛在的知識(shí)點(diǎn)要說(shuō)一下摇予,就是代碼開(kāi)頭的那個(gè) $this->route() 方法汽绢,其實(shí)是用來(lái)獲取路由綁定參數(shù)的方法。這要求我們?cè)诼酚勺?cè)里侧戴,有類(lèi)似下面這樣的條目:

Route::post('blogPosts/{blogPost}', function () {  })

使用路由位置參數(shù)綁定傳遞的值宁昭,可以使用 $this->route()方法讀取,這與 get/post 方法的獲取有所不同救鲤,大家要記得區(qū)分久窟。

好了,授權(quán)做完了本缠,下面該驗(yàn)證規(guī)則上場(chǎng)了斥扛,一旦通過(guò)驗(yàn)證的數(shù)據(jù)進(jìn)入到驗(yàn)證環(huán)節(jié),就要執(zhí)行 rules 方法內(nèi)定義的規(guī)則,我們修改代碼如下:

public function rules()
{
    return [
        'body' => 'required|max:1000'
    ];
}

這只是一個(gè)示例啊稀颁,大家將就看一看芬失,更多驗(yàn)證規(guī)則在文檔或者源碼里,有詳細(xì)的說(shuō)明匾灶。

完成上述的表單請(qǐng)求類(lèi)之后棱烂,就可以在代碼內(nèi)引入使用了。最簡(jiǎn)單的阶女,在路由文件內(nèi)使用依賴(lài)注入實(shí)例化該類(lèi):

Route::post('blogPosts/{blogPost}/comment', function (App\Http\Requests\CreateCommentRequest $request) {
    // 存儲(chǔ)數(shù)據(jù)
});

這條路由是我們上述代碼中演示位置參數(shù) blogPost 時(shí)引入了颊糜,我們?cè)趫?zhí)行方法中引入了表單請(qǐng)求類(lèi),laravel自動(dòng)會(huì)將請(qǐng)求數(shù)據(jù)代入到該類(lèi)內(nèi)執(zhí)行驗(yàn)證秃踩。

我們使用 FormRequest 改造驗(yàn)證方法之后衬鱼,不僅引入了資源的權(quán)限判斷,還把驗(yàn)證規(guī)則獨(dú)立出來(lái)憔杨,可用于獨(dú)立維護(hù)鸟赫,或者集中管控,是不是方便多了消别?

寫(xiě)在最后

本文用了一個(gè)對(duì)博客帖子創(chuàng)建評(píng)論內(nèi)容的方法抛蚤,將驗(yàn)證規(guī)則在 FormRequest 內(nèi)實(shí)現(xiàn)。我們完全可以從最后一個(gè)寫(xiě)作方法中延伸出更多的花樣玩法寻狂,大家可以去github借鑒大神的寫(xiě)法岁经,學(xué)習(xí)更多技巧。

Happy coding :-)

我是@程序員小助手荆虱,專(zhuān)注編程知識(shí)蒿偎,圈子動(dòng)態(tài)的IT領(lǐng)域原創(chuàng)作者

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末朽们,一起剝皮案震驚了整個(gè)濱河市怀读,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌骑脱,老刑警劉巖菜枷,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異叁丧,居然都是意外死亡啤誊,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)拥娄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)蚊锹,“玉大人,你說(shuō)我怎么就攤上這事稚瘾∧道ィ” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵摊欠,是天一觀的道長(zhǎng)丢烘。 經(jīng)常有香客問(wèn)我柱宦,道長(zhǎng),這世上最難降的妖魔是什么播瞳? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任掸刊,我火速辦了婚禮,結(jié)果婚禮上赢乓,老公的妹妹穿的比我還像新娘忧侧。我一直安慰自己,他們只是感情好牌芋,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布苍柏。 她就那樣靜靜地躺著,像睡著了一般姜贡。 火紅的嫁衣襯著肌膚如雪试吁。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,679評(píng)論 1 305
  • 那天楼咳,我揣著相機(jī)與錄音熄捍,去河邊找鬼。 笑死母怜,一個(gè)胖子當(dāng)著我的面吹牛余耽,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播苹熏,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼碟贾,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了轨域?” 一聲冷哼從身側(cè)響起袱耽,我...
    開(kāi)封第一講書(shū)人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎干发,沒(méi)想到半個(gè)月后朱巨,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡枉长,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年冀续,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片必峰。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡洪唐,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出吼蚁,到底是詐尸還是另有隱情凭需,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站功炮,受9級(jí)特大地震影響溅潜,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜薪伏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一滚澜、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧嫁怀,春花似錦设捐、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至存捺,卻和暖如春槐沼,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背捌治。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工岗钩, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人肖油。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓兼吓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親森枪。 傳聞我的和親對(duì)象是個(gè)殘疾皇子视搏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355