V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
DavidNineRoc
V2EX  ›  PHP

Laravel 中优雅的验证日期需要大于今天

  •  
  •   DavidNineRoc · Sep 19, 2018 · 6133 views
    This topic created in 2788 days ago, the information mentioned may be changed or developed.
    • 我们有时会碰到一个场景,比如买车票,需要进行查询车票剩余,这时候需要一个日期范围,开始日期必须大于等于今天,结束日期必须大于等于开始日期。

    Version

    • Laravel 5.5.40
    • PHP 7.1

    开始之前,为方便查看结果,在/Exceptions/Handler.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方法写的自然不生效了,之后的验证便无法继续进行

    原文链接-Laravel 中优雅的验证日期需要大于今天

    Supplement 1  ·  Sep 19, 2018

    经 v友 指点,已经原文链接修改使用after_or_equal:today,因为today这个关键字在PHP的strtotime中是合法的关键字,可能成功转换

    30 replies    2018-09-25 14:10:03 +08:00
    update
        1
    update  
       Sep 19, 2018
    看懵了。。
    Rekkles
        2
    Rekkles  
       Sep 19, 2018
    不知道你想表达什么东西,但是你都用 Laravel 了,不用 Carbon 去做日期处理吗?
    geelaw
        3
    geelaw  
       Sep 19, 2018   ❤️ 1
    虽然我不是 PHP/Laravel 用户,但我看了如此精妙的操作之后,简单地查了一下文档:

    https://laravel.com/docs/5.4/validation#rule-after
    http://php.net/manual/en/function.strtotime.php

    为什么不能用

    'start_date' => 'required|date|after_or_equal:today'

    呢?
    icanfork
        4
    icanfork  
       Sep 19, 2018
    尾巴的外链才是重点
    但是正文真的不走心啊
    carlclone
        5
    carlclone  
       Sep 19, 2018
    楼上的几位简直打脸,楼主被暴打
    jowan
        6
    jowan  
       Sep 19, 2018
    ```
    return [
    'start_time' => 'nullable|date|after_or_equal:today',
    'finish_time' => 'nullable|date|after_or_equal:start_time',
    ];
    ```

    验证的字段必须是给定日期后的值,这个日期将会通过 PHP 函数 strtotime 来验证。
    你也可以指定其它的字段来比较日期。

    很简单明了的操作为何被你搞的这么骚
    pkoukk
        7
    pkoukk  
       Sep 19, 2018
    我不是 php 用户,我想问下这优雅么?
    cncqw
        8
    cncqw  
       Sep 19, 2018
    一顿源码分析猛如虎
    nothingtodo
        9
    nothingtodo  
       Sep 19, 2018
    @pkoukk 不优雅,明明能很简单的写个函数非得弄这么复杂,也可能是我看不懂 laravel 吧
    justfindu
        10
    justfindu  
       Sep 19, 2018
    就不能好好看一下文档么
    DavidNineRoc
        11
    DavidNineRoc  
    OP
       Sep 19, 2018
    @update 建议不要看后面的操作
    @Rekkles 楼上有正确的用法之后,真正的操作只是需要一个时间字符串做参数,让 Laravel 作比较
    @geelaw perfect
    @belin520 哈哈>_<,该怎么做才走心呢 >
    @carlclone 出来就是为了混的,没有什么打不打脸,就是学习到了
    @jowan 没跳到 getDateTimestamp 这个方法详细看,才看到调用了 strtotime
    @pkoukk 那么,实际你应该怎么做呢
    @cncqw 哈哈
    @justfindu 收到
    zavieryip
        12
    zavieryip  
       Sep 19, 2018
    自从学了 laravel,每次听到"优雅"总会自觉的替换成"恶心",大概是我境界不够
    DavidNineRoc
        13
    DavidNineRoc  
    OP
       Sep 19, 2018
    @nothingtodo 写函数很复杂的,我一般都是直接 if (@empty($_GET))

    @zavieryip 是的,对自己不喜欢的东西恶心的是对。如果对什么都有好感那人还有什么意思
    nothingtodo
        14
    nothingtodo  
       Sep 19, 2018
    @DavidNineRoc if 也很简单啊,鸟哥都吐槽 laravel 复杂,费劲
    lepig
        15
    lepig  
       Sep 19, 2018
    没全看完 只是觉得正文确实不走心

    `下图圈出的红色部分,需改成 return true 因为我们身份验证一般不在这里验证 ` 虽然我知道想表达的是什么,但是这文字描述跟图文都不匹配好吧.
    lepig
        16
    lepig  
       Sep 19, 2018
    @lepig 好吧 请无视我的评论. 原因是中间的几张图片没加载出来.导致文字和图片中描述的不相符.不过 v2 这图片看的真蛋疼,每张都必须在新标签打开才能看的清楚
    xjr1022
        17
    xjr1022  
       Sep 19, 2018
    还需要自己写吗,虽然我没用过 laravel,我记得 Yii2 就可以直接配置文件里面配置啊,laravel 那肯定也有的,再者这哪里优雅了
    DavidNineRoc
        18
    DavidNineRoc  
    OP
       Sep 19, 2018
    @lepig 确实有些蛋疼,有时候贴大图还会丢失。
    @xjr1022 有类似的,并不复杂,我在文章有一个分割线,说想去找找源码为什么在 rules 直接增加参数不生效,并分析原因。最后得出结果。
    ********************************************************
    这个框架有一个表单验证器。正常的操作只需要两步
    第一步在 request 类填写验证规则,比如 required, exists 之类的
    3L 6L 的朋友说了用 today,可以在填写验证规则的时候少写一个多余的操作

    ![]( )

    ![]( )

    就这两步,其他都是没用的东西。能看的就看,不能看的跳过就行。
    DavidNineRoc
        19
    DavidNineRoc  
    OP
       Sep 19, 2018
    @nothingtodo 这个是真理,的确看到吐槽
    alwayshere
        20
    alwayshere  
       Sep 19, 2018
    论如何化简为繁
    way2create
        21
    way2create  
       Sep 19, 2018
    一直懒得看 laravel 因为太优雅了 我比较粗鲁
    achenme
        22
    achenme  
       Sep 19, 2018
    已经看不懂 php 了。真的绕
    RorschachZZZ
        23
    RorschachZZZ  
       Sep 19, 2018
    优雅不优雅不重要,关键是很好用
    leoleoasd
        24
    leoleoasd  
       Sep 19, 2018


    没人注意到白色主题 ide 吗
    DavidNineRoc
        25
    DavidNineRoc  
    OP
       Sep 20, 2018
    @alwayshere 是的,因为你没有仔细看
    @way2create 粗鲁人好呀
    @achenme 可能吧
    @RorschachZZZ 我觉得表单验证确实好用,可能我写得乱了点。很多人没有仔细看,人云亦云
    @leoleoasd 其他颜色的 IDE 警告不显眼,不好区分。白色一眼看出来
    KgM4gLtF0shViDH3
        26
    KgM4gLtF0shViDH3  
       Sep 20, 2018
    laravel 就是用来训练看源码技能的。。楼主,请问再 Request 里面获取输入的具体的某个字段啊
    KgM4gLtF0shViDH3
        27
    KgM4gLtF0shViDH3  
       Sep 20, 2018
    @bestkayle #25 这输入法。。请问怎么在 Request 里面.....
    KgM4gLtF0shViDH3
        28
    KgM4gLtF0shViDH3  
       Sep 21, 2018
    上面那个问题太傻逼了。。当时自己把自己懵住了。
    miaotaizi
        29
    miaotaizi  
       Sep 24, 2018
    Laravel 就得"优雅"
    DavidNineRoc
        30
    DavidNineRoc  
    OP
       Sep 25, 2018
    @bestkayle 中秋都不过节的吗 >_<,表单类本身继承的 Request 类
    @miaotaizi 你说得对
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   1087 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 71ms · UTC 23:02 · PVG 07:02 · LAX 16:02 · JFK 19:02
    ♥ Do have faith in what you're doing.