Laravel中優雅的驗證日期須要大於今天

  • 咱們有時會碰到一個場景,好比買車票,須要進行查詢車票剩餘,這時候須要一個日期範圍,開始日期必須大於等於今天,結束日期必須大於等於開始日期。

Version

  • Laravel 5.5.40
  • PHP 7.1

開始以前,爲方便查看結果,在/Exceptions/Handler.php文件捕獲了異常

那麼咱們開始作一個驗證吧:php

  • 新建一個request並注入到須要驗證控制器的方法

  • 下圖圈出的紅色部分,需改爲return true由於咱們身份驗證通常不在這裏驗證

  • 如上圖,end_date能夠很簡單的經過start_date來限制時間範圍,那麼start_date該怎麼驗證呢?我原本想的是這樣的。

  • 經過增長一個額外的字段curr_date,而後start_date經過這個字段限制範圍。測試發現實際並不生效。直接進入了控制器打印的數據

  • 調試了一下,我在Illuminate\Validation\Concerns、ValidatesAttributes::validateAfterOrEqual方法跳到compareDates方法,並嘗試打印了$this->getValue($parameters[0])這時候的$paramters[0]curr_date老是null


  • 而後查閱了一下源碼,知道了緣由,直接說能正確驗證的方法,再說詳細的過程。
  • 正確的方法是這樣的

  • 重寫父類的prepareForValidation方法,以後再測試

  • 這時候獲得想要的驗證了

  • 分析一下過程
  • 能經過依賴注入實例化咱們想要的對象,這一切都得感謝LaravelIoC容器
  • 容器每次解析完新對象以後,老是會釋放一些綁定的事件

  • 這些事件不少都是經過服務提供者來綁定的,咱們直接查看config/app.php裏有關表單驗證的服務提供者



  • 咱們能夠看到當實現ValidatesWhenResolved對象的類在解析以後會自動調用validate方法
  • 回到新建的IndexTicketRequest類,沒有這個方法,去到父類,發現實現了ValidatesWhenResolved,而validate是在traitValidatesWhenResolvedTrait

  • 這個類找到了答案,在validate方法裏分三步主要的
  • $this->prepareForValidation() 在驗證以前的準備
  • 新建一個驗證明例
  • 開始驗證
  • 之因此是須要在驗證以前設置curr_date,咱們來看看新建驗證明例便知道答案


  • 這裏有一個地方致使咱們的問題出現,就是先調用了$this->validationData()方法拿到request的數據,而後再經過$this->container->call([$this, 'rules'])拿到驗證規則,因此咱們在rules方法寫的天然不生效了,以後的驗證便沒法繼續進行
相關文章
相關標籤/搜索