【问题标题】:Laravel command every minute doesn't workLaravel 命令每分钟都不起作用
【发布时间】:2016-01-25 18:58:21
【问题描述】:

编辑: @Bogdan,脚本只执行了一次,正好是第二天开始前一小时,这很奇怪,还因为那天两个约会的start时间不同。然而,这两个约会都定在第二天。

所以基本上我的脚本没有检查下一小时即将到来的约会,而只是检查为明天设置的约会,并在这些约会开始前一小时发送一封电子邮件。令人困惑。另外,如果以Y-m-d H:i 格式检查时间,那么秒数不重要吗?还是我错过了什么?

操作:

我使用 laravel cronjob 和调度程序设置了一些命令。我已经得到了所有我需要工作的命令,除了一个。我有一个约会数据库,我在其中存储约会到期的时间戳。使用命令,我想在约会到期前一小时发送一封电子邮件。为此,我使用以下命令:

$schedule->command('appointment:hourly')->everyMinute();

所以它每分钟运行一次。在我的命令中,我有以下内容:

$date = Carbon::now()->addHours('1')->format('Y-m-d H:i');

$appointments = Appointment::latest('start')->date($date)->get();

因此它将日期设置为now(),然后添加一个小时并在数据库中检查该值。我的电子邮件永远不会被发送(电子邮件脚本有效,因为我对其他命令使用相同的脚本)。

我也尝试了以下方法:

$date = Carbon::now()->addHours('1')->format('Y-m-d H:i:s');

还是什么都没有。我的日期存储在数据库中,例如:

2016-01-25 09:00:00

所以不管它是否也检查以匹配秒,它应该可以工作。例如,当我检查我的$date 时,它确实返回了2016-01-25 09:00

任何指点将不胜感激。

顺便说一句,我的date() 函数。它只是根据start 列检查值:

public function scopeDate($query, $date)
{
    if($date)
    {
        return $query->whereDate('start', '=', $date);
    }
    else {
        return false;
    }
}

PS。我应该提一件事。昨晚正好是晚上 11:00,我收到了来自上述命令的两封电子邮件,说预约将在一个小时后开始。这些是设置为今天开始的约会,但它们并未设置为在 00:00 开始。所以我猜用上面的命令,它不会检查今天的约会。我很困惑,还没有弄清楚这一点。

【问题讨论】:

    标签: php date laravel command schedule


    【解决方案1】:

    这里有两点需要考虑:

    1.确保您在config/app.php 文件中设置了正确的时区,因为这可能是约会通知电子邮件在错误时间发送的原因。

    2. 从 cron 作业运行到执行 Carbon::now() 语句,时间可能与您期望的不同(这不是确定性的,而是可能会受到您的代码所做的事情和/或执行时服务器负载的影响)。所以时间可能是09:00:01 而不是09:00:00,在这种情况下,您的条件将不再成立(这是它偶尔起作用的另一个原因)。

    为了确保时差不影响条件,您应该检查时间是否距离当前时间一小时或更短,这当然需要您设置某种 标记,让您知道通知是否已发送。此外,由于whereDate 仅比较日期和时间字符串的日期部分,因此还需要处理检查时间。由于 Eloquent 没有为此提供任何方法,因此您可以将 hourminute MySQL 函数与 whereRaw 结合使用,如下所示:

    $date = Carbon::now()->addHours('1');
    
    $query->where('notified', false)
          ->whereDate('start', '=', $date->format('Y-m-d'))
          ->whereRaw('hour(start) <= ?', [$date->format('H')])
          ->whereRaw('minute(start) <= ?', [$date->format('i')]);
    

    【讨论】:

    • “为确保时差不影响条件,您应检查时间是否与当前时间相差一小时或更短”。这确实很有意义,我相信它会起作用。至于我的范围,我是这样使用它的,因为我在我的视图中也使用了那个范围,它工作得很好。如果我像你说的那样使用它,如果没有任何东西传递给范围,我的视图就不再起作用了。
    • 编辑了 OP 以简要解释一些事情,因为 cmets 不是该 imo 的方法:D
    • 刚刚做了一些测试,我添加了一些记录,其中时间是确切的日期,包括当前的小时和分钟,加上秒。进行了一些刷新测试,但没有从数据库中提取任何内容。所以出了点问题,我会弄清楚的:) 我的正确时区是在 app.php 顺便说一句设置的。我认为因为 whereDate 只检查日期,当时间被添加到组合中时,它就不再起作用了。
    • 你是正确的whereDate 只检查日期而不是时间,所以我已经用解决方案更新了答案。这也不是很清楚,为什么它在晚上 11:00 工作是完全有道理的。这是因为添加一个小时将当前日期和时间从“今天”晚上 11:00 转换为“明天”上午 00:00,因此条件成立,因为两个整体都将start 日期设置为第二天(时间是没有比较,所以两个条目都匹配)。
    • 是的,这也击中了我 :) 我只需要拿起手机看看我是否正确。现在回去睡觉,我会尽快解决这个问题并接受你的回答:)谢谢!
    猜你喜欢
    • 2020-02-15
    • 2021-06-04
    • 1970-01-01
    • 1970-01-01
    • 2013-09-25
    • 2015-09-24
    • 2022-01-12
    • 2013-10-14
    • 2015-02-25
    相关资源
    最近更新 更多