How To Use Service Providers To Their Full Potential Laravel
Since its initial release in 2011, Laravel'due south usage and developers' interest in it grew exponentially, establishing it as the almost popular open up-source PHP framework currently available. Contributing factors to this were its extremely rich characteristic set, splendid documentation, code elegancy, and on top of it all, incredible simplicity.
While from the programmer's perspective, all of this sounds bang-up—and information technology really is—Laravel development's flat learning curve ways employers demand to take extra steps to ensure they're hiring a office-fourth dimension or total-time developer capable of delivering quality, scalable code. This article will focus on introducing Laravel's extensive characteristic set also as some cadre programming concepts which will equip interviewers to construct effective questions and recognize developers with acceptable feel and expertise for their project requirements.
Concepts
Before we dive into Laravel specifics, we're going to introduce a few programming and web application concepts. It's important interviewers are familiar with these concepts because nosotros're going to exist referring to them afterward, and understanding them will also enable you lot to gauge a potential employee's programming knowledge.
Model-view-controller (MVC)
MVC is a software design pattern. Simply put, it dictates that all application lawmaking should be separated into 3 layers:
- The data layer (model) stores and/or prepares data based on the controller's instructions.
- The presentation layer (view) displays to the end user the data received from the controller.
- The "glue" layer (controller) handles incoming requests and instructs the data layer on what to do with the request data. Based on the request, it gets the data layer to ready new data, which is and then sent to the presentation layer for rendering.
The Laravel framework is based around the MVC design, merely information technology does not enforce developers' utilize of MVC. This ways that a developer not being familiar with MVC and non honoring best practices can result in poorly written code, regardless of the framework.
Let's look at examples of poorly written and well-written code:
<html> <caput> </caput> <body> <?php $pdo = new PDO('mysql:host=localhost;dbname=laraveldb', 'root', 'pass'); $query = $pdo->query('select * from articles'); $results = $query->fetchAll(PDO::FETCH_ASSOC); ?> <?php foreach ($results as $articleData): ?> <div> <h2><?php echo $articleData['championship']; ?></h2> <p><?php echo $articleData['content']; ?></p> </div> <?php endforeach; ?> </body> </html>
In this case, we interact with the database directly in our presentation layer. Nosotros also don't have a model for the articles table, or a controller which would transport data to the view. Permit'southward rewrite this in Laravel.
The Commodity
model:
namespace App; use Illuminate\Database\Eloquent\Model; class Commodity extends Model { // }
Our controller, which will laissez passer all of the Commodity
s to the view:
namespace App\Http\Controllers; employ App\Http\Controllers\Controller; employ App\Commodity; class ArticleController extends Controller { public office alphabetize() { return view('articlesList', ['articles' => Commodity::all()]); } }
Now, the $articles
variable will be available in our articlesList
view:
<html> <head> </caput> <body> @foreach ($articles as $article) <div> <h2>{{ $commodity->title }}</h2> <p>{{ $article->content }}</p> </div> @endforeach </body> </html>
Each function of the lawmaking is at present separated into its corresponding layer, making it clean and maintainable.
Note: This example uses syntax like Article::all()
and @foreach
that will be explained later in the guide.
Dependency Injection
Dependency injection is a software design concept which states that a client (object) should only know which dependencies (e.g., services) it needs to perform certain functions, only should not know who supplies these dependencies or how they're constructed. This allows for loose coupling, which makes the lawmaking more flexible and less prone to errors. Nosotros'll talk more about this after.
Let's take a look at an case:
grade Article { protected $contentFormatter; protected $content; public office __construct($content) { $this->contentFormatter = new ContentFormatter; $this->content = $content; } public function getFormattedContent() { return $this->contentFormatter->format($this->content); } } $article = new Article('Lorem Ipsum Content'); $formattedContent = $article->getFormattedContent();
Nosotros tin meet how the Article
grade is responsible for instantiating the ContentFormatter
, when all it should really care about is providing the formatted content. Allow's implement dependency injection:
class Commodity { protected $contentFormatter; protected $content; public part __construct($contentFormatter, $content) { $this->contentFormatter = $contentFormatter; $this->content = $content; } public function getFormattedContent() { return $this->contentFormatter->format($this->content); } } $contentFormatter = new ContentFormatter; $article = new Article($contentFormatter, 'Lorem Ipsum Content'); $formattedContent = $article->getFormattedContent();
This might not seem like a big comeback at the moment, but it volition go much more apparent how this technique can solve architectural bug and make the lawmaking easier to maintain one time we've covered the Service Container section of this guide.
Object-relational Mapping (ORM)
ORM is a technique for converting data from relational database tables into objects, and vice-versa. Once constructed, these objects tin can then manipulate information via the API provided by the ORM implementation they're using, and relieve information technology into the database. This profoundly simplifies interacting with the database through lawmaking, and in most cases, does not require writing any SQL at all.
Here are some examples of how this works:
Article::where('is_active', 1)->get(); // select * from articles where is_active = one Article::create([ 'title' => 'Some Commodity Championship', 'content' => 'Lorem ipsum content' ]); // insert into articles (championship, content) values // ("Some Article Championship", "Lorem ipsum content") User::whereIsNull('email')->delete(); // delete from users where e-mail is null
Laravel Core Architecture
Past now, using everything we've talked virtually so far, managers should exist able to arts and crafts interview questions that will give insight into a programmer'southward understanding of some core programming concepts, and help weed out those who lack the experience to build the visitor'south next amazing project. But what well-nigh Laravel's specific architecture and features?
Service Container
The service container is the principal component of Laravel's dependency injection implementation. It provides several ways of registering dissimilar types of bindings. Peradventure the nearly commonly used container's feature is binding an interface to a given implementation.
app()->demark( 'App\Contracts\PaymentGateway', 'App\Services\StripePaymentGateway' );
This code instructs the container to inject StripePaymentGateway
when PaymentGateway
service is required by a class:
course PaymentController { protected $paymentGateway; public function __construct(PaymentGateway $paymentGateway) { $this->paymentGateway = $paymentGateway; } }
Provided our PaymentController
is resolved from the service container, its $paymentGateway
property will be an instance of StripePaymentGateway
. Call back the loose coupling we mentioned earlier? This is it. We've decoupled the client from the PaymentGateway
implementation, which ways, if at some bespeak nosotros decide to supervene upon Stripe with another payment gateway, nosotros can only demark PaymentGateway
interface to our new SomeOtherPaymentGateway
implementation, and everything else will piece of work without changing any of the lawmaking.
Service Providers
Service providers serve the purpose of bootstrapping a Laravel application. This includes registering different bindings, event listeners, or routes, as well as configuring things similar macros. All service providers must be registered inside the config/app.php
config file.
Service providers include two methods: annals
and boot
. The register
method should only be used to bind things into the service container. The boot
method is called after all the service providers take been registered, pregnant its code has access to all the dependencies registered in any service provider. This method also supports type-hinting dependencies:
namespace App\Providers; use Illuminate\Support\ServiceProvider; use App\Services\SomeService; course PaymentGatewayServiceProvider extends ServiceProvider { public function register() { $this->app->demark( 'App\Contracts\PaymentGateway', 'App\Services\StripePaymentGateway' ); } public function boot(SomeService $someService) { $someService->bootstrap(); } }
Laravel bootstraps all of its components through service providers, and by default ships with an empty provider (AppServiceProvider
) so developers can use information technology for whatever additional custom bootstrapping. In larger applications, additional bootstrapping can be split between any number of different custom service providers.
Request Lifecycle
All HTTP requests are handled past the HTTP kernel. Internally, the HTTP kernel runs all required bootstrappers before the request is really handled, which includes loading all of the service providers. Adjacent, the asking is passed to the router. The router runs all the applicable middleware—which nosotros'll talk over later—and and so dispatches the request to the specified controller.
Summary
Understanding Laravel'due south architecture is one of the keys to writing clean, flexible, and maintainable code. The programmer should know where certain parts of the lawmaking vest and how unlike components of the framework work together. Their power to answer questions on these topics should give interviewers conviction.
Laravel Fundamentals
With Laravel'south core compages clear, let's motility on to Laravel's extensive feature set, with which every seasoned programmer should exist well familiar. Each one of these modules is very probable to be used in the bulk of Laravel-based applications, then interviewers should make sure candidates understand all of the concepts in this section.
Routing
Routing is a way of directing requests to controller methods based on the URL of a request. While Laravel's router is a very powerful tool, we won't get into details most all of its features. Instead, we'll expect at its basic functionalities and the things you should pay attending to while reviewing a candidate's code.
Here's an example of a simple route definition:
Road::become('posts')->uses('PostController@index');
That road volition directly all /posts
Become requests to the index
method of PostController
.
By default, Laravel comes with web.php
and api.php
routes, located in the /routes
folder, and, every bit nosotros mentioned earlier, a sensible set of middleware assigned to these routes via the RouteServiceProvider
.
The registered routes support all HTTP verbs:
Route::become(...); Route::post(...); Route::put(...); Route::patch(...); Route::delete(...); Route::options(...);
Information technology's too possible to match multiple, or all verbs:
Route::lucifer(['get', 'postal service'], ...); Route::whatsoever(...);
Routes besides accept a closure instead of a controller activeness:
Route::get('post', role() { $posts = Post::all(); return view('postList')->with(['posts' => $posts]); });
…however, this is considered bad exercise in nearly cases and should non be used. It clutters the code and prevents the routes from beingness cached. Developers who are fairly familiar with Laravel volition know this and avert it.
When defining routes, you'll ofttimes need access to parts of the route URI called parameters. Parameters are segments encased within {}
, can be optional ({param?}
), and are automatically sent to the controller method:
Road::get('user/{userId}/posts/{postId?}')->uses('UserPostController@evidence'); // ... // UserPostController's show method public office show($userId, $postId = null) { ... }
Another characteristic of the router is named routes:
Route::become('posts')->name('posts')->uses('PostController@index');
This makes it possible to easily generate URLs for routes in our views:
<a href="{{ route('dashboard') }}">Dashboard</a>
Or, for example, redirect the user after a successful login:
return redirect()->route('dashboard');
While the router offers many more features, this sums upwards the basic ones. Proficient use of these features should come effortlessly for an experienced Laravel developer.
Middleware
Middleware is a blazon of filtering layer that HTTP requests must pass through earlier entering the awarding. For case, hallmark middleware tin can pass up the request if the user is not logged in, function middleware can redirect the user based on their user role, etc.
Past default, Laravel ships with a spider web
middleware grouping, which contains several useful middleware similar session handling and cookie handling. It's applied to all spider web requests past the RouteServiceProvider
.
Let'southward meet what a middleware class may expect similar:
namespace App\Http\Middleware; use Closure; class UserIsAdmin { public function handle($request, Closure $adjacent) { if (! $asking->user()->isAdmin()) { abort(403); } return $next($request); } }
When applied to a road, this middleware will make sure non-admin users are denied access to that route (we'll talk more nearly routing in a bit).
Middleware can be practical globally for every asking, and per route every bit a unmarried piece of middleware or a group of middleware. All middleware should be registered in the /app/Http/Kernel.php
class.
To run a piece of middleware for every HTTP request, add together it to the list in the $middleware
property of the HTTP kernel course.
To assign middleware to a particular road, coders demand to showtime add together them to the list in the $routeMiddleware
property:
// App\Http\Kernel Course protected $routeMiddleware = [ // Other middleware here... 'admin' => App\Http\Middleware\UserIsAdmin::form, ];
Now, the 'admin'
middleware tin be assigned to a road:
Route::get('assistants')->uses('AdminController@index')->middleware('admin');
When assigning multiple middleware to a route, developers may want to group it first under a single key in the $middlewareGroups
property:
protected $middlewareGroups = [ 'activeAdmin' => [ App\Http\Middleware\UserIsActive::course, App\Http\Middleware\UserIsAdmin::class ] ];
And and so assign it to a route using that central:
Route::become('administration')->uses('AdminController@index')->middleware('activeAdmin');
Let's look at our AdminController@alphabetize
method before applying the middleware:
// AdminController public office index(Request $request) { if (! $request->user()->isAdmin()) { abort(403); } return view('user.profile', ['user' => User::findOrFail($id)]); }
Imagine if we had several methods in the AdminController
which only admin users should have access to. We'd have to bank check for that condition in every unmarried method, which would unnecessarily clutter the code and make it harder to maintain. Later applying the admin
middleware to our assistants routes, nosotros tin make clean up the code past getting rid of the status check in the controller methods:
public function index(Request $request) { return view('user.profile', ['user' => User::findOrFail($id)]); }
When looking through the candidate's lawmaking examples, this is a detail managers would do well to pay attending to.
Controllers
Serving as mucilage between the presentation and data layers, controllers are 1 of the fundamental components of the MVC pattern. Pointing routes to controller methods allows you to hands organize request-handling logic within controller classes, which significantly improves code readability.
Controller methods tin return several types of responses. Let's list the most common ones:
// View: render view('homepage')->with(['someVariable' => 'some value']); // Response object: render response($content)->header('Some-Header', 'Header-Value')->cookie('cookieName', 'cookieValue', $minutes); // JSON: return response()->json(['data' => $data]); // File download: return response()->download($filePath)->deleteFileAfterSend(); // Redirect render redirect()->road('dashboard');
And a few other response types that may non exist used as frequently:
// String return 'Success'; // Assortment render [1, 2, 3]; // Redirect to a controller activeness: return redirect()->action('DashboardController@index'); // Redirect to external links: render redirect()->away('https://www.toptal.com/');
Before, we talked about assigning middleware to routes. There's also another style of assigning middleware: straight in the controller'southward constructor. Specifying middleware in this way as well supports attaching the middleware only to specific methods, or omitting it for specific methods. Let's expect at an example:
public function __construct() { $this->middleware('something'); $this->middleware('auth')->except('logout'); $this->middleware('invitee')->only('logout'); }
One more than important thing to address when information technology comes to controllers is dependency injection. When constructing a controller object, Laravel's service container will inject blazon-hinted dependencies both in its constructor:
public role __construct(GuzzleHttp\Customer $client) { $this->client = $client; }
…and in the chosen methods, where the most common injected dependency will be the Request
instance:
public part update(Illuminate\Http\Asking $request) { // ... }
This covers the essential features of Laravel'southward controllers. Understanding how controllers work and being able to use their features efficiently is a must for every dedicated Laravel programmer.
Session
Sessions provide a way to retain information across multiple HTTP requests: user authentication country, grade data that didn't completely validate, etc. Laravel supports multiple session drivers:
-
file
-
cookie
-
database
-
memcached
-
redis
The default driver is file
, considering that will work out of the box on basically whatsoever setup, and is adequate for almost applications. Only memcached
and redis
are preferred considering they're in-retention drivers, and therefore extremely performant.
There are two means to utilize the session feature provided by Laravel: Firstly, if we have access to the Request
case, we can call the session methods in the following way:
$request->session()->get('key');
Alternatively, we tin use the session()
helper, which will piece of work anywhere:
session('primal');
Let'south look at the most commonly used methods for manipulating session data:
// Get value for 'key', or default value if it doesn't exist: session('primal', 'default'); // Get all data in the session session()->all(); // Store value for 'cardinal': $request->session()->put('key', 'value'); session()->put('central', 'value'); session(['key' => 'value']); // Delete key session()->forget('key'); // Delete all session data: session()->flush();
Since maintaining state beyond multiple requests is one of the key features of spider web development, information technology'south important the developer is familiar with sessions and differences between supported session drivers.
Validation
Validation is a way to check incoming asking information against a set of rules. Laravel provides a simple, yet powerful, API to perform validation using numerous supported types of rules. As with many other Laravel topics, this one is extensive, so we'll cover the basics that should be part of every practiced Laravel developer'southward toolset.
There are iii different ways of using the validator. Firstly, if nosotros take access to the Request
instance, we can phone call the validate()
method on it:
public function update(Request $request) { $validatedData = $request->validate([ 'name' => 'required|string|max:150', 'email' => 'required|email|max:150' ]); // Utilise the validated data... }
Secondly, nosotros can type-hint a form request on a controller method. Course requests are custom request classes where developers tin can put validation logic, and they significantly reduce the ataxia in controllers. This is the preferred method of performing validation in most cases:
public function update(UpdateUser $request) { // The asking is automatically validated against the rules // defined in the rules() method in the UpdateUser grade // Fetch the validated data $validated = $request->validated(); }
This is what the rules()
method would await similar:
public function rules(Request $asking) { return [ 'proper noun' => 'required|string|max:150', 'email' => 'required|email|max:150' ]; }
Lastly, if the previous methods don't give enough control over validation or how the validation error responses are generated past Laravel, we can manually create a Validator
instance:
namespace App\Http\Controllers; use App\Http\Controllers\Controller; apply Illuminate\Http\Request; use Illuminate\Back up\Facades\Validator; class UserController extends Controller { public office update(Request $asking) { $validator = Validator::make($request->all(), [ 'name' => 'required|string|max:150', 'email' => 'required|e-mail|max:150' ]); if ($validator->fails()) { return redirect() ->dorsum() ->withErrors($validator) ->withInput(); } // Update user } }
The official listing of validation rules can be good interview question provender.
With that, we've covered the nearly important features of Laravel'due south validator, and hopefully given you insight into what to look for in the candidate'due south code samples.
Blade Templating
Blade is Laravel's powerful, easy-to-use templating engine. While we could write an entire article just about Blade, we're only going to go through the essential features every Laravel spider web developer should be familiar with.
Maybe Bract's virtually-used characteristic is its ability to extend layouts, use sections, and include sub-views. Allow'due south take a look at an example:
<!-- Main Layout --> <html> <head> <championship>Page</title> </caput> <body> @include('header') @yield('content') </torso> </html>
Here, we have a base of operations layout which is located in /resource/views/layout.blade.php
. It includes a header subview, /resources/views/header.blade.php
, and it displays content from the content
section of the view which extends the layout. Here's how we would write the /resources/page.blade.php
view containing that department:
@extends('layout') @section('content') <p>Lorem ipsum dolor sit amet.</p> @endsection
Our header subview could look like this:
<header> <h1>Lorem Page</h1> </header>
Now, we just need to return the page.blade.php
view from our controller method:
public function bear witness() { return view('page'); }
…and the rendered HTML will look like this:
<html> <head> <title>Folio</championship> </head> <body> <header> <h1>Lorem Page</h1> </header> <p>Lorem ipsum dolor sit amet.</p> </trunk> </html>
Yet, rather than just displaying static content, often, we'll need to ship data from controller methods to the Blade views where they'll need to be displayed. This can be done very hands:
public part show() { return view('page')->with(['pageTitle' => 'Some Page']); }
The $pageTitle
variable volition now be accessible in our views. Permit'due south display it in the header:
<header> <h1>{{ $pageTitle }}</h1> </header>
Sometimes, nosotros'll also have collections of information which we'll demand to iterate over and display in the view. For case, permit's pull Mail service
southward from the database:
public function evidence() { $posts = Mail::all(); return view('postList')->with(['posts' => $posts]); }
In resource/views/postList.blade.php
, Blade's @foreach
and @if
statements brand it a cakewalk to brandish only the active ones:
@extends('layout') @section('content') @foreach($posts as $post) @if ($post->is_active) <h2>{{ $postal service->championship }}</h2> {{ $post->content }} @endif @endforeach @endsection
While in that location's a lot more to the Bract templating engine, these are the fundamentals needed to write clean, scalable front end-end lawmaking. In few cases, if ever, volition Bract require any workaround solutions for a problem, then this is something to consider when evaluating the candidate'due south lawmaking.
Hallmark
Laravel comes with a complete and powerful, nevertheless simple, authentication system implementation. By default, information technology uses the App\User
model—specifically its electronic mail
and countersign
properties—to authenticate users.
Interacting with the authentication organisation is done in one of ii means:
- Using the
Illuminate\Back up\Facades\Auth
facade - Using the
auth()
helper part
Both support the aforementioned methods, so using one or the other is only programmer's preference.
Allow's look at the near usually used methods when working with hallmark:
// Try to log in a user using credentials supplied in the request if (auth()->attempt(['email' => $request->input('email'), 'password' => $request->input('password')])) { // User is authenticated } // Log in an existing user instance auth()->login($user); // Log a user in using their ID auth()->loginUsingId($id); // Retrieve authenticated user $user = auth()->user(); // Log the user out auth()->logout(); // Determine if the current user is logged in... if (auth()->cheque()) { // User is logged in } // ...or non if (auth()->guest()) { // User is not logged in }
This is a cursory overview of how Laravel'southward authentication arrangement works. Still, for most applications, this is actually everything that's needed to take advantage of its features. That, in plough, speeds upwardly the evolution process by doing all the heavy lifting when it comes to everything authentication-related. Having a good grasp of the authentication system is one of the things that makes a great Laravel practiced.
Authorization is a way of assuasive or preventing users to do certain actions—for example, creating a folio or updating their username. There are two unlike approaches: Gates and Policies. Gates are closure-based and are by and large used for actions which are not related to any item model, while policies are grade-based with each policy being specific for a single model.
Let's await at a couple of Gate
s, which will usually be defined in the AuthServiceProvider
:
public function boot() { $this->registerPolicies(); Gate::define('update-username', office ($user) { return $user->role == 'admin'; }); Gate::define('delete-page', office ($user, $page) { return $user->role == 'admin' && $folio->canBeDeleted(); }); }
Gates always receive a user instance every bit the first argument, and can receive any number of boosted arguments. To use Gate
s, we have two methods at our disposal—allows
and denies
:
if (Gate::allows('update-username')) { // Current user can update their username... } if (Gate::denies('delete-folio', $page)) { // Electric current user cannot delete the page... }
Unlike gates, each policy's focus is a single model. For example, if you lot have an application which has categorized items, you lot're likely going to have an Item
model and an ItemPolicy
that authorizes actions for that model.
Policies are registered in the policies
holding of the AuthServiceProvider
, where all models are mapped to their corresponding policies. The easiest fashion to create a policy is via the artisan make:policy
command:
php artisan make:policy ItemPolicy
The policy should contain a corresponding method for each model action that needs to be authorized, like update
or delete
, and should return true
if the action is authorized, or imitation
if it's not. Each method will receive the user example as its first parameter, and optionally an case of the model for which the action is beingness authorized:
namespace App\Policies; utilise App\Item; utilise App\User; class ItemPolicy { // Every user can create an Item public role create(User $user) { return true; } // Simply item's possessor can update the Item public office update(User $user, Item $particular) { return $particular->user_id == $user->id; } // Only administrator can delete an item public function delete(User $user, Item $detail) { return $user->role == 'admin'; } }
There are several means we can apply policies. The about common ones are calling the can
and deceit
methods on the user example:
if ($user->tin can('create', App\Particular::class)) { // ... } if ($user->cant('update', $item)) { // ... }
…and calling the authorize
method within a controller method on the controller instance:
public function delete(Asking $request, $itemId) { $detail = Particular::find($itemId); $this->authorize('delete', $detail); // User tin can delete the particular }
Gates and policies offer a clean and simple mode to extract and group an app's authorization logic. A proficient Laravel programmer will use these methods to continue their lawmaking clean, readable, and scalable.
Collections
The Collection
grade is a powerful wrapper for PHP arrays. It provides numerous user-friendly methods for working with arrays, such as map
, filter
, and contains
.
Creating a collection is very elementary. We just call the collect()
helper function and laissez passer an array as an argument:
$drove = collect(['some', 'values', 'hither']);
Now, permit'south accept a await at some examples of how collections can make a programmer's life easier and the code cleaner:
collect([20, 13, 18, 22])->sort()->values()->toArray(); // [13, xviii, 20, 22] collect([ ['name' => 'John', 'historic period' => twenty], ['name' => 'Jane', 'age' => 30], ['proper noun' => 'Mark', 'age' => 35], ['name' => 'Fizz', 'age' => 18] ])->filter(function($item) { render $item['historic period'] >= 30; })->toArray(); // [['proper name' => 'Jane', 'age' => 30], ['name' => 'Mark', 'age' => 35]] collect([ ['folio' => 'Home'], ['page' => 'Near Us'] ])->map(role($item) { $particular['slug'] = Str::slug($item['folio']); render $particular; })->toArray(); // [['page' => 'Dwelling house', 'slug' => 'home'], ['page' => 'About United states of america', 'slug' => 'nearly-us']]
This is merely a tiny fraction of what the Collection
class is capable of. In a proficient programmer's hands, collections will all only render PHP'southward native functions for working with arrays obsolete—speeding upwards evolution and increasing code readability. Good Laravel developers will utilise collections wherever possible; anything less should exist considered a red flag.
Artisan
Artisan is a control-line interface (CLI) that ships with Laravel. It provides numerous convenient commands for automating tedious, everyday tasks while writing an application, like generating controllers, models, and jobs; caching config, routes, and views; clearing the cache; creating migrations; and many more. (Running the php artisan list
command gives a full list of commands.)
While the built-in commands are sufficient in most cases, sometimes, a developer volition want to be able to execute some arbitrary, custom code via an Artisan control. They can do and so by creating a custom command, which volition exist placed in the /app/Console/Commands
binder:
php artisan make:command PruneUsers
Custom commands consist of $signature
and $description
properties, and the handle()
method. $signature
is used to run the command—for instance, php artisan clip:users
—and it will be displayed alongside the $clarification
when artisan list
is called. When running the command, the handle()
method is called. This is where developers identify the code to be run, and where they type-hint whatsoever dependencies:
namespace App\Console\Commands; use App\User; use App\Repositories\UserRepository; utilise Illuminate\Panel\Control; class PruneUsers extends Command { protected $signature = 'prune:users'; protected $description = 'Prune inactive users'; public function __construct() { parent::__construct(); } public function handle(UserRepository $userRepository) { $userRepository->inactiveUsers()->delete(); } }
As we can see, Artisan commands can be very handy for automating certain tasks, and/or having quick and clean access to functionality both via the scheduler and the CLI. Being familiar with the Artisan CLI can increase productivity and help developers make clean up their code.
Queues
Laravel queues enable apps to offload lengthy tasks (sending emails, generating reports, etc.) to the background for processing, which significantly increases app responsiveness. While this topic is very comprehensive, we're going to give a cursory overview of how queues piece of work and how to utilize them.
Laravel supports several different queue drivers out of the box: database, Beanstalkd, SQS, and Redis. For local testing, in that location is also a sync
driver, which executes tasks immediately. Usually, developers will opt for one of these built-in connexion options and configure several different queues ("lanes" that tasks can exist dispatched into) on information technology—for example, one might have an emails
queue and a reportGeneration
queue. All of this is configured within the /config/queue.php
configuration file.
With the configuration all set, we can start sending jobs onto queues. A Job
is a dispatchable class, which just ways it implements the Illuminate\Contracts\Queue\ShouldQueue
contract so it tin be easily sent off to a queue by calling the dispatch()
method on it. One time in a queue, a job'southward handle()
method volition be chosen—this is where the task-processing logic is coded.
Jobs are created by running the make:job
Artisan command:
php artisan make:chore GenerateReport
Let'due south expect at an case of a Chore
class:
namespace App\Jobs; employ Illuminate\Omnibus\Queueable; utilize Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; class GenerateReport implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; protected $reportData; public part __construct($reportData) { $this->reportData = $reportData; } public function handle() { // Generate Report logic... } }
Now, permit's dispatch information technology:
class ReportController extends Controller { public part generate(Request $request) { GenerateReport::acceleration($asking->all())->onQueue('reportGeneration'); return response()->json(204); } }
One time the job has been dispatched onto the queue, it will get picked upwards past a queue worker. Queue workers are long-lived processes that hold the electric current Laravel application state in memory, and procedure jobs in queues. This means they will not pick up any code changes to your application, then you'll need to restart queue workers each fourth dimension y'all update the application. Queue workers are started and restarted with the following Artisan commands:
# first php artisan queue:piece of work # restart php artisan queue:restart
Queues can exist a very powerful tool in a Laravel developer's arsenal. Therefore, the candidate should be familiar with how and when queues should exist used, and the basic deviation between supported queue drivers.
Task Scheduling
Instead of having to ssh
into a server and define a separate cron
task for every recurring task, Laravel's task scheduler allows developers to do so inside PHP lawmaking using a fluent API. To brand this work, all that's needed is to gear up a unmarried cron
job on the server that runs the php artisan schedule:run
command every minute. Laravel will leverage this cron
task to assess the app's defined tasks and run the ones that are due.
Scheduled tasks are defined in the schedule
method of the App\Panel\Kernel
form. The scheduler can run Artisan commands, queued jobs, or whatever other arbitrary piece of code:
protected function schedule(Schedule $schedule) { // Run an artisan command in one case a week $schedule->control('locations:update-images')->weekly(); // Queue a GenerateReport task in one case a 24-hour interval $schedule->job(new GenerateReport)->daily(); // Execute arbitrary lawmaking every thirty minutes $schedule->call(function () { // Code... })->everyThirtyMinutes(); }
The Laravel scheduler also supports various commands for defining the frequency at which the tasks volition execute, similar daily()
and weekly()
used in our examples.
Laravel's job scheduler is a very convenient tool for "porting" cron
job definitions from the server to the app codebase, and therefore assuasive developers to continue them inside a project'south version control arrangement (VCS)—e.grand., Git, also as making them more readable and elegant. Developers who know Laravel'southward ins and outs will also know how to use the features offered by the chore scheduler to their advantage.
Database
Interacting with a database in Laravel is very simple, using either the Illuminate\Support\Facades\DB
facade, or the Eloquent ORM. Nosotros'll talk about Eloquent in a scrap; for now, let'southward wait at how nosotros can run raw SQL queries using the DB
facade:
// Select statement DB::select('select * from posts where id > ?', [twenty]); // Insert argument DB::insert('insert into posts (title, slug, content) values (?, ?)', ['First Post', 'first-mail', 'Lorem ipsum content']); // Insert statement DB::update('update posts ready content = ? where slug = ?', ['Dolor sit down amet content', 'beginning-post']); // Delete argument DB::delete('delete from posts where slug = ?', ['first-post']); // General statement DB::statement('Modify TABLE posts Alter title post_title VARCHAR(255) Graphic symbol Ready utf8 COLLATE utf8_unicode_ci');
Running raw SQL statements is sometimes required, but most times, there'southward a better, more readable, API-based mode of generating SQL queries: the query builder. Laravel's query builder offers a user-friendly way of generating almost any query an application volition ever need. Let's wait at the nearly commonly used methods:
// get() method returns a Collection of results $posts = DB::table('posts')->become(); // where() method appends the WHERE clause $posts = DB::table('posts')->where('id', '>', 20)->become(); // outset() method returns the offset result every bit an // stdClass object that matches the criteria $posts = DB::table('posts')->where('slug', 'some-post')->starting time(); // orderBy() method sorts the results $posts = DB::orderBy('created_at', 'desc')->get(); // insert() method inserts a row into the database DB::table('posts')->insert( ['title' => 'Some Mail service Title', 'slug' => 'some-post', 'content' => 'Lorem ipsum content'] ); // update() method updates a row in the database DB::table('posts')->where('slug', 'some-post') ->update(['content' => 'Dolor sit amet content']); // delete() method deletes rows from the database DB::tabular array('posts')->where('agile', 0)->delete();
Here's a few more examples of what can be achieved using the query builder:
// Select all posts which are either active, // or created by users with id 1, ii or 3 $posts = DB::table('posts')->where('is_active', 1) ->orWhereIn('user_id', [1, 2, 3])->get(); // Skip 20 posts, then select the next 10 $posts = DB::table('posts')->skip(20)->take(10)->get(); // Join posts with users, and select all columns from // 'posts' tabular array, and 'proper noun' from 'users' table $posts = DB::tabular array('posts') ->join('users', 'posts.user_id', '=', 'users.id') ->select('posts.*', 'users.name')->get();
Another user-friendly feature provided by the DB
facade are transactions. A transaction ensures that either all of the queries within it are executed, or none are. At that place are two ways to use transactions: closure-based and manually:
// Closure based DB::transaction(role () { DB::tabular array('users')->where('id', 5)->update(['active' => 1]); DB::table('users')->where('agile', 0)->delete(); }); // Transmission effort { DB::beginTransaction(); DB::table('users')->where('id', 5)->update(['active' => 1]); DB::table('users')->where('active', 0)->delete(); DB::commit(); } catch (\Exception $e) { DB::rollback(); }
The closure-based approach is mostly simpler to apply considering it automatically handles committing its transaction, or rolling it dorsum in instance of an exception. But the manual approach tin can offer more than control in situations where that's needed.
I final, but definitely non to the lowest degree, feature to mention is database migrations. Migrations are classes which allow for version-controlling database changes—everything from creating tables and columns, deleting them, and updating them. They consist of upwards
and down
methods. The upwardly
method is run when showtime changing the database in some manner (creating a table, column, etc.), and the down
method is used for reverting those changes.
Migration classes are generated past running the make:migration
Artisan command:
php artisan make:migration create_posts_table
Artisan places the migration files in the /database/migrations
folder. A migration file will include various column types (string, text…) and modifiers (index, nullable…):
use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Design; utilise Illuminate\Back up\Facades\Schema; course CreatePostsTable extends Migration { public role upwardly() { Schema::create('posts', role (Design $table) { $table->id(); $table->string('title')->alphabetize(); $table->cord('subtitle')->nullable(); $table->string('slug')->index(); $table->text('content'); $table->timestamps(); }); } public part downwards() { Schema::drop('posts'); } }
Migrating the database is done via the drift
Artisan control:
php artisan drift
This will run the up
method in the migration classes. Rolling back the migrations is done by running:
php artisan migrate:rollback
This will run the down
method in the migration classes.
While options for interaction with databases are plentiful in Laravel, the API is fairly easy to remember, which makes for an efficient developer experience. Having a deep agreement of how the database API works is very important for Laravel application evolution, as it affects both productivity and code quality.
Eloquent: Laravel'southward Object-relational Mapper (ORM)
Eloquent is likely the almost complex component of the Laravel framework, but its basic functionalities are the foundation for using Laravel proficiently. Each Eloquent model maps directly to a database table, and each Model
object maps to a database row in that table. This, and the fact that information technology uses Laravel'due south query builder underneath to generate SQL queries makes it an invaluable tool for interacting with the database in an object-oriented mode.
All Eloquent models must extend the Illuminate\Database\Eloquent\Model
class, and the easiest style to create them is by using the brand:model
Artisan control:
php artisan make:model Post
This volition generate the post-obit grade in the app
folder:
namespace App; employ Illuminate\Database\Eloquent\Model; grade Post extends Model { // }
By default, the table name the model corresponds to will be auto-guessed by Eloquent—for our particular example, a posts
table. If developers wish to define a custom tabular array proper name, they can use the protected $table
property on the model.
Now that nosotros have our model and know which database table it volition utilise, let'southward look at the most common operations we can perform, using the same fluent API as we did with the query architect:
// Return a drove of Postal service objects $posts = Post::all(); $posts = Postal service::where('agile', one)->become(); $posts = Mail::where('user_id', 5)->orderBy('created_at', 'desc')->get(); // Return a single Post object $post = Postal service::find(5); $post = Mail service::where('slug', 'some-post')->showtime(); // Create a Mail service object $postal service = Mail::create(['title' => 'Some Mail service', 'slug' => 'some-post', 'content' => 'Lorem ipsum content']); // Update the Postal service object Post::where('slug', 'some-post')->update(['content' => 'Dolor sit amet content']); // Alternatively $postal service = Mail::where('slug', 'some-mail')->starting time(); $post->content = 'Dolor sit amet content'; $mail service->save(); // Delete the matching Post objects Post::where('active', 0)->delete(); // Alternatively, delete a Post object $postal service = Mail service::where('slug', 'some-postal service')->first(); $post->delete();
Another powerful feature of the Eloquent ORM is managing table relationships. For case, a Category
model may have many Post
s, and a Post
may vest to a User
. Eloquent provides a fluent API for managing several types of relationships:
- One to one
- One to many
- Many to many
- Has i through
- Has many through
- One to one (polymorphic)
- One to many (polymorphic)
- Many to many (polymorphic)
We're going to accept a look at the nearly commonly used relationships:
- One to many (a
Category
has manyPost
s) - Its inverse, belongs to (each
Post
belongs to a unmarriedUser
) - Many to many (a
Postal service
has manyTag
due south, and aTag
can belong to manyPost
southward)
Relationships are defined every bit methods that render a relationship instance. Let'south define the ane to many Post
southward human relationship on our Category
model:
grade Category extends Model { public role posts() { render $this->hasMany('App\Post'); } }
For this relationship to piece of work, we must accept a category_id
column in our posts
table, which is automatically assumed past Laravel by concatenating category
(snake-cased name of the Category
model) and adding _id
to it. Now we can call the relationship:
$categoryPosts = $category->posts()->get();
This will render a collection of Postal service
due south that belong to the given Category
. Alternatively, we tin achieve the same result by calling posts
equally a dynamic holding instead of the posts()
method. Eloquent is smart enough to map the posts
dynamic belongings to the human relationship method and return the desired Postal service
s collection:
$categoryPosts = $category->posts;
We can likewise apply filters, aforementioned every bit we did earlier:
$activePosts = $category->posts()->where('agile', 1)->orderBy('created_at', 'desc')->get();
If we want to find out which User
owns a certain Post
, nosotros tin can define changed of the hasMany
relationship (belongsTo
) on our Post
model:
class Post extends Model { public function user() { render $this->belongsTo('App\User'); } }
Let'due south call it:
$user = $post->user;
One time once more, notice we're non calling the user()
method, just rather the user
dynamic property.
The many to many human relationship requires an additional, intermediary (pivot) table. If we desire our Postal service
s to take many Tag
s, and the Tag
s to belong to many Mail service
south, and so our intermediary table will need to be named post_tag
(snake-cased models ordered alphabetically) and have post_id
and tag_id
columns.
At present nosotros tin can define relationships on the models:
class Post extends Model { public function tags() { return $this->belongsToMany('App\Tag'); } } course Tag extends Model { public office posts() { return $this->belongsToMany('App\Postal service'); } }
This allows the states to find all the Tag
s for a given Mail service
:
$postTags = $postal service->tags()->become();
And all the Post
south a given Tag
belongs to:
$tagPosts = $tag->posts()->go();
Eloquent also provides a way of optimizing database queries using eager loading. Eager loading solves the "N + 1 problem" when iterating over a collection of Model
objects and querying their relationships. For instance, let'due south iterate over a category's posts and display the proper noun of each post's user:
$category = Category::observe(one); foreach ($category->posts equally $mail service) { echo $post->user->name; }
If our category has 10 posts, this code segment will generate 12 queries. Allow's encounter what happens:
Category::find(ane);
This will query the database for a Category
with an ID of 1.
foreach ($category->posts ...
This will load the category's posts into the Category
object. Now comes the problematic role:
$post->user...
We have x posts, and each post will query the database to fetch the user who owns the post, so we can display their name. To gear up this, nosotros tin eager load all the users for all of our category'south posts:
$category = Category::with('posts.user')->where('id', i)->starting time();
Past calling the with('posts.user')
method, we can tell Eloquent that we want information technology to discover all the posts belonging to the category with ID one, then find all of their users in a single database query. This volition result in a total of merely three queries, regardless of the number of posts the category has:
- I query for fetching the category
- One query for fetching all of its posts
- One query for fetching all of users for these posts
This sums upwardly the basics of the Eloquent ORM. While Eloquent tin can practice much more than what we've discussed here, this should be enough to evaluate how far the developer's knowledge reaches. Understanding Eloquent is a must for every expert Laravel developer, so including Eloquent-related questions in the interview procedure volition go a long way.
Debugging
Laravel's simplicity can exist a double-edged sword. It can fool novice developers into thinking that writing lawmaking will always exist a smooth experience, and goose egg can ever go incorrect. But that's not how software development works: Once they hit a wall in the form of a deceiving bug, they'll get lost and won't know how to movement frontwards. An mistake 500 screen will be presented to them, and they won't know what the adjacent step is toward the solution.
One of the nigh valuable traits of an experienced developer is being expert in debugging. When it comes to Laravel, there are several methods to debug an application.
The first thing the programmer should exist enlightened of is the debug
option in the config/app.php
config file: When set to true
, after striking an exception in code, the exception details screen volition exist shown in the browser, instead of a blank fault 500 page. This will, in most cases, bespeak us to the exact line of code where the exception happened and provide a lot of helpful information well-nigh the exception. All of this information will also be written to the storage/logs/laravel.log
log file, regardless of the value of the debug
option.
Another great mode to debug is using the Laravel Debugbar library. Autonomously from displaying all of the exception-related data, Debugbar will also provide information about request data, session information, and executed database queries, which tin can speed upwardly debugging considerably. Other debugging libraries worth mentioning are Laravel Telescope and the Clockwork browser extension.
How to Rent the All-time Laravel Developers: Experience with Best Practices Is Central
Finding and hiring a great Laravel freelancer can definitely be a tall order. The simplicity of the Laravel framework and its excellent, easy-to-empathize documentation brand it easy for almost whatever developer to choice it up speedily, regardless of their experience. This tin can make information technology hard to weed out novice developers and notice the right fit for your team.
Our Laravel hiring guide provides enough knowledge and understanding of how Laravel spider web development works to help recognize skilled developers in the U.s.a. or abroad and make the right selection for their business concern needs. Still, not knowing everything mentioned in this guide off the meridian of their head does non necessarily hateful the developer is not good at what they do. And vice-versa: Memorizing all of Laravel'due south documentation without any practical years of experience does not make a developer great.
With this guide on how to hire dedicated Laravel developers, interviewers can readily craft the relevant interview questions they need, evaluate their candidates' knowledge, and brand the final telephone call within their normal hiring models. Best of luck!
Source: https://www.toptal.com/laravel
Posted by: royliting.blogspot.com
0 Response to "How To Use Service Providers To Their Full Potential Laravel"
Post a Comment