2016-09-20 3 views
1

Я изо всех сил пытаюсь использовать прошлый квинтет часов, чтобы использовать дату Carbon в предложении where в коллекции на проекте Laravel 5.2 ... без успеха.Как использовать дату карбона в том месте, где статья в коллекции Laravel

Итак, сначала я получить коллекцию забронированы назначения на указанную дату из базы данных:

$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) говорит нуль? «start» - это объект Carbon, а $ currentTime - также Carbon.

При написании этого вопроса мой разум наконец пришел к whereLoose вместо where. Фактически результат whereLoose больше не имеет значения (это может быть решение или проблема в моем дизайне, которую я не вижу). Почему с тем же классом объекта и тем же значением предложение where не получает подтверждения?

Заранее благодарим за то, что указали мне на то, что мне не хватает здесь!

отводящий (следующий ответ Джереми)

С Laravel до 5.3, где положение в коллекции делает строгое сравнение (в то время как содержит делает рыхлый один). Это означает, что результат верен, только если сравниваемые «вещи» являются клонами друг друга. Для того, чтобы убедить себя, я прибегал к этому примеру из моего кода:

$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 клонирован, объекты действительно идентичны! К счастью, это было изменено в 5.3 в соответствии с the official upgrade doc.

ответ

1

Как вы уже выяснили, whereLoose() будет работать для вас. Причина в том, что метод буквально называет метод where() и просто передает false в качестве третьего аргумента для строгой проверки типов.

согласно documentation:

enter image description here

С нестрогого сравнения (то, что вы получаете с и whereLoose()), он будет пытаться манипулировать типы. Более конкретно, в этом случае, если объект имеет метод __toString() (например, Carbon), он может преобразовать его в строку в попытке сравнить.

Со строгим сопоставлением он не манипулирует типами и поэтому пытается сравнить один экземпляр объекта напрямую с другим, хотя один и тот же тип имеет разные данные.

С PHP object comparison строгая проверка типов с помощью === только верна, если «переменные объекта идентичны тогда и только тогда, когда они относятся к одному и тому же экземпляру того же класса».

Хороший вопрос, кстати!

+0

Большое спасибо Джереми! Я получил его сейчас: * они должны ссылаться на один и тот же экземпляр *. После 'whereLoose', если я делаю ' $ rdv = $ reservedRDVs-> whereLoose ('start', $ currentTime) -> first(); \t \t \t \t \t \t \t \t эхо '
. 'Начало '; \t \t \t \t var_dump ($ rdv-> start); // печатает объект (Carbon \ Carbon) # 377 некоторые данные \t \t \t \t echo '
'. 'Текущее время '; \t \t \t \t var_dump ($ currentTime); // печатает объект (Carbon \ Carbon) # 278 те же данные \t \t \t \t echo '
'. 'start clone'; \t \t \t \t var_dump (clone $ rdv-> start); // печатает объект (Carbon \ Carbon) # 377 некоторые данные' Так что только клон прошел бы строгое сравнение! – HelloWorld