如何使用伪造者dateTimeBetween创建伪造事件?

时间:2019-03-28 14:30:16

标签: php laravel datetime faker

我正在尝试在Laravel中创建一个Factory,该工厂将伪造在日历上创建的事件。该事件具有开始日期时间结束日期时间。我希望开始日期是现在以后的某个时间,结束日期时间在开始日期时间的几个小时之内。我在开始和结束时都得到相同的dateTime。

我尝试了一些从Google找到的不同方法,这些方法都导致开始和结束dateTimes相同。

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,
        ];
});

我希望开始日期时间介于现在和1个月之间, 我希望结束日期时间在开始日期时间和5小时后之间。

1 个答案:

答案 0 :(得分:0)

您的问题实际上很容易确定。您正在多个位置使用存储在$start_date中的同一实例,这意味着对该实例的任何更改都将反映在所有位置,因为:

  

In PHP objects are passed by reference

这意味着,如果您创建存储在DateTime中的$start_date实例,然后调用$start_date->modify(),它将修改该值并将反映在变量所处的所有位置引用。

因此,您实际上要传递相同的两个修改后的$start_date值以生成$end_date值,这就是为什么两个范围边都得到相同日期的原因。


要解决参考问题,您应$start_date中的create a clone,然后致电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合作。