Как создать фальшивое событие с фейером dateTimeBetween? - PullRequest
1 голос
/ 28 марта 2019

Я пытаюсь создать Фабрику в Laravel, которая будет подделывать событие, созданное в календаре. Событие имеет Дата начала и Дата окончания . Я хочу, чтобы начальная дата была когда-то в будущем, а конечная дата - в течение нескольких часов после начальной даты. Я продолжаю получать одно и то же dateTime и в начале и в конце.

Я испробовал несколько различных методов, которые я нашел в Google, и все они приводят к тому, что начальная и конечная даты и время совпадают.

use Faker\Generator as Faker;

$factory->define(App\Event::class, function (Faker $faker) {

    $start_date = $faker->dateTimeBetween('+0 days', '+1 month');
    $end_date = $faker->dateTimeBetween($start_date, $start_date->modify('+5 hours'));

    $user = factory(App\User::class)->create();

    return [
        'name' => $faker->sentence,
        'description' => $faker->paragraph,
        'start_date_time' => $start_date,
        'end_date_time' => $end_date,
        'owner_id' => $user->id,
        ];
});

Я ожидаю, что начальный DateTime будет между сейчас и 1 месяцем, и, Я ожидаю, что конечный DateTime будет между начальным DateTime и 5 часами позже.

1 Ответ

0 голосов
/ 28 марта 2019

Ваша проблема на самом деле довольно проста для выявления.Вы используете один и тот же экземпляр, хранящийся в $start_date, в нескольких местах, что означает, что любое изменение этого экземпляра будет отражено во всех местах, потому что:

В PHP объекты передаютсяссылка

Это означает, что если вы создаете экземпляр DateTime, хранящийся в $start_date, а затем вызываете $start_date->modify(), это изменит значение и будет отражено во всех местах вна которую ссылается переменная.

Таким образом, вы по существу передаете те же два измененных значения $start_date, чтобы сгенерировать значение $end_date, поэтому вы получаете одинаковую дату для обоих краев диапазона.


Чтобы решить проблему с ссылками, вам нужно создать клон вашего $start_date и вызвать modify для этого, чтобы избежать изменения исходного значения:

$start_date = $faker->dateTimeBetween('+0 days', '+1 month');
$start_date_clone = clone $start_date;

$end_date = $faker->dateTimeBetween($start_date, $start_date_clone->modify('+5 hours'));

Для смягчения проблем со ссылками в PHP 5.5 введено DateTimeImmutable, которое не применяет изменения к себе.Однако реализация Faker dateTimeBetween специально проверяет, являются ли экземпляры, переданные методу, объектом DateTime (или просто обычными строками даты и времени, которые он может передать strtotime()), поэтому он не работает с DateTimeImmutable.

...