Noting Found

View all related articles

Laravel 9 released, See What's new

Laravel 3 mins read

Table of Content


    Laravel 9 is finally here! It comes with a ton of handy new features, from routes to database, and this is what we are going to discover in this article.

    Laravel new design


    • Knowledge of PHP
    • Basic Knowledge of Laravel
    • PHP v8.0 at minimum

    Releases Schedule

    For LTS releases, such as Laravel 9, bug fixes are provided for 2 years and security fixes are provided for 3 years. These releases provide the longest window of support and maintenance. For general releases, bug fixes are provided for 18 months and security fixes are provided for 2 years. For all additional libraries, including Lumen, only the latest release receives bug fixes. In addition, please review the database versions supported by Laravel.

    Version PHP (*) Release Bug Fixes Until Security Fixes Until
    6 (LTS) (**) 7.2 - 8.0 September 3rd, 2019 January 25th, 2022 September 6th, 2022
    7(-) 7.2 - 8.0 March 3rd, 2020 October 6th, 2020 March 3rd, 2021
    8 7.3 - 8.1 September 8th, 2020 July 26th, 2022 January 24th, 2023
    9 (LTS) 8.0 - 8.1 February 8th, 2022 February 8th, 2024 February 8th, 2025
    10 8.0 - 8.1 February 7th, 2023 August 7th, 2024 February 7th, 2025

    (-) End of life (*) Supported PHP versions (**) Security fixes only

    Laravel 9 new features

    New route:list look

    when you type php artisan route:list you will see a brand-new design look, besides you can see which middleware applied to each route!


    Route Groups

    You may now use the controller method to define the common controller for all the routes within the group. Then, when defining the routes, you only need to provide the controller method that they invoke:

    1use App\Http\Controllers\OrderController;
    3Route::controller(OrderController::class)->group(function () {
    4 Route::get('/orders/{id}', 'show');
    5 Route::post('/orders', 'store');

    Forced Scoped Bindings

    you may now instruct Laravel to scope "child" bindings even when a custom key is not provided. To do so, you may invoke the scopeBindings method when defining your route:

    1use App\Models\Post;
    2use App\Models\User;
    4Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) {
    5 return $post;

    Or, you may instruct an entire group of route definitions to use scoped bindings:

    1Route::scopeBindings()->group(function () {
    2 Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) {
    3 return $post;
    4 });

    If you want to know more, you may take a look here

    Blade Template Inline Rendering

    Sometimes you may need to transform a raw Blade template string into valid HTML. You may accomplish this using the render method provided by the Blade facade. The render method accepts the Blade template string and an optional array of data to provide to the template:

    1use Illuminate\Support\Facades\Blade;
    3return Blade::render('Hello, {{ $name }}', ['name' => 'Oussama Sid']);

    Similarly, the renderComponent method may be used to render a given class component by passing the component instance to the method:

    1use App\View\Components\HelloComponent;
    3return Blade::renderComponent(new HelloComponent('Oussama Sid'));

    Optional Bootstrap 5 Pagination Views

    Laravel now includes pagination views built using Bootstrap 5. To use these views instead of the default Tailwind views, you may call the paginator's useBootstrapFive method within the boot method of your App\Providers\AppServiceProvider class:

    1use Illuminate\Pagination\Paginator;
    4 * Bootstrap any application services.
    5 *
    6 * @return void
    7 */
    8public function boot()
    10 Paginator::useBootstrapFive();

    Brand new Ignition Page

    Ignition, the open source exception debug page created by Spatie, has been redesigned from the ground up. The new, improved Ignition ships with Laravel 9.x and includes light / dark themes, customizable "open in editor" functionality, and more.

    Brand new Ignition Page

    str() helper function

    The str function returns a new Illuminate\Support\Stringable instance for the given string. This function is equivalent to the Str::of method:

    1$string = str('Oussama')->append(' Sid');
    3// Oussama Sid

    If no argument is provided to the str function, the function returns an instance of Illuminate\Support\Str:

    2$string = str()->append('Oussama Sid')->uppercase();

    to_route() helper function

    The to_route function generates a redirect HTTP response for a given named route, providing an expressive way to redirect to named routes from your routes and controllers:

    1return to_route('users.show', ['user' => 1]);
    3// equivalent to
    5return redirect()->route('user.show', ['user' => 1]);

    Enum Attribute Casting

    Enum casting is only available for PHP 8.1+

    Eloquent now allows you to cast your attribute values to PHP enums. To accomplish this, you may specify the attribute and enum you wish to cast in your model's $casts property array:

    • Create PostStatus class inside app/Enums directory
    1namespace App\Enums\PostStatus;
    3enum PostStatus
    5 case Published;
    6 case Pending;
    7 case Archived;
    8 case Draft;

    Inside your model:

    1use App\Enums\PostStatus;
    4 * The attributes that should be cast.
    5 *
    6 * @var array
    7 */
    8protected $casts = [
    9 'status' => PostStatus::class,

    Once you have defined the cast on your model, the specified attribute will be automatically cast to and from an enum when you interact with the attribute:

    1if ($post->status == PostStatus::Pending) {
    3 $post->status = PostStatus::Published;
    5 $post->save();

    Brand-new Accessors & Mutators (Simplified)

    Laravel 9.x offers a new way to define Eloquent accessors and mutators. In previous releases of Laravel, the only way to define accessors and mutators was by defining prefixed methods on your model like so:

    1public function getNameAttribute($value)
    3 return strtoupper($value);
    6public function setNameAttribute($value)
    8 $this->attributes['name'] = $value;

    However, in Laravel 9.x you may define an accessor and mutator using a single, non-prefixed method by type-hinting a return type of Illuminate\Database\Eloquent\Casts\Attribute:

    1use Illuminate\Database\Eloquent\Casts\Attribute;
    3public function name(): Attribute
    5 return new Attribute(
    6 get: fn ($value) => strtoupper($value),
    7 set: fn ($value) => $value,
    8 );

    Laravel 9 Release Notes

    Laravel 9 comes with release notes, and the full list of features, you can see them on Laravel 9 release notes

    Upgrade To Laravel 9

    You have 2 possible ways to upgrade your application to Laravel 9


    The features above are just a few ones on this new release, if you want to know more, you may refer to Laravel 9 release notes

    If you are a visual learner, you may check Laravel 9 - Everything You Need to Know (In 45 Minutes) by Jeffery way on laracasts, or 12 Minutes, What's New in Laravel 9 by Mohamed Said.

    This all what I want to say today, Have a happy Upgrade 🥳

    Related Tags

    About the Author

    Oussama's Profile Picture
    Full Stack Web Developer | Technical Writer

    Oussama is an experienced full-stack web developer with a strong focus on Laravel. He's passionate about crafting web applications with Filament and the TALL Stack. With 8+ years of experience, and he's a dedicated open-source contributor.


    Join our newsletter

    Subscribe to Our Newsletter and never miss our offers, latest news, Articles, etc.

    We care about the protection of your data. Read our Privacy Policy.