使用Laravel 5.6运行cronjob(使用Scheduler)

时间:2018-07-04 12:37:50

标签: php laravel laravel-5

在我的应用程序中,我有一些任务应按设置的时间间隔自动运行。因此,我立即想到:我可以在服务器上执行cron作业。

我从阅读几篇文章开始:

以及有关计划的Laravel文档。

我正在尝试将Facebook和Twitter帖子从API提取到数据库中。

更新Facebook和Twitter

<?php
namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;

use App\Article;
use App\TwitterPost;
use App\FacebookPost;
use Twitter;

class UpdateSocial extends Command
{
  /**
   * The name and signature of the console command.
   *
   * @var string
   */
  protected $signature = 'update:social';

  /**
   * The console command description.
   *
   * @var string
   */
  protected $description = 'Updates facebook and twitter feeds to DB';

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

  public function updateFacebook()
  {

      //Access token
      $access_token = 'secret';
      //Request the public posts.
      $json_str = file_get_contents('https://graph.facebook.com/v3.0/NewableGroup/feed?access_token='.$access_token);
      //Decode json string into array
      $facebookData = json_decode($json_str);

      //For each facebook post
      foreach($facebookData->data as $data){

          //Convert provided date to appropriate date format
          $fbDate = date("Y-m-d H:i:s", strtotime($data->created_time));
          $fbDateToStr = strtotime($fbDate);

          //If a post contains any text
          if(isset($data->message)){

            //Create new facebook post if it does not already exist in the DB
            $facebookPost = FacebookPost::firstOrCreate(
                  ['post_id' => $data->id], ['created_at' => $fbDateToStr, 'content' => $data->message, 'featuredImage' => null]
            );

            //Output any new facebook posts to the console.
            if($facebookPost->wasRecentlyCreated){
                $this->info("New Facebook Post Added --- " . $facebookPost->content);
             }

          }

      }

  }

  public function updateTwitter($amount)
  {

      $twitterData = Twitter::getUserTimeline(['count' => $amount, 'tweet_mode'=>'extended', 'format' => 'array']);

      foreach($twitterData as $data){

          //Convert provided date to appropriate date format
          $tweetDate = date("Y-m-d H:i:s", strtotime($data['created_at']));
          $tweetDateToStr = strtotime($tweetDate);
          $tweetImg = null;

          //Get the twitter image if any
          if(!empty($data['extended_entities']['media']))
          {
              foreach($data['extended_entities']['media'] as $v){
                  $tweetImg = $v['media_url'];
              }
          }

          //Create new tweet if it does not already exist in the DB
          $twitterPost = TwitterPost::firstOrCreate(
              ['post_id' => $data['id']], ['created_at' => $tweetDateToStr, 'content' => $data['full_text'], 'featuredImage' => $tweetImg]
          );

          //Output any new twitter posts to the console.
          if($twitterPost->wasRecentlyCreated){
             $this->info("New Tweet Added --- " . $twitterPost->content);
          }

      }

  }

  /**
   * Execute the console command.
   *
   * @return mixed
   */
  public function handle()
  {
    $this->updateFacebook();
    $this->updateTwitter(20);
  }
}

这是Laravel中的控制台命令,已在Kernal.php中注册

<?php

namespace App\Console;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{
    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
        'App\Console\Commands\UpdateSocial'
    ];

    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        $schedule->command('update:social')->everyTenMinutes();
    }

    /**
     * Register the commands for the application.
     *
     * @return void
     */
    protected function commands()
    {
        $this->load(__DIR__.'/Commands');

        require base_path('routes/console.php');
    }
}

这使我能够运行命令:php artisan update:social,但是,很明显,要自动执行该命令,我需要在服务器上设置cron作业。

文档在某些地方重复了这一行:

* * * * * php /path-to-your-project/artisan schedule:run >> /dev/null 2>&1

我知道* * * * *相当于每天的每一分钟,schedule:run的含义很明显,但是最后一部分是什么?

这部分专门:

>> /dev/null 2>&1

而且,即使它仅每10分钟运行一次,为什么还要在服务器上每分钟运行一次?

还可以使用相同的设置在xxamp之类的本地服务器上运行这些作业吗?

更新

另一个用户提供了一个很棒的链接:https://unix.stackexchange.com/questions/163352/what-does-dev-null-21-mean-in-this-article-of-crontab-basics

这很好地解释了cronjob命令的最后一部分。

图片供参考:

enter image description here

1 个答案:

答案 0 :(得分:1)

您正在使用xamp,所以我假设您在Windows上。建议您下载并安装https://sourceforge.net/projects/cronw/ 然后,您可以使用Unix样式的cronjobs来运行作业。

您也可以考虑使用Windows任务计划程序,但是在我看来,使用cron计划程序效果更好,因为Windows任务计划程序每5分钟仅允许触发一次。

您还需要按照INSTALL文件中的说明进行启动和运行。但是一旦运行,就像unix crontab的

一样,它很容易管理。

您每分钟运行一次Laravel scheduler,但是Laravel计划程序随后会调查计划中需要运行的内容。

您有Cron触发了调度程序。
然后您的调度程序将其加载。
迭代那些并过滤掉尚未调度的
执行易调度的作业。

Cron只是启动调度程序以查看是否有任何可能运行的待处理作业的方法。

如果您只想运行artisan命令而不使用调度程序服务,则不必每分钟运行一次,但是可以让cron作业每10分钟运行一次。

我个人建议执行一个scheduler作业,因为如果前一个进程尚未完成,您可以不执行它,而同时停止两个进程。

>> /dev/null 2>&1作为https://unix.stackexchange.com/questions/163352/what-does-dev-null-21-mean-in-this-article-of-crontab-basics的评论在链接rkj中发布,这是一种简单的方法,可以防止将自动电子邮件作为状态报告发送给您。