Queues are amazing. Queues literally make your ‘Job’ faster. But, queues are confusing and often too much a hassle to learn. In this tutorial, I will try to make it simple enough to understand yet actual enough to be used in the real world.
This is not a laravel CRUD example. There are already plenty of CRUD tutorials available you can learn by clicking here.
Step 1: Make a new Laravel 6 Project. Run this command in your terminal
composer create-project --prefer-dist laravel/laravel laravel-techflow360
Step 2: Navigate inside the folder and check the version and download additional packages using npm (Node.js and npm is required) using the commands
cd laravel-techflow360
php artisan -V
> Laravel Framework 6.14.0
npm install
Step 3: Build a MySQL database named laravel-techflow360.Simply use phpMyAdmin to build a database using GUI.
Step 3.1: Open the entire project folder ‘laravel-techflow360‘ in your choice of text editor (I will be using Sublime).
Step 4: Enter your database credentials in the .env file
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel-techflow360
DB_USERNAME=root
DB_PASSWORD=
Step 5: Laravel needs few tables to work efficiently. Let’s migrate them now.
php artisan migrate
Ok so now that we have the basic model ready. Let us explore laravel a bit more. Laravel uses MVC (Model-View-Controller) framework. You can read about MVC framework here. Here is a quick overview.
The model manages the data, logic and the algorithm of the application.
The view is for the representation of the chart, diagram etc. Users only get to see this part.
The controller receives the input and converts it as a command for the view or the model.
Step 6: Let’s create a model Student
php artisan make:model Student --migration
You will get an output like this:-
Model created successfully.
Created Migration: 2020_02_08_131311_create_students_table
Step 7: Navigate to database\migration\2020_02_08_131311_create_students_table file in your text editor and modify it like this. (Pro Tip: Use Ctrl+P to quickly search for files in Sublime). Postmodification your file will look like this:-
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateStudentsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/ public function up()
{
Schema::create('students', function (Blueprint $table) {
$table->bigIncrements('id');
$table->timestamps();
$table->string('name');
$table->string('roll');
$table->string('result');
$table->string('mobile');
});
}
/**
* Reverse the migrations.
*
* @return void
*/ public function down()
{
Schema::dropIfExists('students');
}
}
We modified and added name, roll, result and mobile column in the schema.
Step 8: Migrate the table now
php artisan migrate
Step 9: Now open the file app\Student.php and modify it accordingly
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Student extends Model
{
protected $fillable = [
'name',
'roll',
'result',
'mobile'
];
}
Step 10: Create a Controller
php artisan make:controller StudentController --resource
Note:
–resource is a clever little command that automatically creates a CRUD layout in the controller and a single command in the route file web.php creates multiple paths to the controller. Here is the initial skeleton of the controller with path app\Http\Controllers\StudentController. For simplicity of the tutorial, we will only concern ourselves with functions index(), create() and store()
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class StudentController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/ public function index()
{
//
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/ public function create()
{
//
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/ public function store(Request $request)
{
//
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/ public function show($id)
{
//
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/ public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/ public function update(Request $request, $id)
{
//
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/ public function destroy($id)
{
//
}
}
Step 11: Navigate to routes\web.php and add the following line (Route::resource(‘students’, ‘StudentController’);). Your web.php file should look like this
Route::get('/', function () {
return view('welcome');
});
Route::resource('students', 'StudentController');
Step 12: Add use App\Contact; in StudentController. It should look like
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Student;
class StudentController extends Controller
{
Step 13: Modify the Student controller index(),create(),store() function like this:-
public function index()
{
$students = Student::all();
return view('students.index', compact('students'));
}
public function create()
{
return view('students.create');
}
public function store(Request $request)
{
$request->validate([
'name'=>'required',
'roll'=>'required',
'mobile'=>'required',
'result'=>'required'
]);
$student = new Student([
'name' => $request->get('name'),
'roll' => $request->get('roll'),
'mobile' => $request->get('mobile'),
'result' => $request->get('result')
]);
$student->save();
return redirect('/students')->with('success', 'Student saved!');
}
Step 14: In resources/views folder create a template.blade.php file
cd resources/views
touch template.blade.php
Step 15: Open resources/views/template.blade.php and modify it
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Techflow360 Queue Tutorial</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<style>
* {
box-sizing: border-box;
}
input[type=text], select, textarea {
width: 100%;
padding: 12px;
border: 1px solid #ccc;
border-radius: 4px;
resize: vertical;
}
label {
padding: 12px 12px 12px 0;
display: inline-block;
}
input[type=submit] {
background-color: #4CAF50;
color: white;
padding: 12px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
float: right;
}
input[type=submit]:hover {
background-color: #45a049;
}
.container {
border-radius: 5px;
background-color: #f2f2f2;
padding: 20px;
}
.col-25 {
float: left;
width: 25%;
margin-top: 6px;
}
.col-75 {
float: left;
width: 75%;
margin-top: 6px;
}
/* Clear floats after the columns */.row:after {
content: "";
display: table;
clear: both;
}
/* Responsive layout - when the screen is less than 600px wide, make the two columns stack on top of each other instead of next to each other */@media screen and (max-width: 600px) {
.col-25, .col-75, input[type=submit] {
width: 100%;
margin-top: 0;
}
}
</style>
</head>
<body>
<div class="container">
@yield('main')
</div>
</body>
</html>
Step 16: Create a new repository named students inside resources/views
mkdir students
Step 17: Navigate inside students and create a blade file named create.blade.php
cd students
touch create.blade.php
Step 18: Open create.blade.php and enter the following code
@extends('template')
@section('main')
<div class="row">
<div class="col-sm-8 offset-sm-2">
<h1 class="display-3">Add a Student</h1>
<div>
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div><br />
@endif
<form method="post" action="{{ route('students.store') }}">
@csrf
<div class="form-group" class="col-25">
<label for="name">Full Name:</label>
<input type="text" class="form-control" name="name"/>
</div>
<div class="form-group" class="col-25">
<label for="roll">Roll Number:</label>
<input type="text" class="form-control" name="roll"/>
</div>
<div class="form-group" class="col-25">
<label for="mobile">Mobile Number:</label>
<input type="text" class="form-control" name="mobile"/>
</div>
<div class="form-group" class="col-25">
<label for="result">Result:</label>
<input type="text" class="form-control" name="result"/>
</div>
<div class="row">
<input type="submit"></input>
</div>
</form>
</div>
</div>
</div>
@endsection
Step 19: Similarly create an index.blade.php file inside students folder
@extends('template')
@section('main')
<div class="row">
<div class="col-sm-12">
<h1 class="display-3">Students</h1>
<a class="btn btn-primary" href="{{route('students.create')}}">ADD A NEW STUDENT</a>
<table class="table table-striped">
<thead>
<tr>
<td>ID</td>
<td>Name</td>
<td>Roll</td>
<td>Result</td>
<td>Mobile</td>
</tr>
</thead>
<tbody>
@foreach($contacts as $contact)
<tr>
<td>{{$contact->id}}</td>
<td>{{$contact->name}}</td>
<td>{{$contact->roll}}</td>
<td>{{$contact->result}}</td>
<td>{{$contact->mobile}}</td>
</tr>
@endforeach
</tbody>
</table>
<div>
</div>
@endsection
Step 20: Start the server and run the code
php artisan serve
>Laravel development server started: http://127.0.0.1:8000
Step 21: Navigate to your URL in my case it’s 127.0.0.1:8000
http://127.0.0.1:8000/students
Let us now start with our actual tutorial of laravel queue. I knowwwww!!!! Gosh! In my defence, basics are important too.
Step 22: Open .env file again and change the queue driver/connection to the database. Additionally, enter two more variables which will be used later. API Key and Sender ID are required to send SMS. It is available for FREE at www.pingsms.in. Check out my Github Repo to learn about the different features of the API.
QUEUE_CONNECTION=database
PINGSMS_API_KEY=NisD1NYRZaye0SuAmzE4wbIsKT0t0kdjjfu82923920203283djna
PINGSMS_SENDERID=PNGDMO
Step 23: We will use the database so we need a job table. Run
php artisan queue:table
Step 24: Migrate the table
php artisan migrate
Step 25: Create a new Job to send SMS. (Don’t worry you can use jobs for mail also)
php artisan make:job SendSMSJob
Step 26: Open the SendSMSJob file in located in app\Jobs
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use DB;
class SendSMSJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $tries = 5;
protected $details;
/**
* Create a new job instance.
*
* @return void
*/ public function __construct($details)
{
$this->details = $details;
}
/**
* Execute the job.
*
* @return void
*/ public function handle()
{
$students=$students=DB::select('SELECT * FROM students WHERE id=?',[$this->details]);;
foreach($students AS $student){
$curl = curl_init();
$apiKey=env("PINGSMS_API_KEY"); //Enter The API Key Here
$senderId=env("PINGSMS_SENDERID"); //Your SenderId. PNGSMS is default senderId
$mobileNumber=$student->mobile; //10 digit phone number separated by comma (,)
$language="1";
$product="1";
$message="Dear $student->name,
Your Roll No. is $student->roll and your Result is $student->result.";
$message=urlencode($message);// Encode the message to send it through URL
curl_setopt_array($curl, array(
CURLOPT_URL => "https://www.pingsms.in/api/sendsms?key=".$apiKey."&sender=".$senderId."&mobile=".$mobileNumber."&language=".$language."&product=".$product."&message=".$message,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array("X-Authorization: ".$apiKey),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response."\n";
}
}
}
}
Step 27: Dispatch the Job in Student controller in the store function. Modified store() will look like:-
public function store(Request $request)
{
$request->validate([
'name'=>'required',
'roll'=>'required',
'mobile'=>'required',
'result'=>'required'
]);
$student = new Student([
'name' => $request->get('name'),
'roll' => $request->get('roll'),
'mobile' => $request->get('mobile'),
'result' => $request->get('result')
]);
$student->save();
dispatch(new \App\Jobs\SendSMSJob($student->id)); //Dispatch the JOB Here
return redirect('/students')->with('success', 'Student saved!');
}
Step 28: Run the Job(No Longer required in laravel v6)
php artisan queue:work
I use queue:work in production and queue:listen in local, Check my old article to know why. A better way to run the queue can be found here.
Feel free to comment below if you have additional queries.
Source code is available at https://github.com/sa1if3/laravel-techflow360/
With over 3 years of versatile experience in IT Specialist, Project Manager, CTO, and Coding Instructor roles, I bring a comprehensive skill set to my current position as a Senior IT Support Analyst at RBC Capital Markets. I am proficient in stakeholder management, envisioning, producing, and delivering well-tested software products, and optimizing business processes. My passion lies in two key areas: technical writing and cloud engineering.
My expertise in technical writing is evidenced by published works on esteemed platforms like Techflow360, FreeCodeCamp, and Elsevier. In the realm of cloud engineering, I am further bolstered by my Google Cloud Associate Cloud Engineer certification.
At She Thinks Code, I actively contribute to offering computer science education to women from Least Developed Countries, harnessing technology to empower individuals. I am eager to explore collaborations and initiatives that capitalize on my expertise in diverse technical environments, including leveraging my cloud engineering skills.
App Engine is a robust platform within Google Cloud that empowers developers to create and…
Django is an open-source web framework that helps developers to create and maintain high-quality, secure…
The problem of converting a string in a zigzag pattern is a classic problem in…
When Neeraj Chopra bagged India's only gold medal in Tokyo 2020 Olympics, the whole nation…
Htmx is short for high power tools for HTML. It simplifies tedious work for developers.…
What is Biomechanics? We know, mechanics is the branch of physics dealing with the motion…