Tempo di lettura: 13 minuti
In questo tutorial vi spiego come impostare i cron jobs in Laravel 10 con i quali si possono realizzare attività pianificate.
Tradotto dall’inglese–L’utilità della riga di comando cron è un programma di pianificazione dei lavori su sistemi operativi simili a Unix. Gli utenti che configurano e gestiscono ambienti software utilizzano cron per pianificare i lavori, noti anche come lavori cron, da eseguire periodicamente a orari, date o intervalli fissi. Wikipedia (inglese)
Impostare i cron jobs con Laravel: installiamo laravel
Scegliete una vostra directory a piacere , aprite il terminale e digitate :
composer create-project laravel/laravel crontest
ok quindi una volta scaricato il progetto spostatevi al suo interno:
cd crontest
ora aprite il progetto con il vostro ide preferito, io in genere utilizzo vsc , open source e davvero ottimo.
Installa webpack.mix
Dalla versione 9 di laravel è stato introdotto Vite , un moderno strumento di creazione frontend che fornisce un ambiente di sviluppo estremamente veloce e raggruppa il codice per la produzione.
Tuttavia se qualcuno non si abituasse al suddetto può sempre tornare al buon vecchio webpack.mix.js(se volete utilizzare vite saltate pure questa sezione).
Da terminale digitate:
npm install --save-dev laravel-mix
quindi create il file webpack.mix.js nella directory principale:
touch webpack.mix.js
apritelo e aggiungete:
const mix = require('laravel-mix'); /* |-------------------------------------------------------------------------- | Mix Asset Management |-------------------------------------------------------------------------- | | Mix provides a clean, fluent API for defining some Webpack build steps | for your Laravel applications. By default, we are compiling the CSS | file for the application as well as bundling up all the JS files. | */ mix.js('resources/js/app.js', 'public/js') .postCss('resources/css/app.css', 'public/css', [ // ]);
aprite package.json e modificate come di seguito:
... "scripts": { "dev": "npm run development", "development": "mix", "watch": "mix watch", "watch-poll": "mix watch -- --watch-options-poll=1000", "hot": "mix watch --hot", "prod": "npm run production", "production": "mix --production" }, ...
ora possiamo rimuovere la chiave type, da terminalke digitate:
npm pkg delete type
bene ora aprite il file .env e modificate eliminando:
... VITE_APP_NAME="${APP_NAME}" VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}" VITE_PUSHER_HOST="${PUSHER_HOST}" VITE_PUSHER_PORT="${PUSHER_PORT}" VITE_PUSHER_SCHEME="${PUSHER_SCHEME}" VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" ...
sostituendolo con:
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
rimuovete il plugin vite, da terminale:
npm remove vite laravel-vite-plugin
quindi rimuovete il file:
rm vite.config.js
Installazione bootstrap
Installate ora il framework bootstrap con lo scaffolding per l’autenticazione , sempre da terminale:
composer require laravel/ui --dev
php artisan ui bootstrap --auth
npm install && npm run dev
ottimo. Quindi aprite il file resources\css\app.css ed importate il css di bootstrap:
@import '~bootstrap/dist/css/bootstrap.min.css';
aprite resources\views\layouts\app.blade.php, eliminate:
@vite(['resources/sass/app.scss', 'resources/js/app.js'])
ed aggiungete:
<link rel="stylesheet" href="{{ mix('css/app.css') }}"> <script src="{{ mix('js/app.js') }}" defer></script>
avviate il server:
php artisan serve
ed ecco qua:
Impostare i cron jobs con Laravel: Crea il database
Prima di realizzare il database vi consiglio di scaricarvi il server locale laragon, più avanti capirete il perchè. Una volta installato apritelo e nel corpo dello stesso fate click con il tasto dx :
in Quick add scegliete phpMyAdmin:
in pratica gli avete detto di utilizzare phpMyadmin come gestore dei database default.
Benissimo ora siamo pronti per avviare tutti i servizi, una volta fatto cliccate su terminale:
quindi nella console che si apre scrivete:
mysql -u root -p password:
quandoi vi chiede la password date invio, in locale non abbiamo nessuna password. quindi ora possiamo cerare il database:
Create database cronlaravel_db;
per una verifica digitate:
show databases;
il risultato , se tutto ok dovrebbe essere questo:
ora potete uscire digitando exit quindi di nuovo exit.
Aprite il file .env ed aggiungete il database appena creato:
... DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=cronlaravel_db DB_USERNAME=root DB_PASSWORD= ...
quindi migrate le tabelle:
php artisan migrate
Bene ora da interfaccia http://127.0.0.1:8000/ registrate un utente.
Aggiungete un servizio di mailing:
In rete esistono diversi servizi di mailing che ci consentono di inviare delle mail ad una nostra mailing list, alcuni di loro sono anche gratuiti chiaramente con un piano limitato. Tra essi spiccano Sendinblue(oggi acquisito da Brevo), mailtrap tra i più noti. La mia scelta ricade sul primo in quanto offre un piano gratuito che ci consente di inviare fino a 300 mail al giorno.
Per il nostro scopo è più che sufficiente in quanto andremo a realizzare un invio di email ad una nostra ipotetica mail list con un comando pianificato.
Andate su Brevo e registratevi utilizzando il vostro piano preferito( io ripeto utilizzo quello gratuito). Una volta registrati, accedete ed espandete il tasto privato in alto a dx quindi cliccate su SMTP & api:
questi sono dei parametri che ci servono e da impostare nel nostro file .env:
... MAIL_MAILER=smtp MAIL_HOST=smtp-relay.brevo.com MAIL_PORT=587 MAIL_USERNAME=ticalilucio@gmail.com MAIL_PASSWORD=vostrapassword MAIL_ENCRYPTION=null MAIL_FROM_ADDRESS="hello@example.com" MAIL_FROM_NAME="${APP_NAME}" ...
perfetto una volta fatto tutto ciò siamo finalmente pronti per concentrarci e dedicarci alla realizzazione dell’attività pianificata, vero scopo del tutorial.
Realizza il comando
Realizza il comando DailyNews, da terminale digita:
php artisan make:command DailyNews
questo comando ha creato una classe in app\Console\Commands\DailyNews.php:
<?php namespace App\Console\Commands; use Illuminate\Console\Command; class DailyNews extends Command { /** * The name and signature of the console command. * * @var string */ protected $signature = 'app:daily-news'; /** * The console command description. * * @var string */ protected $description = 'Command description'; /** * Execute the console command. */ public function handle() { // } }
dove $signature rappresenta il comando da impartire con artisan per lanciarlo, nel metodo handle bisognerà implementare la funzionalità della pianificazione.
quindi modifichiamo come segue:
protected $signature = 'news:daily';
e
protected $description = 'Respectively send an exclusive quote to everyone daily via email.';
quindi modificate il metodo handle:
public function handle() { $news = [ 'La formica' => 'Che cosa hanno in comune un televisore e una formica? Le antenne!', 'La Mosca' => 'Qual è la città preferita dai ragni? Mosca!', 'Cattivo odore' => 'Qual è la pianta più puzzolente? Quella dei piedi!', 'la zebbra' => 'Che cos\'è una zebra? Un cavallo evaso dal carcere!', 'Il pomodoro' => 'Sapete perché il pomodoro non riesce a dormire? Perché l’insalata… russa!', 'Il cane' => 'Qual è il colmo per un cane? Avere una bella gatta da pelare.', 'Divorziati' => 'Qual è il colmo per due divorziati americani? Essere… stati uniti.' ]; // Setting up a random word $key = array_rand($news); $data = $news[$key]; $users = User::all(); foreach ($users as $user) { Mail::raw("{$key} -> {$data}", function ($mail) use ($user) { $mail->from('digamber@positronx.com'); $mail->to($user->email) ->subject('Daily New Quote!'); }); } $this->info('Successfully sent daily quote to everyone.'); }
ora dailyNews.php è :
<?php namespace App\Console\Commands; use App\Models\User; use Illuminate\Console\Command; use Illuminate\Support\Facades\Mail; class DailyNews extends Command { /** * The name and signature of the console command. * * @var string */ protected $signature = 'news:daily'; /** * The console command description. * * @var string */ protected $description = 'Respectively send an exclusive quote to everyone daily via email.'; /** * Execute the console command. */ public function handle() { $news = [ 'La formica' => 'Che cosa hanno in comune un televisore e una formica? Le antenne!', 'La Mosca' => 'Qual è la città preferita dai ragni? Mosca!', 'Cattivo odore' => 'Qual è la pianta più puzzolente? Quella dei piedi!', 'la zebbra' => 'Che cos\'è una zebra? Un cavallo evaso dal carcere!', 'Il pomodoro' => 'Sapete perché il pomodoro non riesce a dormire? Perché l’insalata… russa!', 'Il cane' => 'Qual è il colmo per un cane? Avere una bella gatta da pelare.', 'Divorziati' => 'Qual è il colmo per due divorziati americani? Essere… stati uniti.' ]; // Setting up a random word $key = array_rand($news); $data = $news[$key]; $users = User::all(); foreach ($users as $user) { Mail::raw("{$key} -> {$data}", function ($mail) use ($user) { $mail->from('lucio@freewebsolution.it'); $mail->to($user->email) ->subject('Daily New Quote!'); }); } $this->info('Successfully sent daily quote to everyone.'); } }
ora aprite il file app/Console/Kernel.php e registrate la classe ,modificate:
<?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 = [ Commands\DailyNews::class, ]; /** * Define the application's command schedule. * * @param \Illuminate\Console\Scheduling\Schedule $schedule * @return void */ protected function schedule(Schedule $schedule) { $schedule->command('news:daily') ->everyMinute(); } /** * Register the commands for the application. * * @return void */ protected function commands() { $this->load(__DIR__.'/Commands'); require base_path('routes/console.php'); } }
bene come vedete nel metodo schedule ho inserito il metodo everyMinute(), ciò vuol dire esegui ogni minuto.
Da terminale digitate:
php artisan list
e come potete vedere da immagine abbiamo il nostro comando nella lista:
ok quindi lanciate il comando:
php artisan news:daily
se state ricevendo un messaggio di successo nella console vuol dire che tutto è a posto, quindi aprite il vostro client per l’email e verificate che sia arrivato il messaggio( ammesso che in fase di registrazione abbiate inserito un indirizzo valido, vostro):
Bene diciamo che il comando funziona, questo è solo il test perchè il nostro scopo è quello di pianificarlo ad intervalli regolari.
Imposta il cron su laragon
Ora avrete capito il perchè vi ho fatto installare Laragon. Su di esso è molto semplice impostare i cron, quindi dal menu dello stesso scegliete laragon->procfile->procfile e sul file che si apre aggiungete:
Cron: autorun "Cronical --console >NUL 2>&1" PWD=bin\cronical
in fondo.
Quindi sempre dal menu di laragon scegliete attrezzi->cron->conical.dat e nel file che si apre aggiungete:
* * * * * php C:/laragon/www/crontest/artisan schedule:run
sempre in fondo.
Gli asterischi in questo caso vogliono dire ogni minuto, se volete saperne di più in cima dello stesso file vi è una spiegazione. Noi imposteremo il tempo dal nostro comando in laravel per cui questi per ora non ci interessano.
Riavviate laragon.
Aprite un terminale e fatelo puntare su C:\laragon\bin\cronical (il percorso vostro chiaramente che punti alla folder cronical del vostro laragon) e digitate :
.\Cronical.exe --console --debug
si avvia la lista degli eventi cron di laragon per debug dove potete verificare e vedere i processi che si avviano:
... 16:10:09.377 [5] Config: Terminate cron jobs after = 3600 seconds 16:10:09.423 [5] Found new CronJob: php C:/laragon/www/crontest schedule:run 16:10:09.461 [5] All jobs reloaded 16:10:10.393 - [4] Checking services ..
come potete vedere anche il nostro servizio è partito con successo e niente errori 😁 😁 😁
Ottimo il nostro pianificatore sta funzionando con successo:
In questo modo , visto che stiamo testando, nel nostro comando avevamo inserito
protected function schedule(Schedule $schedule) { $schedule->command('news:daily') ->everyMinute(); }
dicendogli di avviarsi ogni minuto. In casi reali non avrebbe senso ricevere una mail al minuto non trovate?
Quindi eccovi una tabella completa e descrittiva su ciò che possiamo impostare in base alle nostre esigenze:
Method | Description |
---|---|
->cron('* * * * *'); |
Run the task on a custom cron schedule |
->everySecond(); |
Run the task every second |
->everyTwoSeconds(); |
Run the task every two seconds |
->everyFiveSeconds(); |
Run the task every five seconds |
->everyTenSeconds(); |
Run the task every ten seconds |
->everyFifteenSeconds(); |
Run the task every fifteen seconds |
->everyTwentySeconds(); |
Run the task every twenty seconds |
->everyThirtySeconds(); |
Run the task every thirty seconds |
->everyMinute(); |
Run the task every minute |
->everyTwoMinutes(); |
Run the task every two minutes |
->everyThreeMinutes(); |
Run the task every three minutes |
->everyFourMinutes(); |
Run the task every four minutes |
->everyFiveMinutes(); |
Run the task every five minutes |
->everyTenMinutes(); |
Run the task every ten minutes |
->everyFifteenMinutes(); |
Run the task every fifteen minutes |
->everyThirtyMinutes(); |
Run the task every thirty minutes |
->hourly(); |
Run the task every hour |
->hourlyAt(17); |
Run the task every hour at 17 minutes past the hour |
->everyOddHour($minutes = 0); |
Run the task every odd hour |
->everyTwoHours($minutes = 0); |
Run the task every two hours |
->everyThreeHours($minutes = 0); |
Run the task every three hours |
->everyFourHours($minutes = 0); |
Run the task every four hours |
->everySixHours($minutes = 0); |
Run the task every six hours |
->daily(); |
Run the task every day at midnight |
->dailyAt('13:00'); |
Run the task every day at 13:00 |
->twiceDaily(1, 13); |
Run the task daily at 1:00 & 13:00 |
->twiceDailyAt(1, 13, 15); |
Run the task daily at 1:15 & 13:15 |
->weekly(); |
Run the task every Sunday at 00:00 |
->weeklyOn(1, '8:00'); |
Run the task every week on Monday at 8:00 |
->monthly(); |
Run the task on the first day of every month at 00:00 |
->monthlyOn(4, '15:00'); |
Run the task every month on the 4th at 15:00 |
->twiceMonthly(1, 16, '13:00'); |
Run the task monthly on the 1st and 16th at 13:00 |
->lastDayOfMonth('15:00'); |
Run the task on the last day of the month at 15:00 |
->quarterly(); |
Run the task on the first day of every quarter at 00:00 |
->quarterlyOn(4, '14:00'); |
Run the task every quarter on the 4th at 14:00 |
->yearly(); |
Run the task on the first day of every year at 00:00 |
->yearlyOn(6, 1, '17:00'); |
Run the task every year on June 1st at 17:00 |
->timezone('America/New_York'); |
Set the timezone for the task |
per approfondire potete navigare su laravel.
Bene con questo è tutto, abbiamo fatto uno splendido lavoro a dimostrazione della flessibilità di utilizzo di questo splendido framework. Potete utilizzare i vostri pianificatori a tempo come meglio ritenete adattandoli alle vostre esigenze.
Happy coding 😎😎😎