Я хочу, чтобы все пользователи были созданы на указанную дату:
// $date is a Carbon instance parsed from command line argument.
// I checked it and it is correct.
$users = User::where('created_at', '>', $date->startOfDay())
->where('created_at', '<', $date->endOfDay())
->get();
Но это возвращает 0 результатов, тогда как в базе данных есть строки, соответствующие этой дате.
Что я делаю неправильно?
Carbon
не ведет себя как объект значения (т. е. он не является неизменным), так что это:
$date->startOfDay();
$date->endOfDay();
просто модифицирует $date
объект и возвращает его обратно. При этом строка, которая передается в запрос, получается, когда PDO
связывает это в подготовленном утверждении, когда $date
уже мутирован в endOfDay
,
Это означает, что вы просто передаете ссылку на объект:
$start === $end; // true
Так что либо используйте разные объекты:
$users = User::where('created_at', '>', $date->copy()->startOfDay())
->where('created_at', '<', $date->copy()->endOfDay())
->get();
или просто верните нужную строку вместо Carbon
объект:
$users = User::where('created_at', '>', $date->startOfDay()->toDateTimeString())
->where('created_at', '<', $date->endOfDay()->toDateTimeString())
->get();
еще, $date
теперь будет держать xxxx-xx-xx 23:59:59
отметка времени, так что имейте это в виду, если вам нужно работать с этой переменной где-то еще.
Проблема здесь не в самом Laravel, а в Carbon.
При использовании следующего кода:
use Carbon\Carbon;
$date = new Carbon('2014-10-07');
$start = $date->startOfDay();
$end = $date->endOfDay();
echo $start.' '.$end;
что вы получаете:
2014-10-07 23:59:59 2014-10-07 23:59:59
поэтому Laravel выполнит запрос:
select * from `users` where `created_at` >'2014-10-07 23:59:59' and `created_at` <'2014-10-07 23:59:59';
и, очевидно, вы не получите никаких результатов.
Как вы видите $start
результат не то, что вы ожидаете здесь.
чтобы заставить его работать, я нашел решение, которое создает 2 углеродных объекта:
use Carbon\Carbon;
$date = new Carbon('2014-10-07');
$date2 = new Carbon('2014-10-07');
$start = $date->startOfDay();
$end = $date2->endOfDay();
echo $start.' '.$end;
Теперь результат, как и ожидалось:
2014-10-07 00:00:00 2014-10-07 23:59:59
Теперь вы можете использовать:
use Carbon\Carbon;
$date = new Carbon('2014-10-07');
$date2 = new Carbon('2014-10-07');
$users = User::where('created_at', '>', $date->startOfDay())
->where('created_at', '<', $date2->endOfDay())
->get();
или же
use Carbon\Carbon;
$date = new Carbon('2014-10-07');
$date2 = new Carbon('2014-10-07');
$users = User::whereBetween('created_at', [$date->startOfDay(), $date2->endOfDay()])->get();
В вашем запросе осталось имя таблицы:
$users = DB::table('users')
->where('votes', '>', 100)
->orWhere('name', 'John')
->get();
Посмотрите: http://laravel.com/docs/4.2/queries#selects