w3resource

Laravel (5.7) Queues

Step 1: Configure the Laravel

Install it by the following command.

composer create-project laravel/laravel --prefer-dist emailqueue

Now, in the .env file, configure the database and email server.

For email sending, I have used https://mailtrap.io. So if you want that use, go to the website and signup, and you will see your username and password, grab it and put in the .env file, and you are good to go.

Also, we need to change the queue driver to the database. By

default laravel uses sync.
APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:N/+b/PAQXgtG8OiYu3TKyudhicgYsGYfb551yrqkjmQ=
APP_DEBUG=true
APP_LOG_LEVEL=debug
APP_URL=http://localhost

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=queue
DB_USERNAME=root
DB_PASSWORD=

BROADCAST_DRIVER=log
CACHE_DRIVER=file
SESSION_DRIVER=file
SESSION_LIFETIME=120
QUEUE_DRIVER=database

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=
MAIL_PASSWORD=
MAIL_ENCRYPTION=tls

PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=

Step 2: Create a route for sending mail

We will create one route to send an email and also create one controller called EmailController.

php artisan make:controller EmailController

In routes >> web.php file, add the following code.

Route::get('email', 'EmailController@sendEmail');

Okay, now we need to create one mailable class, so in the terminal, type the following command.

php artisan make:mail SendMailable

So, it will create this file inside App\Mail\SendMailable.php.

Now, write the sendMail function inside the MailController.php file.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use App\Mail\SendMailable;

class EmailController extends Controller
{
    public function sendEmail()
    {
        Mail::to('[email protected]')->send(new SendMailable());
        echo 'email sent';
    }
}
Also, out SendMailable.php file looks like this.
<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;

class SendMailable extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->view('welcome');
    }
}

Now, start the server with the following command.

php artisan serve

Switch to the browser and hit this URL:

http://localhost:8000/email

You will see, there is a delay and then we can get the mail. So here is the solution and that is a queue.

Step 3: Configure Queue

We can use queue with the Database, Redis, and other drivers as mentioned  in Laravel 5.7 Queues.

We will use Database and so we need to create a migration for Jobs table.

php artisan queue:table

It will create a migration and then we need to migrate the database.

php artisan migrate

It will create the jobs table in the database.

Step 4: Create a job

Now, we will need to create the job that purpose is to send the actual email to the user.

php artisan make:job SendEmailJob

Now, the send email function will reside in the job file. So that job file looks like this.

<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Support\Facades\Mail;
use App\Mail\SendMailable;

class SendEmailJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        Mail::to('[email protected]')->send(new SendMailable());
    }
}

In EmailController.php file, we will need to trigger this job.

So we need to dispatch the newly created job from the EmailController. So that code will look like this.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Jobs\SendEmailJob;

class EmailController extends Controller
{
    public function sendEmail()
    {
        dispatch(new SendEmailJob());

        echo 'email sent';
    }
}

Now, again hit that email URL.

Still, the delay is there; we have just moved the logic to the job file. We need to send the mail in the background. So we need to delay our queue.

public function sendEmail()
{
   $emailJob = (new SendEmailJob())->delay(Carbon::now()->addSeconds(3));
   dispatch($emailJob);

   echo 'email sent';
}

Now, hit the URL again.

This time there is only 3 seconds delay, or we can say no delay, but wait, if you switch to mailtrap then there is no mail either. So how we can send real mail also.

Go to the database and see the jobs table. There is one entry for the job. So that means, the process of that job is not started. So Laravel, there is a concept called Queue Worker. We need to run that Queue Worker.

Switch to the terminal and type the following command to start the queue worker.

php artisan queue:work
In the terminal, it will say like this.
[2019-04-17 13:58:14] Processing: App\Jobs\SendEmailJob
[2019-04-17 13:58:19] Processed:  App\Jobs\SendEmailJob

Now, go to the mailtrap, and yes we will see that mail sent.

Previous: Laravel (5.7) Package Development
Next: Laravel (5.7) Task Scheduling



Follow us on Facebook and Twitter for latest update.