この記事では、Laravel Web フレームワークの魅力的な機能であるタスク スケジューリングを紹介します。 Laravel を使用してアプリケーション内でスケジュールされたタスクを管理する方法を見ていきます。さらに、最終的にはデモンストレーション目的で独自のカスタム スケジュールされたタスクを作成する予定です。
Laravel フレームワークを使用すると、スケジュールされたタスクを設定できるため、システム レベルでの設定について心配する必要がなくなります。 Laravel ではユーザーフレンドリーな方法でタスクを定義できるため、スケジュールされたタスクを設定するときに複雑な cron 構文を使用する必要がなくなります。
最初に従来の cron ジョブを設定する方法について説明し、次に Laravel がそれを実装する方法を検討します。この記事の後半では、このトピックについての実践的な洞察を提供するカスタムのスケジュールされたタスクをいくつか作成して試してみます。
日常のアプリケーション開発では、特定のスクリプトやコマンドを定期的に実行する必要があることがよくあります。 *nix システムを使用している場合は、cron ジョブがこれらのコマンドを処理することをおそらくご存知でしょう。一方、Windows ベースのシステムでは、スケジュールされたタスクと呼ばれます。
*nix ベースの cron ジョブの簡単な例を簡単に見てみましょう。
リーリー非常に簡単です - statistics.sh ファイルを 5 分ごとに実行します。
これは非常に単純な例ですが、多くの場合、より複雑な使用例を実装する必要があります。複雑なシステムでは、異なる間隔で実行する複数の cron ジョブを定義する必要があります。
複雑な Web アプリケーションがバックエンドで定期的に実行する必要があるタスクのいくつかを見てみましょう。
幸いなことに、Laravel には、これまで不可能だった方法でスケジュールされたタスクを定義できる組み込みのタスク スケジュール API が付属しています。はい、次のセクションでは、Laravel タスクのスケジュール設定の基本について説明します。
Laravelのやり方
先に進む前に、Laravel が提供するスケジューリング機能は他の機能とまったく同じであり、自動的には呼び出されないことを理解することが重要です。したがって、システム レベルでは何もする必要がないと考えている場合は、運が悪いと言えます。
実際、Laravel スケジューリング システムを使用したい場合、最初に行う必要があるのは、次のコード スニペットに示す
artisan コマンドを呼び出す毎分実行される cron ジョブを設定することです。
リーリー
artisan コマンドは Laravel スケジューラを呼び出し、アプリケーションで定義されている保留中の cron ジョブをすべて実行します。
これは、
App\Console\Kernel クラスの
schedule メソッドであり、アプリケーション固有のスケジュールされたタスクを定義する場合に使用する必要があります。
app/Console/Kernel.php ファイルの内容を取得します。 リーリー
ご覧のとおり、コア コード自体が有用な例を提供しています。上記の例では、Laravel はinspire
artisan コマンドを 1 時間ごとに実行します。そもそも構文が直感的だと思いませんか?
コマンドを呼び出します。
はい、カスタムのスケジュールされたタスクをどのように実装するか疑問に思われていることはわかります。これが記事の冒頭で約束したことです。
Laravel で最初のスケジュールされたタスクを作成します
クロージャ/呼び出し可能メソッド
call メソッドが用意されています。
app/Console/Kernel.php ファイルを次のコードで変更しましょう。
<?php namespace App\Console; use Illuminate\Console\Scheduling\Schedule; use Illuminate\Foundation\Console\Kernel as ConsoleKernel; use Illuminate\Support\Facades\DB; class Kernel extends ConsoleKernel { /** * The Artisan commands provided by your application. * * @var array */ protected $commands = [ // ]; /** * 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(); } /** * Register the commands for the application. * * @return void */ protected function commands() { $this->load(__DIR__.'/Commands'); require base_path('routes/console.php'); } }
如您所见,我们将闭包函数作为 call
方法的第一个参数传递。另外,我们将频率设置为每 30 分钟一次,因此它将每 30 分钟执行一次关闭函数!
在我们的示例中,我们计算每个用户的帖子总数并相应地更新 statistics
表。
artisan
命令除了闭包或可调用之外,您还可以安排一个 artisan
命令,该命令将按一定的时间间隔执行。事实上,它应该是优于闭包的首选方法,因为它同时提供了更好的代码组织和可重用性。
继续使用以下内容修改 app/Console/Kernel.php 文件的内容。
<?php namespace App\Console; use Illuminate\Console\Scheduling\Schedule; use Illuminate\Foundation\Console\Kernel as ConsoleKernel; use Illuminate\Support\Facades\DB; 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) { $schedule->command('statistics:user')->everyThirtyMinutes(); } /** * Register the commands for the application. * * @return void */ protected function commands() { $this->load(__DIR__.'/Commands'); require base_path('routes/console.php'); } }
这是 command
方法,如果您希望安排 artisan
命令,如上面的代码片段所示,您可以使用该方法。您需要传递 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]); } } }
exec
命令我们可以说到目前为止我们讨论的方法是特定于 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 不应该运行同一任务的另一个实例。默认情况下,Laravel 将始终开始运行计划任务,即使同一任务的前一个实例已经在运行但尚未完成。
那么让我们看看如何避免重叠计划任务。
$schedule->command('statistics:user')->everyThirtyMinutes()->withoutOverlapping();
正如你所看到的,你只需要使用 withoutOverlapping
方法来确保 Laravel 不会与已经运行的任务重叠。默认情况下,Laravel 重叠任务之前的锁定时间为 24 小时。如果您想覆盖它,可以按照以下代码片段所示进行操作。
$schedule->command('statistics:user')->everyThirtyMinutes()->withoutOverlapping(30);
在上面的示例中,Laravel 等待 30 分钟才清除重叠锁。
如果您同时安排多个任务,Laravel 会按顺序运行它们。因此,如果您有一个需要很长时间才能执行的任务,则下一个计划任务将不得不等待很长时间。为了避免这种情况,您可以在后台执行此类任务。
让我们快速看一下下面的示例,了解如何定义后台任务。
$schedule->command('statistics:user')->daily()->runInBackground();
如您所见,您可以使用 runInBackground
方法来定义后台任务。
今天,我们了解了 Laravel Web 框架中的任务调度 API。看到它如何轻松地管理需要定期运行的任务真是令人着迷。
在文章的开头,我们讨论了传统的设置计划任务的方式,接下来我们介绍了 Laravel 的设置方式。在本文的后半部分,我们通过几个实际示例来演示任务调度概念。
我希望您喜欢这篇文章,并且您应该对在 Laravel 中设置计划任务更有信心。对于那些刚刚开始使用 Laravel 或希望通过扩展来扩展您的知识、网站或应用程序的人,我们在 Envato Market 上提供了多种您可以学习的内容。
以上がLaravelでのタスクのスケジュール設定の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。