在本文中,我们将介绍Laravel Web框架的令人兴奋的功能之一-任务调度。 在本文的整个过程中,我们将研究Laravel如何允许您管理应用程序中的计划任务。 此外,我们还将最终创建用于演示目的的自定义计划任务。
Laravel框架允许您设置计划的任务,因此您不必担心在系统级别设置它们。 您可以在设置计划任务时摆脱那种复杂的cron语法,因为Laravel允许您以用户友好的方式定义它们。
我们将从您如何习惯于设置传统的cron作业开始,然后,我们将探索Laravel实现它的方式。 在本文的后半部分,我们将通过创建几个自定义的计划任务来进行尝试,这些任务应该提供对该主题的动手理解。
传统计划任务设置
在日常应用程序开发中,经常会遇到需要定期执行某些脚本或命令的情况。 如果您正在使用* nix系统,则可能知道cron作业会处理这些命令。 另一方面,它们在基于Windows的系统上被称为计划任务。
让我们快速看一下基于* nix的cron作业的简单示例。
*/5 * * * * /web/statistics.sh
非常简单-它每五分钟运行一次statistics.sh
文件!
尽管那是一个非常简单的用例,但您常常会发现自己处在需要实施更复杂的用例的情况下。 另一方面,复杂的系统要求您定义以不同时间间隔运行的多个cron作业。
让我们看看复杂的Web应用程序必须在后端定期执行的一些任务。
- 从数据库后端清除不必要的数据。
- 更新前端缓存索引以使其保持最新。
- 计算站点统计信息。
- 发电子邮件。
- 备份不同的站点元素。
- 生成报告。
- 和更多。
因此,正如您所看到的,有很多东西等待定期运行,并且也要在不同的时间间隔运行。 如果您是经验丰富的系统管理员,那么为您定义所有这些任务的cron任务很容易,但是有时作为开发人员的我们希望有一个更简单的方法。
幸运的是,Laravel带有内置的任务计划 API,使您可以定义前所未有的计划任务。 是的,下一部分将讨论所有这些-Laravel任务调度的基础。
Laravel方式
在前面的部分中,我们介绍了设置cron作业的传统方法。 在本节中,我们将在任务计划API的上下文中详细介绍Laravel。
在继续之前,需要了解的重要一点是,Laravel提供的调度功能与任何其他功能一样,不会自动调用。 因此,如果您认为您不需要在系统级别执行任何操作,那么您就不走运了。
实际上,如果您希望使用Laravel调度系统,您应该做的第一件事就是设置每分钟运行一次的cron作业,并调用以下代码片段中所示的artisan命令。
* * * * * php /path-to-your-project/artisan schedule:run >> /dev/null 2>&1
上面的artisan命令调用Laravel调度程序,然后依次执行您的应用程序中定义的所有挂起的cron作业。
当然,我们还没有看到如何在Laravel应用程序中定义计划的任务,这是我们接下来要研究的内容。
如果要定义特定于应用程序的计划任务,则需要使用App\Console\Kernel
类的schedule
方法。
继续并获取app/Console/Kernel.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\Inspire',
];
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
$schedule->command('inspire')->hourly();
}
}
如您所见,核心代码本身提供了一个有用的示例。 在上面的示例中,Laravel每小时运行一次inspire
工匠命令。 您不认为语法首先是如此直观吗?
实际上,Laravel允许您使用几种不同的方式来定义计划任务:
- 使用闭包/可调用的。
- 调用工匠命令。
- 执行shell命令。
此外,您可以选择许多内置的调度频率:
- 每分钟/每五分钟
- 每小时/每天/每周/每季度/每年
- 在一天中的特定时间
- 还有很多
实际上,我想说的是,它提供了一套完整的例程,因此您无需触摸外壳即可创建自定义cron作业!
是的,我可以告诉您,您渴望了解如何实现自定义的计划任务,而这也是我在本文开头所承诺的。
在Laravel中创建您的第一个计划任务
正如我们所讨论的,Laravel允许您使用不同的方式来定义计划任务。 让我们仔细研究一下它们的工作原理。
闭包/可调用方法
调度API提供了允许您执行可调用函数或闭包函数的call
方法。 让我们使用以下代码修改app/Console/Kernel.php
文件。
<?php
namespace App\Console;
use Illuminate\Support\Facades\DB;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
// the call method
$schedule->call(function () {
$posts = DB::table('posts')
->select('user_id', DB::raw('count(*) as total_posts'))
->groupBy('user_id')
->get();
foreach($posts as $post)
{
DB::table('users_statistics')
->where('user_id', $post->user_id)
->update(['total_posts' => $post->total_posts]);
}
})->everyThirtyMinutes();
}
}
如您所见,我们已经将闭包函数作为call
方法的第一个参数传递了。 另外,我们将频率设置为每30分钟一次,因此它将每30分钟执行一次关闭功能!
在我们的示例中,我们计算每个用户的总帖子数,并相应地更新统计信息表。
工匠司令部
除了闭包或可调用对象之外,您还可以计划将以一定间隔执行的工匠命令。 实际上,与闭包相比,这应该是首选方法,因为它可以同时提供更好的代码组织和可重用性。
继续并使用以下内容修改app/Console/Kernel.php
文件的内容。
<?php
namespace App\Console;
use Illuminate\Support\Facades\Config;
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\UserStatistics'
];
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
// artisan command method
$schedule->command('statistics:user')->everyThirtyMinutes();
}
/**
* Register the Closure based commands for the application.
*
* @return void
*/
protected function commands()
{
require base_path('routes/console.php');
}
}
如果您希望像上面的代码片段中所示那样调度工匠命令,则可以使用该command
方法。 您需要传递artisan命令签名作为command
方法的第一个参数。
当然,您还需要在app/Console/Commands/UserStatistics.php
定义相应的artisan命令。
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
class UserStatistics extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'statistics:user';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Update user statistics';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
// calculate new statistics
$posts = DB::table('posts')
->select('user_id', DB::raw('count(*) as total_posts'))
->groupBy('user_id')
->get();
// update statistics table
foreach($posts as $post)
{
DB::table('users_statistics')
->where('user_id', $post->user_id)
->update(['total_posts' => $post->total_posts]);
}
}
}
执行命令
可以说,到目前为止我们讨论的方法特定于Laravel应用程序本身。 此外,Laravel还允许您调度Shell命令,以便您也可以运行外部应用程序。
让我们来看一个简单的示例,该示例演示如何每天备份数据库。
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
// exec method
$host = config('database.connections.mysql.host');
$username = config('database.connections.mysql.username');
$password = config('database.connections.mysql.password');
$database = config('database.connections.mysql.database');
$schedule->exec("mysqldump -h {$host} -u {$username} -p{$password} {$database}")
->daily()
->sendOutputTo('/backups/daily_backup.sql');
}
}
从代码中可以明显看出,您需要使用调度程序的exec
方法,并且需要将要运行的命令作为第一个参数传递。
除此之外,我们还使用了sendOutputTo
方法,该方法允许您收集命令的输出。 另一方面,有一个方法emailOutputTo
,它允许您通过电子邮件发送输出内容!
这使我们到了本文的结尾。 实际上,我们只是拉开了Laravel Scheduling API的表面,它提供了很多功能。
结论
今天,我们了解了Laravel Web框架中的任务调度API。 令人惊讶的是,它使您能够轻松管理需要定期运行的任务。
在本文的开头,我们讨论了设置计划任务的传统方法,然后介绍了Laravel方法。 在本文的后半部分,我们通过几个实际示例演示了任务调度概念。
我希望您喜欢这篇文章,并且对在Laravel中设置计划任务感到更加自信。 对于那些刚刚开始使用Laravel或希望通过扩展来扩展您的知识,网站或应用程序的人,我们可以在Envato Market中进行很多研究。
如果您有任何想法,请使用下面的供稿开始对话!
翻译自: https://code.tutsplus.com/tutorials/tasks-scheduling-in-laravel--cms-29815