繁体   English   中英

如何在 Laravel Collection 的 where 子句中使用 Carbon 日期

[英]How to use Carbon date in where clause in Laravel Collection

在过去的五个小时里,我一直在努力在 Laravel 5.2 项目的集合的 where 子句中使用 Carbon date ……但没有成功。

所以首先我从数据库中检索给定日期的预订约会集合:

 $bookedRDVs = RDV::where('idAgenda', $idAgenda)
                    ->whereDate('start', "=", $date)
                    ->get();

然后我有一个营业时间 ([businessStart ; businessEnd]) 内的时间段列表(固定持续时间),我想将它们标记为免费与否。

$currentTime = $businessStart->copy(); // $businessStart is a Carbon date

while($currentTime < $businessEnd){
    echo 'start is an object of class ' . get_class($bookedRDVs->first()->start); // start is an object of class Carbon\Carbon
    echo 'currentTime is an object of class ' . get_class($currentTime); // currentTime is an object of class Carbon\Carbon


    if($bookedRDVs->contains('start', $currentTime) ) {
        $rdv = $bookedRDVs->where('start', $currentTime)->first();
        var_dump($rdv); // prints NULL => why ?
    } //end if
} // end while

为什么$bookedRDVs->contains('start', $currentTime)说 true ,但是$bookedRDVs->where('start', $currentTime)说 null ? 'start' 是 Carbon 对象,$currentTime 也是 Carbon。

在写这个问题时,我的思绪终于来到了whereLoose而不是where 实际上whereLoose的结果whereLoose为空(因此它可能是解决方案,或者我的设计中存在我看不到的问题)。 为什么使用相同的对象类和相同的值 where 子句没有得到验证?

提前感谢您指出我在这里缺少的东西!

外卖(按照杰里米的回答)

在 5.3 之前的 Laravel 中,Collection 中的 where 子句进行了严格的比较(而 contains 进行了松散的比较)。 这意味着只有当比较的“事物”是彼此的克隆时,结果才为真。 为了说服自己,我从我的代码中使用了这个例子:

 $rdv = $bookedRDVs->whereLoose('start', $currentTime)->first(); 
 echo '</br>' . 'start '; 
 var_dump($rdv->start); // prints object(Carbon\Carbon)#377 (3) { ["date"]=> string(26) "2016-09-13 09:20:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> string(3) "UTC" } 


 echo '</br>' . 'currentTime '; 
 var_dump($currentTime); // prints object(Carbon\Carbon)#278 (3) { ["date"]=> string(26) "2016-09-13 09:20:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> string(3) "UTC" }


 echo '</br>' . ' start clone '; 
 var_dump(clone $rdv->start); // prints object(Carbon\Carbon)#377 (3) { ["date"]=> string(26) "2016-09-13 09:20:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> string(3) "UTC" } 

所以$rdv->start$currentTime之间的唯一区别是$rdv->start号后面的数字(详见此处) 当这些数字不同时,这意味着该对象不是来自同一实例。 如果$rdv->start被克隆,那么对象真的是相同的! 幸运的是,根据官方升级文档,这已在 5.3 中更改。

正如您所发现的, whereLoose()对您whereLoose() 原因是该方法从字面上调用where()方法,并且只是将false作为严格类型检查的第三个参数传递。

根据文档

在此处输入图片说明

通过非严格比较(您使用contains()whereLoose() ),它将尝试处理类型。 更具体地说,在这种情况下,如果对象具有__toString()方法(就像 Carbon 一样),它可以将其转换为字符串以尝试进行比较。

通过严格比较,它不会处理类型,因此尝试将一个对象实例直接与另一个对象实例进行比较,尽管类型相同,但具有不同的数据。

使用PHP 对象比较,如果“对象变量相同,当且仅当它们引用同一类的同一实例”时,使用===严格类型检查才为真。

顺便问一下好问题!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM