0

I need to create a cron job that will run every minute and search a mysql database for all rows that have a date field that is equal to the current date and time rounded to the minute.

My problem is what is the proper query and perhaps the best way to store the event date.

The basic use case here is that I have scheduled events and I need to send a notification at the exact time those events were scheduled. This seems like a pretty common thing to do but I am having trouble figuring out if this is the best approach.

Thanks in advance.

4

2 回答 2

1

为您的调度程序创建一个工匠命令:

文件:app/commands/CheckSchedule.php

use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;

class CheckScheduleCommand extends Command {

    /**
     * The console command name.
     *
     * @var string
     */
    protected $name = 'check:schedule';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Process scheduled messages.';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct(Scheduler $scheduler)
    {
        parent::__construct();

        $this->scheduler = $scheduler;
    }

    /**
     * Execute the console command.
     *
     * @return void
     */
    public function fire()
    {
        $this->scheduler->check();
    }

}

告诉 Artisan 加载您的命令编辑文件 app\start\artisan.php 并添加:

Artisan::resolve('CheckScheduleCommand');

创建一个调度器类:

class Scheduler {

    public function check()
    {
        $date = \Carbon\Carbon::now();

        // set the seconds to 59 to get the 'whole' minute in the
        $date->second = 59;

        /// this filter will get every notification not sent from now to the past
        /// If your server got slow or something like that people will still be notified
        $notifications = Schedule::where('notify_at','<=',$date)->where('notified',false)->get();

        foreach($notifications as $notification)
        {
            $this->notify($notification);
        }
    }

    public function notify($notification)
    {
        /// do whatever you need here to notify your user;

        $notification->notified = true;
        $notification->save();
    }

}

然后通过运行测试它

php artisan check:schedule

您可以使用 cron 每分钟执行一次

* * * * * /path/to/php /var/www/project/artisan check:schedule

关于您的日期字段,您最好使用时间戳,将更容易过滤,您可以使用访问器和修改器让人们友好地使用它并仍然将其存储为时间戳: http: //laravel.com/docs/eloquent#accessors- and-mutators

于 2013-10-10T20:21:02.730 回答
0

也许你需要稍微改变一下逻辑。

你可以让它更容易,只需实现这个查询块:

... WHERE date_field <= CURRENT_TIMESTAMP() AND processed = 0;

请注意,我使用了 CURRENT_TIMESTAMP() 函数,这是因为查询速度,如果您将日期作为 unix 时间戳存储在 INTEGER 类型字段中,它将非常快

于 2013-10-10T19:20:55.840 回答