Select all rows with a date of right now [closed]

耗尽温柔 提交于 2019-12-23 04:52:47

问题


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.


回答1:


Create an artisan command for your scheduler:

file: 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();
    }

}

Tell Artisan to load your command editing file app\start\artisan.php and adding:

Artisan::resolve('CheckScheduleCommand');

Create a Scheduler class:

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();
    }

}

Then test it by running

php artisan check:schedule

And you can use cron to do it every minute

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

About your date field, you better use a timestamp, will be easier to filter and you can use acessors and mutators to make people use it friendly and still store it as timestamp: http://laravel.com/docs/eloquent#accessors-and-mutators




回答2:


maybe you need to change the logic a little bit.

you can make it much more easier, just implement this chunk of query:

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

note that I have used CURRENT_TIMESTAMP() function, its because of query speed, if you store date as an unix timestamp in INTEGER type field, it will be very fast



来源:https://stackoverflow.com/questions/19304071/select-all-rows-with-a-date-of-right-now

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!