如何在Laravel Collection

时间:2016-09-20 20:03:09

标签: php laravel-5.2 php-carbon

我一直在努力争取过去几个小时的时间,在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)表示正确,但$bookedRDVs->where('start', $currentTime)为空? &#39;启动&#39;是Carbon对象,$ currentTime也是Carbon。

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

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

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

使用Laravel 5.3之前,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之间的唯一区别是哈希符号(see here for details)后面的数字。当这些数字不同时,意味着该对象不是来自同一个实例。如果克隆$rdv->start那么对象真的相同!幸运的是,根据the official upgrade doc,这已在5.3中进行了更改。

1 个答案:

答案 0 :(得分:1)

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

根据documentation

enter image description here

通过非严格比较(您使用contains()whereLoose()获得的内容),它将尝试处理这些类型。更具体地说,在这种情况下,如果对象具有__toString()方法(如Carbon所做的那样),它可以将其转换为字符串以尝试比较。

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

对于PHP object comparison,仅当“对象变量相同且当且它们引用同一类的同一实例时”对象变量是相同的时,才使用===进行严格类型检查。

顺便提一下好问题!