Cron jobs are the go to tools for developers to run scheduled tasks/jobs. A cron job is a Linux tool used for scheduling tasks to be executed at scripted times. Maintaining and managing cron jobs outside the application is a maintainability headache. Also, SSH access is required to edit cron entries.
Laravel’s command scheduler is a better way to manage scheduled tasks in your PHP application. It enables you to define your command schedule fluently and expressively within your application itself. Your task schedule is defined in the app/Console/Kernel.php file’s schedule method. Lets have a look:
Structure of Task Scheduling
Steps to configure Laravel Scheduler
- Create Laravel Project
- Create mailing function – Only if we need results in a email
- Create controller for new function
- Create command
- Test the command
- Configure command in kernel file
- Configure Schedule worker in Crontab
1. Create Laravel Project
cd task-demo
2. Create mailing function – Only if we need results in a email
Configure the constructor and build function to accept parameters and send emails as defined in the controller.
namespace App\Mail; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Mail\Mailable; use Illuminate\Queue\SerializesModels; class SendMail extends Mailable { use Queueable, SerializesModels; private $details; /** * Create a new message instance. * * @return void */ public function __construct($details) { $this->details = $details; } /** * Build the message. * * @return $this */ public function build() { return $this->from($this->details['from'],$this->details['from_name']) ->subject($this->details['subject']) ->view($this->details['template']) ->with('details',$this->details); } }
For sending emails, we have to configure email sections from .env file. You can update MAIL parameter details in .env file for connecting with your email server. For example we have connected to mailtrap with below configurations
MAIL_MAILER=smtp MAIL_HOST=smtp.mailtrap.io MAIL_PORT=25 MAIL_USERNAME=************* MAIL_PASSWORD=************** MAIL_ENCRYPTION=null MAIL_FROM_ADDRESS=null MAIL_FROM_NAME="${APP_NAME}"
3. Create controller for new function
Create a function for your task and use the mail class if you need the output to send as an email. Functions can also be written directly in the command handle section if it is a small piece of code.
namespace App\Http\Controllers; use App\Mail\SendMail; use Illuminate\Http\Request; use Illuminate\Support\Facades\Mail; class MyTaskController extends Controller { public function MyTasks() { // Logic of the task $a = 10; $b = 20; $result = $a + $b; // Send results as an email // Send mail with status $details =[ 'from' => 'mail@appname.com', 'from_name' => 'App Name', 'subject' => 'Test Process Status', 'template' => 'emails.template1', // Email template blade for bypassing default template 'title' => 'Test task Processing Status', 'body' => 'The result for my task is ' . $result ]; Mail::to('to@email.com')->cc("cc@email.com")->send(new SendMail($details)); } }
4. Create command
Update signature section – here we define the command name which can be called through schedule worker. Also update the handle section for calling the function from the controller. You can also call a Laravel Job in this section.
namespace App\Console\Commands; use Illuminate\Console\Command; use App\Http\Controllers\MyTaskController; class MyTask extends Command { /** * The name and signature of the console command. * * @var string */ protected $signature = 'mytask:mytask'; /** * The console command description. * * @var string */ protected $description = 'This is a test task'; /** * Create a new command instance. * * @return void */ public function __construct() { parent::__construct(); } /** * Execute the console command. * * @return int */ public function handle() { $myTasks = new MyTaskController(); $myTasks--->MyTasks(); } }
5. Test the command
You can test your new command by using the PHP artisan command.
6. Configure command in kernel file
Add command in schedule function of Console Kernel file for adding the task to the scheduler.
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) { // $schedule--->command('inspire')->hourly(); $schedule->command('mytask:mytask')->weekly(); } /** * Register the commands for the application. * * @return void */ protected function commands() { $this->load(__DIR__.'/Commands'); require base_path('routes/console.php'); } }
7. Configure Schedule worker in Crontab
Open terminal and run crontab -e
Add below line to the bottom of the crontab for running laravel scheduler in every 1 minute.
References