Maison >développement back-end >tutoriel php >Planification des tâches dans Laravel
Dans cet article, nous présenterons une fonctionnalité intéressante du framework Web Laravel : la planification des tâches. Nous verrons comment Laravel vous permet de gérer les tâches planifiées dans votre application. De plus, nous créerons éventuellement notre propre tâche planifiée personnalisée à des fins de démonstration.
Le framework Laravel vous permet de configurer des tâches planifiées afin que vous n'ayez pas à vous soucier de leur configuration au niveau du système. Vous pouvez vous éloigner de la syntaxe cron complexe lors de la configuration des tâches planifiées car Laravel vous permet de les définir de manière conviviale.
Nous verrons d'abord comment configurer une tâche cron traditionnelle, puis nous explorerons la façon dont Laravel l'implémente. Dans la seconde moitié de cet article, nous allons l'essayer en créant quelques tâches planifiées personnalisées qui devraient fournir un aperçu pratique du sujet.
Dans le développement quotidien d'applications, vous devez souvent exécuter régulièrement certains scripts ou commandes. Si vous utilisez un système *nix, vous savez probablement que les tâches cron gèrent ces commandes. D'un autre côté, elles sont appelées tâches planifiées sur les systèmes Windows.
Jetons un coup d'œil rapide à un exemple simple de tâche cron basée sur * nix.
*/5 * * * * /web/statistics.sh
Très simple : il exécute le fichier statistics.sh toutes les cinq minutes !
Bien qu'il s'agisse d'un exemple très simple, vous devrez souvent mettre en œuvre des cas d'utilisation plus complexes. Les systèmes complexes nécessitent que vous définissiez plusieurs tâches cron qui s'exécutent à différents intervalles.
Examinons certaines des tâches que les applications Web complexes doivent effectuer régulièrement sur le backend.
Comme vous pouvez le constater, il y a beaucoup de choses qui attendent d'être exécutées régulièrement et à des intervalles différents. Si vous êtes un administrateur système expérimenté, vous pouvez facilement définir des tâches cron pour toutes ces tâches, mais parfois, en tant que développeurs, nous souhaitons un moyen plus simple.
Heureusement, Laravel est livré avec une API de planification de tâches intégrée qui vous permet de définir des tâches planifiées comme jamais auparavant. Oui, la section suivante concerne les bases de la planification des tâches Laravel.
Dans la section précédente, nous avons abordé la manière traditionnelle de configurer une tâche cron. Dans cette section, nous présenterons Laravel en détail dans le contexte de l'API de planification de tâches.
Avant de continuer, la chose importante à comprendre est que la fonctionnalité de planification fournie par Laravel est comme n'importe quelle autre fonctionnalité et n'est pas appelée automatiquement. Donc, si vous pensez que vous n’avez rien à faire au niveau du système, je dirais que vous n’avez pas de chance.
En fait, si vous souhaitez utiliser le système de planification Laravel, la première chose à faire est de configurer une tâche cron qui s'exécute toutes les minutes et d'appeler la commande artisan
affichée dans l'extrait de code suivant.
* * * * * php /path-to-your-project/artisan schedule:run >> /dev/null 2>&1
La commande artisan
ci-dessus appelle le planificateur Laravel, qui exécute ensuite toutes les tâches cron en attente définies dans l'application.
Bien sûr, nous n'avons pas vu comment définir des tâches planifiées dans une application Laravel, c'est ce dont nous parlerons en profondeur ensuite.
C'est la AppConsoleKernel
类的 schedule
méthode que vous devez utiliser si vous souhaitez définir des tâches planifiées spécifiques à une application.
Continuez pour obtenir le contenu du fichier 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 = [ // ]; /** * Define the application's command schedule. * * @param \Illuminate\Console\Scheduling\Schedule $schedule * @return void */ protected function schedule(Schedule $schedule) { // $schedule->command('inspire')->hourly(); } /** * Register the commands for the application. * * @return void */ protected function commands() { $this->load(__DIR__.'/Commands'); require base_path('routes/console.php'); } }
Comme vous pouvez le constater, le code principal lui-même fournit un exemple utile. Dans l'exemple ci-dessus, Laravel exécute la commande inspire
inspire
artisan
toutes les heures. Ne pensez-vous pas que la syntaxe est intuitive au départ ?
En fait, Laravel vous permet de définir des tâches planifiées de différentes manières :
artisan
. De plus, vous avez le choix entre des tonnes de fréquences de planification intégrées :
En fait, je dirais qu'il fournit un ensemble complet de routines vous permettant de créer des tâches cron personnalisées sans toucher au shell !
Oui, je vois que vous vous demandez comment mettre en œuvre vos tâches planifiées personnalisées, c'est ce que j'ai promis au début de l'article.
Comme nous en avons discuté, Laravel vous permet de définir des tâches planifiées de différentes manières. Voyons comment cela fonctionne un par un.
L'API Scheduling fournit la méthode call
, qui vous permet d'exécuter une fonction appelable ou une fonction de fermeture. Modifions le fichier app/Console/Kernel.php en utilisant le code suivant.
<?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 上提供了多种您可以学习的内容。
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!