使用Laravel管理Cronjobs

本文介绍了如何在PHP应用程序中,特别是使用Laravel框架,来创建和调度任务。文章探讨了Cron的基础知识,如何在Laravel中创建Artisan命令,并详细说明了如何通过Laravel任务调度器安排这些命令的执行,以及如何启动Laravel调度器。
摘要由CSDN通过智能技术生成

There are times when your application needs to run administrative tasks periodically on the server. Whether you want to send out emails to your users or clean up the database tables at the end of the day, you will need a task scheduling mechanism to take care of the tasks, when it’s time.

有时,您的应用程序需要定期在服务器上运行管理任务。 无论您是想在一天结束时向用户发送电子邮件还是清理数据库表,您都需要一种任务调度机制来在需要时处理任务。

Cron is a task scheduler in unix-like systems, which runs shell commands at certain intervals. This article is not meant for introducing Cron, but since it is a key concept in our tutorial, we’ll will describe the basics of how it works.

Cron是类Unix系统中的任务调度程序,它以特定间隔运行shell命令。 本文并非旨在介绍Cron,但由于它是本教程中的关键概念,因此我们将介绍其工作原理。

A clock

Cron基础 (Cron basics)

Cron is a task scheduler daemon which runs scheduled tasks at certain intervals. Cron uses a configuration file called crontab, also known as cron table, to manage the scheduling process.

Cron是一个任务计划程序守护程序,它以一定的时间间隔运行计划的任务。 Cron使用称为crontab的配置文件(也称为cron表)来管理调度过程。

Crontab contains cron jobs, each related to a specific task. Cron jobs are composed of two parts, the cron expression, and a shell command to be run:

Crontab包含cron作业,每个作业都与特定任务相关。 Cron作业由两部分组成:cron表达式和要运行的shell命令:

* * * * * command/to/run

Each field in the above expression (* * * * *) is an option for setting the schedule frequency. It is composed of minute, hour, day of month, month and day of week in order of the placement. The asterisk symbol refers to all possible values for the respective field. As a result, the above cron job will be run every minute in the day.

上面的表达式( * * * * * )中的每个字段都是用于设置计划频率的选项。 它由分钟,小时,每月的某天,每月的某天和一周的某天组成。 星号表示相应字段的所有可能值。 因此,以上cron作业将在一天中的每一分钟运行。

The following cron job is executed at 12:30 every day:

每天12:30执行以下cron作业:

30 12 * * * command/to/run

This is just the tip of the Cron iceberg; to learn more about it, you might want to visit the wikipedia page.

这只是Cron冰山一角。 要了解更多信息,您可能需要访问Wikipedia页面。

In PHP powered applications, administrative tasks are normally standalone PHP scripts which are run in CLI mode. These scripts are written for performing different jobs at certain times.

在PHP驱动的应用程序中,管理任务通常是在CLI模式下运行的独立PHP脚本。 编写这些脚本是为了在特定时间执行不同的工作。

However, we can’t do much without the power of other PHP libraries and frameworks. In this article, you will learn how to use the Laravel framework to create robust PHP scripts for the command line and schedule them right from the source code.

但是,如果没有其他PHP库和框架的强大功能,我们将无能为力。 在本文中,您将学习如何使用Laravel框架为命令行创建健壮PHP脚本,并直接从源代码计划它们。

在Laravel中创建命令 (Creating Commands in Laravel)

Creating a command in PHP is as simple as creating a PHP script, then running it in the command line, using the php command:

用PHP创建命令就像创建PHP脚本一样简单,然后使用php命令在命令行中运行它:

php somefile.php

As you can see, the file is passed as an argument to the command php.

如您所见,该文件作为参数传递给命令php

Whether your application has been developed in Laravel, or you just want to use its facades and helpers to create your scripts, you will need to bootstrap Laravel before using it. However, there’s a better alternative to this: creating a Laravel Artisan command.

无论您的应用程序是在Laravel中开发的,还是只想使用其外观和助手来创建脚本,您都需要在使用Laravel之前对其进行引导。 但是,还有一个更好的选择:创建Laravel Artisan命令。

When using Artisan commands, we will have access to all features of Laravel, including helpers, facades, and other Artisan commands, just to name a few.

使用Artisan命令时,我们将可以访问Laravel的所有功能,包括助手,立面和其他Artisan命令,仅举几例。

We’re not going to go into the details of Artisan commands here, as they’re beyond the scope of this tutorial, but let’s discuss the basics, just to get started. We’ll will be using the latest version of Laravel, which is 5.1 at the time of writing this article.

我们不在这里讨论Artisan命令的详细信息,因为它们超出了本教程的范围,但是让我们讨论基础知识只是为了开始。 在撰写本文时,我们将使用Laravel的最新版本,即5.1

We use the make:console Artisan command to generate a command class skeleton to work with. As an example, we’re going to create a command which sends a happy birthday SMS message to our users on their birthday.

我们使用make:console Artisan命令来生成要使用的命令类框架。 作为示例,我们将创建一个命令,该命令在用户生日那天向我们的用户发送生日快乐SMS消息。

$ php artisan make:console HappyBirthday --command=sms:birthday

The above command will create a class named HappyBirthday in a file of the same name in the app/Console/Commands directory. We also picked a name for the command via the command option. This is the name that we’ll use when calling the command.

上面的命令将在app/Console/Commands目录中的同名文件中创建一个名为HappyBirthday的类。 我们还通过command选项为命令选择了一个名称。 这是我们在调用命令时要使用的名称。

Now let’s open the file, and see what we have so far. There are several properties and methods inside the class that build the command’s backend:

现在,我们打开文件,看看到目前为止。 类内部有几个属性和方法可以构建命令的后端:

<?php
namespace App\Console\Commands;

use Illuminate\Console\Command;

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

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description.';

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

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        //
    }
}

For the $description, we can put a simple description of what the command does when executed.

对于$description ,我们可以对命令执行时的操作进行简单描述。

protected $description = 'Sends a Happy birthday message to users via SMS';

In Laravel 5.1, whenever a command is executed in the terminal, the handle method of the command class is called. That’s where we need to put our logic.

在Laravel 5.1 ,无论何时在终端中执行命令,都会调用命令类的handle方法。 那就是我们需要提出逻辑的地方。

In our case, to send a birthday message to users on their birthday, we can modify handle method like so:

在我们的情况下,要向用户发送生日消息,我们可以像下面这样修改handle方法:

<?php
// ...
public function handle()
{
  User::whereBirthDate(date('m/d'))->get(); 

  foreach( $users as $user ) {
    if($user->has('cellphone')) {
    SMS::to($user->cellphone)
       ->msg('Dear ' . $user->fname . ', I wish you a happy birthday!')
       ->send();
    }   
}  

$this->info('The happy birthday messages were sent successfully!');

}

Once the command is finished, we need to register it with Artisan, so that it will be available in the terminal. To do this, we just need to add the command’s classname to the commands array of theKernel class, which is located at app/Console/Kernel.php:

命令完成后,我们需要在Artisan中注册它,以便在终端中可用。 为此,我们只需要将命令的类名添加到位于app/Console/Kernel.phpKernel类的commands数组中:

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

    // ...

If we run php artisan list in the terminal, we will see our command’s description:

如果在终端中运行php artisan list ,我们将看到命令的描述:

$ php artisan list

...
sms
  sms:birthday        Sends a Happy birthday to users via SMS
...

It’s a good habit to namespace the command names. This will help us categorize them based on their usage.

给命令名称命名空间是一个好习惯。 这将帮助我们根据使用情况对它们进行分类。

As a result, whenever we run the command in the terminal, a happy birthday message would be sent to the matched group of users:

结果,每当我们在终端中运行命令时,就会向匹配的用户组发送生日快乐消息:

$ php artisan sms:birthday

The happy birthday messages were sent successfully!

This is just a hypothetical use case. For a more concrete example, see Younes Rafie’s post about a minification command.

这只是一个假设的用例。 有关更具体的示例,请参见Younes Rafie的有关缩小命令的文章

安排命令 (Scheduling the Commands)

Here comes the fun part. Let’s schedule a task for running the command we just built. To do this, we’ll use a feature you’ll undoubtedly come to love: Laravel Task Scheduler.

这里是有趣的部分。 让我们安排一个任务来运行我们刚刚构建的命令。 为此,我们将使用您肯定会喜欢的功能:Laravel Task Scheduler。

The tasks are defined inside the schedule method of the Kernel class. We can add as many Artisan commands as we need by using the command method.

这些任务在Kernel类的schedule方法内部定义。 通过使用command方法,我们可以根据需要添加任意数量的Artisan命令。

Our task, according to its usage, is supposed to be run once a day. So we can use the daily() method like so:

根据其用途,我们的任务应该每天运行一次。 因此,我们可以像这样使用daily()方法:

<?php

// ...

protected function schedule(Schedule $schedule)
{   
        $schedule->command('sms:birthday')->daily();
}

We can schedule all the commands right from the schedule method. As the documentation states, there are a variety of schedule frequencies we may assign to the tasks. We’ll list a few of them here, but you may want to read the documentation to see the full list and decide which best suits your circumstances.

我们可以直接从schedule方法安排所有命令。 如文档所述,我们可以为任务分配各种计划频率。 我们将在此处列出其中的一些,但是您可能需要阅读文档以查看完整列表,并确定最适合您的情况。

To run a task every hour every day:

每天每小时运行一个任务:

<?php
$schedule->command('myTask')
         ->hourly();

To run a task every day at midnight:

要每天在午夜运行任务:

<?php
$schedule->command('myTask')
         ->daily();

To run a task every day at 9:30:

要每天在9:30运行任务:

<?php
$schedule->command('myTask')
         ->dailyAt('09:30');

To run a task every week:

每周运行一项任务:

<?php
$schedule->command('myTask')
         ->weekly();

To run it every month:

每月运行:

<?php
$schedule->command('myTask')
         ->monthly();

We can also use a custom cron schedule, like an ordinary cron job expression:

我们还可以使用自定义cron时间表,例如普通的cron作业表达式:

$schedule->command('myTask')
         ->cron('* * * * *');

The above task will be run every minute.

以上任务将每分钟运行一次。

To see the full list of options, please refer to the documentation, section Schedule Frequency Options.

要查看选项的完整列表,请参阅文档的“ 计划频率选项”部分。

Laravel also provides a set of schedule constraints, which can be combined with the above methods. For instance, we can schedule a task to be run weekly, but limit it to a certain day and hour.

Laravel还提供了一组计划约束,可以与上述方法结合使用。 例如,我们可以将任务安排为每周运行,但将其限制为特定的日期和时间。

<?php
$schedule->command('theTask')
         ->weekly()
         ->mondays()
         ->at(12:30);

or

要么

<?php
$schedule->command('theTask')
         ->weekly()
         ->sundays()

We can go further and limit the execution of the task to a certain condition, using the when method which accepts a closure. The task will be executed only if the closure returns true.

我们可以使用接受闭包的when方法,进一步将任务的执行限制在一定条件下。 当闭包返回true时,才会执行任务。

<?php
$schedule->command('table:clean')
          ->daily()
          ->when(function() {
             return SMS::isWorkingFine();
          });

启动Laravel Scheduler (Starting the Laravel Scheduler)

To start the scheduler itself, we only need to add one cron job on the server (using the crontab -e command), which executes php /path/to/artisan schedule:run every minute in the day:

要启动调度程序本身,我们只需要在服务器上添加一个cron作业(使用crontab -e命令),该作业就会执行php /path/to/artisan schedule:run 每天 php /path/to/artisan schedule:run 一分钟

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

Please note that we need to provide the full path to the Artisan command of our Laravel installation.

请注意,我们需要提供Laravel安装中Artisan命令的完整路径

To discard the cron output we put /dev/null 2>&1 at the end of the cronjob expression.

要丢弃cron输出,我们将/dev/null 2>&1放在cronjob表达式的末尾。

To read more about the Scheduler, see the Scheduling chapter in the documentation.

要了解有关调度程序的更多信息,请参阅文档中的“ 调度”一章。

结论 (Conclusion)

In this tutorial, we made use of Laravel Artisan commands to create terminal commands. Rather than add many cron job entries on the server per task, we only created one which is executed every minute and delegates responsibility to Laravel’s task scheduler.

在本教程中,我们使用了Laravel Artisan命令来创建终端命令。 我们没有为每个任务在服务器上添加许多cron作业条目,而是仅创建一个每分钟执行一次并将任务委托给Laravel的任务计划程序的任务。

By using custom Artisan commands alongside Laravel’s task scheduler, we can focus on creating the commands and Laravel will take care of the rest. In addition to this, the scheduling frequencies are manageable by other team members since it is now tracked by the version control system.

通过将自定义Artisan命令与Laravel的任务计划程序一起使用,我们可以专注于创建命令,Laravel将负责其余的工作。 除此之外,调度频率可以由其他团队成员管理,因为现在版本控制系统可以跟踪它。

If you have an questions or comments, please post them below and we’ll do our best to reply in a timely manner.

如果您有任何问题或意见,请在下面发布,我们将尽力及时答复。

翻译自: https://www.sitepoint.com/managing-cronjobs-with-laravel/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值