在 Laravel 个观察者中使用自定义 for 循环

Using custom for loop inside Laravel Observers

我想在更新事件发生时开始倒计时,并根据 laravel 5.8 API 应用程序中的特定条件更新其他字段。

基本上,这些是我想要完成的步骤

  1. 当订单 table orderStatus 字段更新为 processing 时,开始倒计时 12 分钟。

  2. 在倒计时期间,如果订单 table paymentStatus 字段从 pending 获得更新,则停止倒计时并将 orderStatus 更新为 completed.

  3. 在倒计时结束时,如果订单 paymentStatus 仍处于待处理状态,则将 orderStatus 更新为 completed 并将 paymentStatus 更新为 aborted.

为了实现这一点,我制作了一个 OrderObserver 来侦听更新事件并尝试了这段代码

public function updated(Order $order)
{
    if ($order->paymentStatus == 'paid') {

        $order->update(['orderStatus' => 'completed']);
    }

    if ($order->paymentStatus == 'processing') {

        // start a timeout function
        for ($orderedAt = $order->created_at; $orderedAt <= $orderedAt->addMinutes(12); $orderedAt->addSecond()) {
            if ($order->paymentStatus !== 'pending') {
                $order->update(['orderStatus' => 'completed']);
                break;
            }

            if ($orderedAt == $orderedAt->addMinutes(12)) {
                $order->update(['orderStatus' => 'completed', 'paymentStatus' => 'aborted']);
                break;
            }
        }
    }
}

显然,第一个 if 块工作正常,但第二个没有。 created_at 时间 12 分钟后,orderStatuspaymentStatus 都没有更新。

我觉得for循环是错误的,但我还没有找到正确的方法。

如何使用 OrderObserver 更新事件实现上述步骤?

我认为您误解了 addMinutes 方法的作用。 created_at 属性是一个 Carbon 对象,不是吗?如果是这样,addMinutes只是计算时间总和并更改属性值。 addSecond 做同样的事情,但需要几秒钟。

如果你想要一个长运行脚本,你将不得不使用睡眠调用来停止进程几秒钟。

但是,IMO 的最佳解决方案是,您应该创建一个 cronb 作业并每分钟检查一次订单是否处于 pending 状态 12 分钟,然后更改状态。

看看https://laravel.com/docs/5.8/scheduling