GSD

Laravel Best Practices for Developers in 2023

Posted by Goodness Woke on September 26, 2023

In today’s society, the only thing that has been proven to be constant is change, or in the case of the web development space, innovation. All you have to do is take a look around to see all the tools that have been created to make processes easier for developers. One of these tools, as you've probably guessed by the title of this article, is none other than Laravel. Laravel is a PHP framework that attempts to take the pain out of development by easing common tasks used in the majority of web projects such as authentication, routing, sessions, and caching.

Laravel aims to make the development process a pleasing one for the developer without sacrificing application functionality. It is descriptive and eloquent, also it possesses a simple syntax that aids in the creation of extraordinary applications. 

What is Laravel?

Laravel is a popular and respected open-source, free PHP programming language framework that is aimed at making development processes appealing without having to sacrifice quality. It uses an MVC (Model View Controller) pattern which makes the language more relatable and adaptable. It can also be regarded as a web application framework with expressive and elegant syntax that attempts to take the pain out of development by easing common tasks used in web projects and applications.

For history's sake, you should know that Laravel was built in place of the CodeIgniter framework as a modern replacement because the CodeIgniter framework missing important core features such as built-in support for user authentication and authorization. Since its initial launch in 2011 Laravel has implemented built-in support for localization, views, dealing with sessions, routing the request to the specific controller, and other amazing features.

PHP problems that Laravel fixes

Over the years Laravel has come to solve various PHP problems such as the following:

  • It makes sure that unauthorized users have no illegal access to paid or secured resources, it configures almost everything out of the box.
  • In Laravel, error handling comes pre-configured, and errors are logged in a App\Exceptions\Handler class.
  • Laravel is also known to be a resolution for a lack of efficiency in applications and application building, this framework is equipped with tools that help speed up both the development process and the application itself such as IDE Helper and Laravel Mix. You can check out more of these tools here.
  • Equally, the problem of putting in place a task scheduling system is solved by a built-in command scheduler allowing you to configure your schedule within Laravel.
  • The idea of going through repetitive programming tasks can often be overwhelming, but the PHP Artisan command-line used when interacting with Laravel completes numerous programming tasks so developers don’t have to do them manually.
  • Due to its large user base and active community, technical vulnerabilities are more often than not, quickly spotted and taken care of by the Laravel maintenance team.
  • Laravel also comes equipped with out-of-the-box PHPunit tests and functionalities to enable expressive testing. Also, executing automated testing sessions which are more precise than the manual ones.
  • When there’s a drawback from sending out notifications to your system subscribers, backing up events via API over the SwiftMailer to SymfonyMailer library suffices.
  • When you’d like to specify your user’s intention for the system to understand where the user is navigating, Laravel allows for configuring URL routing for easy route configuration.

Structure of Laravel

Diagram of the structure of laravel

Core features of Laravel

The Laravel framework also has incredible features that make-up its structures such as:

  • Laravel Eloquent ORM (Object Relational Mapping): Eloquent ORM is software found in the Laravel framework. It creates efficiency in the task of interacting with database tables and eases database record handling by representing data as objects. This can be used by PHP web developers as a basic PHP Active Record Specification to simply execute relational databases using the PHP syntax. As a result, there is no requirement to write SQL code. ORM is considered faster than any other PHP framework. Eloquent ORM is also quite famous for working with databases. Models have made the insertion, update, deletion, and synchronizing of multiple databases effortless. You have to just define database tables and the relation between them and all is set.
  • Security standards: It’s really hard in the business world to say something is 100% secured, but in the case of Laravel web apps, it’s all up to the web developer. The risk of a security breakage or finding errors is reduced if the web developer writes and organizes it correctly. The Laravel structure provides an incredible level of protection that is hard to find in other systems. It brings with it Security-related CSRF tokens, which make sure that the authenticated user is the person actually making the request to the application. The PHP system also generates secure data using the Bcrypt Hashing Algorithm. Similarly Laravel stores passwords in the folder as hashed and salted hashes rather than plain text.

People looking at a web browser window covered in security icons

  • Debugging and testing: When changes occur in any web interface, there are chances that issues will arise as a result. Laravel, however, with useful tools such as Debugar and Telescope, is quick-witted enough to foretell future let-down and execute tests to make sure that the developers’ changes do not result in a bug that will further break the application’s functionality. These tools also assist the developer in keeping an eye on the errors and bugs that may occur during development. 
  • Laravel plugin usage: Laravel supports the use of a plugin mechanism solution for developers who would love to build their own ecosystem. It supports multi versions of plugins such as Canvas, Document templates, etc. You can find a plugin that best suits your taste here.
  • Route handling: It handles routes in an extremely simple way and can be used to build a single interface between your data and client, thereby making it a great candidate for RESTful APIs. In simpler terms, it allows requests to a specific URL like “login” which is very useful for social networks and sites.
  • Authentication: There are numerous ways to implement authentication. Laravel sets that up for us; all needed to be done by the developer is to run a simple command line to enable everything for authentication. As initially mentioned, this feature allows only genuine users access to a site.
  • Session/Cache handling: Laravel collects requests and in that process stores information about the user in drives like file, Redis, Memcached, etc. Items stored or kept away can be easily retrieved because they are stored in a fast and easily accessed data store like the above mentioned. Laravel provides us with mechanisms to compile assets with all the intricacies of storage and file management. This cache handling increases the speed of an application.
  • Unit testing: Just as the name implies, unit testing performs tests on single models and controllers, for the purpose of uncovering issues. According to Laravel documentation support for testing with PHPUnit is included out of the box and a phpunit.xml file is already set up for your application whenever you get started.

undefined

What is Laravel best used for?

Custom web applications and content-heavy sites

When building robust custom web applications and sites that house a large amount of content like blogs (see how you can build a blog with Laravel here), etc., Laravel is the PHP framework that comes to mind due to its enhanced performance capabilities and peculiar way of handling traffic. It’s quite common that large-scale applications can be slow but with Laravel’s enhanced performance capability it’s possible to boost the speed of the application irrespective of the application's size. Laravel is able to offer speed benefits for larger applications due to the fact that it is configured to use file cache drivers like Memcached and DynamoDB which stores cached objects in the file system. Also, when the website or application gains traffic which in this sense, refers to a large number of users simultaneously visiting the website. Laravel being equipped with cache backends is there for back up so there’s no application/website breakdown.

Multilingual applications

The primary purpose for building a multilingual application is so you can provide clients/users with the best user experience possible irrespective of their language. Implementing this feature on any device is not only possible if using Laravel, but also quite easy. Laravel has a localization feature that provides a convenient way for retrieving strings in various languages, allowing you to easily support multiple languages within your application. 

Social networking sites

It’s also a great option for building Social network sites because it has a middleware feature and tight security. This feature, which is available by default in Laravel, makes it the best tool for allowing only genuine users access to a specific site. 

E-Commerce sites

Laravel is a great contender for building e-Commerce websites due to its robust authentication system which helps provide room for safer transactions. When a customer logs into your website and wants to purchase an item, Laravel makes sure they’re able to identify themselves and carry out transactions in the most secure way possible. Laravel also helps prevent lock-in which in this case refers to a situation whereby sign-in systems become slow or difficult. Laravel’s authentication allows customers to securely access the website in a simple interface without having to experience lock-ins. 

Laravel best practices for 2022

Alright, time for the main event! In this section, we'll go over the best practices you should take into consideration while working with Laravel 9 to ensure that your code is as clean and efficient as possible. All of the code snippets used below can be found here

Always use the most stable release

The latest version of Laravel, Laravel 9.x, was released in February 2022. This new release has come with some important updated features detailed below:

  • Migration: Laravel has made anonymous stub migration the default behavior when you run the popular migration command: php artisan make:migration. The issue here is that multiple migrations with the same class name can cause problems when trying to recreate the database from the beginning. This new stub migration feature removes the migration class collisions. From Laravel 8.37, the framework now supports anonymous class migrations files while in Laravel 9, it is the default behavior.
  • There’s a refreshed ignition error page that comes as default when using Laravel 9.
  • New query builder interface: With Laravel 9, type hinting comes with a great level of efficiency for refactoring, inactive analysis, and code completion in their IDEs. With Laravel 9, developers can now enjoy the new query builder interface for type hinting, refactoring, and static analysis.
  • The migration from Swift Mailer to Symfony Mailer for mail conveyance.
  • The route list has a new design: 

New route list design

Source: Laravel Magazine

More of these features can be unearthed here.

Keep business logic in service class 

Controllers are by far the least things to be thought about when it comes to handling business logic because it causes confusion when this functionality needs to be reproduced in lots of places, therefore the code should be kept clean by putting logic in service classes to avoid having issues with always repeating yourself. 

Do this:

 public function store(Request $request)
{
    $this->DownlineService->shareCommissionToDownlines($user, $commission);

    ....
}

class DownlineService
{
    public function shareCommissionToDownlines($user, $commission): void
    {
        if (!empty($user), !is_null($commission)) {
            # code to share commission to downlines
        }
    }
}

Use helper functions

Some people will be tempted to reinvent the wheel by creating their own PHP helpers but that’s not safe and can be task heavy, instead use the helper methods provided in Illuminate/Support/Str which can be called anywhere in the app.

Don’t do this, it’s a bad practice:

public function newId()
{
    $str_result = '23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjklmnpqrstuvwxyz';

    $id = substr(str_shuffle($str_result), 0, 24); 
}

Do this:

public function newId()
{
    ....
    $id = Str::random(24);
    ....
}

Obey the single responsibility principle (SRP)

A class and method should have just one responsibility this makes software implementation easy and intercepts any unforeseen side effects that might arise due to changes that might occur in the future.

Don’t do this, it’s a bad practice:

public function getTransactionAttribute()
{
    if ($transaction && ($transaction->type == 'withdrawal') && $transaction->isVerified()) {
        return ['reference'=>$this->transaction->reference, 'status'=>'verified'];
    } else {
        return ['link'=>$this->transaction->paymentLink, 'status'=>'not verified'];
    }
}

Do this:

public function getTransactionAttribute(): bool
{
    return $this->isVerified() ? $this->getReference() : $this->getPaymentLink();
}

public function isVerified(): bool
{
    return $this->transaction && ($transaction->type == 'withdrawal') && $this->transaction->isVerified();
}

public function getReference(): string
{
    return ['reference'=>$this->transaction->reference, 'status'=>'verified'];
}

public function getPaymentLink(): string
{
    return ['link'=>$this->transaction->paymentLink, 'status'=>'not verified'];
}

Carry out validation in request classes

All forms of validations should be done in the request classes because it carries with it options like form request which is a separate request class containing validation logic, there’s nothing really odd about validating requests with other methods but it’s doing it the best way that counts.

This can’t be classified as the best practice:

public function store(Request $request)
{
    $request->validate([
        'slug' => 'required',
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
        'flImage' => ['image', 'required', 'mimes:png,jpg,jpeg,gif']
    ]);
}

To validate in request classes, do this:

public function store(CreateArticleRequest $request)
{    
    ....
}

class CreateArticleRequest extends Request
{
    public function rules(): array
    {
        return [
            'slug' => 'required',
            'title' => 'required|unique:posts|max:255',
            'body' => 'required',
            'flImage' => ['image', 'required', 'mimes:png,jpg,jpeg,gif']
        ];
    }
}

Timeout HTTP request

Prevent timeout errors by using the timeout method on the HTTP client. By default, Laravel will timeout after 30 seconds. networks can be unreliable. If there is a delay in the request along the way, and you never receive an official error response, your application will hang indefinitely and this is why timeouts are important.


A perfect instance:

public function makeRequest(CreateArticleRequest $request)
{
    ....
    $response = Http::timeout(120)->get(...);
    ....
}

Take advantage of mass assignments

Mass assignments help prevent mass assignment vulnerabilities. Mass assignment vulnerabilities in this case is a situation where an active record pattern in a Web App is abused to modify data items that the user should not normally be allowed to access such as password, granted permissions, or administrator status. 

This is setting a bunch of fields on the model one by one. Don’t do this:

$product = new Product;
$product->name = $request->name;
$product->price = $request->price;
$product->qty = $request->qty;
$product->save();

Here an array is sent to the model creation, basically setting a bunch of fields on the model in a single go. Do this:

Product::create($request->validated());

Chunk data for heavy data tasks

Here, you’re given the opportunity to use the function chunk() to break down heavy data tasks or split data. This is most beneficial when on a time-consuming and drudgery-filled task so as to boost efficiency.

Doing this, you’ll have to repeat yourself on numerous occasions. Don’t do this:

$articles = $this->get();

foreach ($articles as $article) {
    ...
}

Applying the chunk data, you’ve basically split the data task. Do this:

$this->chunk(100, function ($articles) {
    foreach ($articles as $article) {
        ...
    }
});

Do not use environment variables (.env) directly in your code

Environment variables which are well known as a value that can affect the way running processes will behave in a computer should only be used  in config() helper function. Use config() to access .env variables. Any variable in your .env file can be overridden by external environment variables such as server-level or system-level environment variables if this is not followed.

Applying the environment variable directly into your code is a bad practice. Don’t do this:

$apiKey = env('API_KEY');

Instead, use the .en() within the config file. Do this:

// config/api.php
'key' => env('API_KEY'),

// Use the data
$apiKey = config('api.key');

Use eloquent instead of query builder and raw SQL queries

Eloquent allows you to write readable and maintainable code. In addition to that, Eloquent also has great built-in tools like soft deletes, events, scopes, etc., which allow you to add constraints to all queries for a given model because constraints in SQL help to maintain the accuracy, integrity, and reliability of a table's data. It is also easier to manage relationships between models with this because all the relationships serve as query builders.

You don’t need to write SQL codes where Eloquent is already found in the Laravel framework. Don’t do this:

SELECT *
FROM `products`
WHERE EXISTS (SELECT *
              FROM `categories`
              WHERE `products`.`category_id` = `categories`.`id`
              AND `categories`.`deleted_at` IS NULL)
AND `is_available` = '1'
ORDER BY `created_at` DESC

Eloquent creates efficiency, so do this:

Product::has('category')->isAvailable()->latest()->get();

Maintain Laravel naming conventions

Follow the PSR Standards as stated here, and also use the naming conventions accepted by the Laravel community which will help in organizing your files. Using consistent naming conventions is important because inconsistencies can cause confusion which will eventually lead to error. A tabular guideline is provided below.

What

How

Good

Bad

Model

singular

User

Users

hasOne or belongsTo relationship

singular

articleComment

articleComments, article_comment

All other relationships

plural

articleComments

articleComment, article_comments

Table

plural

article_comments

article_comment, articleComments

Route

plural

articles/1

article/1

Pivot table

singular model names in alphabetical order

article_user

user_article, articles_users

Table column

snake_case without model name

meta_title

MetaTitle; article_meta_title

Model property

snake_case

$model->created_at

$model->createdAt

Controller

singular

ArticleController

ArticlesController

Contract (interface)

adjective or noun

AuthenticationInterface

Authenticatable, IAuthentication

Trait

adjective

Notifiable

NotificationTrait

Foreign key

singular model name with _id suffix

article_id

ArticleId, id_article, articles_id

Method

camelCase

getAll

get_all

cta-banner-laravel-red-border.jpg

The future of Laravel

Laravel, being the most popular PHP framework and already on its 9th version, is likely to continue to advance and grow for the foreseeable future. Laravel maximizes the use of easy and practical features like the eloquent ORM, model-view-controller pattern, authentication, tight security, etc., so it's no surprise that over 50% of developers that work with PHP use the framework consistently. 

A laravel themed astronaut riding a rocket to space.

Laravel is always on point when it comes to providing superior coding experience to numerous clients while decreasing product development time. The recognition that Laravel has and continues to gain today is largely due to its secure programming advantage and the benefits that come with using it for web development, such as its ability to keep technical vulnerabilities at bay.

Conclusion

Laravel 9 being the recent stable release of the Laravel framework has a host of new features, obvious ones such as PHP being minimally required and smaller ones such as the tweaks seen in areas like security area, design, and ORM. Add these new features to the tried and true staple features of Laravel then mix them together with the best practices discussed in this post and your next Laravel project is surely set to be a standout. And if you're looking for a headless Laravel CMS to take your project to the next level be sure to check out none other than ButterCMS.

Get our latest tutorials and product updates delivered straight to your inbox.
    
Goodness Woke

Goodness is both a professional and enthusiastic writer and software developer.

ButterCMS is the #1 rated Headless CMS

G2 crowd review award G2 crowd review award G2 crowd review award G2 crowd review award G2 crowd review award G2 crowd review award G2 crowd review award G2 crowd review award G2 crowd review award G2 crowd review award G2 crowd review award G2 crowd review award

Don’t miss a single post

Get our latest articles, stay updated!