Laravel 9.0 Released: Let’s Explore What’s New in Laravel v9.0!

Laravel 9 Released

Laravel 9.0 is Out Now!

And as usual, it is launched with the new features including support to minimum PHP v8.0 version, controller route groups, a refreshed default Ignition error page, Laravel Scout database engine, Symfony mailer integration, Flysystem 3.x, Improved Eloquent accessors/mutators, and many more! And here KrishaWeb is ready to take you on a tour through this blog… Stay Connected!

Before we jump into the detailed new features, we are going to point out that with the launch of Laravel 9, Laravel will release its new versions about every 12 months instead of 6 months schedule.

Laravel 9 is an LTS version that was released on February 8, 2022. Laravel 9 supports PHP versions 8.0 and 8.1 and offers two years of bug fixes (will receive bug fixes until February 2024) and three years of safety (will receive security fixes until February 2025).

New Features in  Laravel 9.0

  1. Eloquent accessors/mutators improvement
  2. Enum attribute casting
  3. Implicit Route Bindings With Enums
  4. Forced Scoping Of Route Bindings
  5. Controller Route Groups
  6. Full-Text Indexes/Where Clauses
  7. Rendering Inline Blade Templates
  8. Checked/Selected Blade Directives
  9. Bootstrap 5 Pagination Views
  10. Improved Validation Of Nested Array Data
  11. Improved Ignition Exception Page
  12. Improved route: list CLI Output
  13. Test Coverage Using Artisan Command
  14. New Helpers
  15. Anonymous Migration Classes

1) Eloquent accessors/mutators improvement

Eloquent accessors/mutators is a feature by Taylor Otwell that allows developers to handle database queries using PHP syntax instead of writing SQL code, which could be time-consuming.

In Laravel 8, you must use the get and set prefixes in the model to define accessors and mutators. However, in Laravel V9, you can declare the prefix with a single non-prefixed term by using the IlluminateDatabaseEloquentCastsAttribute. You may now acquire and set attributes with only one method call.


use Illuminate\Database\Eloquent\Casts\Attribute;
	public function username (): Attribute
		return new Attribute(
		get: fn ($value) => strtoupper($value),
		set: fn ($value) => $value,

In this example, the accessor will cache the value of the username and return it. Here attribute function has two arguments. The first is for get and the second is for set the attribute. Overall, version 9 will make this process easier and quicker.

2) Enum attribute casting

Mohamed Said contributed Enum casting. It is only available in PHP 8.1+ version. Now you can define a enums in enum file and even enum types you wish. You can easily find all this in enum file located in App/Enums/. Also, you need to define a return type in the file, and in order to accomplish this you have to specify attribute and enum in $casts property array in the model.

Once you define your casts on the model, it will cast the specified attribute automatically from an enum file. For more information, you can visit Enum Casting.

3) Implicit Route Bindings With Enums

Enums are now supported in PHP 8.1. Laravel 9.x provides the capability to type-hint an Enum on a route declaration, and Laravel will only apply the route if the route component is a valid Enum value in the URI. Else, it will promptly return to an HTTP 404 error.


In App/Enums/Category:

enum Category: string
	case Fruits = 'fruits';
	case People = 'people';

In Route File :-
Route:: get ('/categories/{category}', function (Category $category) {
return $category->value;

You can now create a route that is only used if the category route segment contains fruits or humans. Otherwise, you’ll get an HTTP 404 response.

4) Forced Scoping Of Route Bindings

Forced scoped bindings were contributed by Claudio Dekker. In the previous version of Laravel for scoping, we need to use the key of the parent eloquent model, but it does not seem like had used scoping. But in Laravel 9 there is a function called the scope bindings method for defining your route.

Laravel will automatically range the query to fetch the nested models by its parent when using norms to assume the relationship’s name on the parent.

Scope bindings method will give instruction to the child model even when a key is not provided. Check out the following formula to do so –


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

You can also bind a scope for the entire group of routes using the group function.

Check the below code for the same:


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

5) Controller Route Groups

Controller route groups are the most powerful feature of Laravel 9 and it is contributed by Luke Downing. For controller routes, you need to use the controller function and then you just have to define the routes and their function for that controller.

That controller will invoke that method automatically. Form controller route grouping, we can avoid duplication use of the controller.


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

6) Full-Text Indexes / Where Clauses

Taylor Otwell and Dries Vints contributed full-text indexes and “where” clauses. The full-text method can now be introduced to column definitions in MySQL and PostgreSQL to produce full-text indexes. For the query, they utilize the WhereFullText and or WhereFullText methods.

Laravel will convert these methods into the necessary SQL for the supporting database system. For MySQL-based applications, a MATCH AGAINST clause will be produced.


$users = DB::table('users')->whereFullText('bio', 'web developer')->get();

7) Rendering Inline Blade Templates

Rendering inline Blade templates was contributed by Jason Beggs. Sometimes you need to transfer some data to HTML, then blade templates are used to convert a string into valid HTML.

You may use the render method provided by blade facades. The render method will accept two arguments: one is blade string and the second one is an array of data, but the second is optional.


use Illuminate\Support\Facades\Blade;
return Blade::render('Hello, {{ $name }}', ['name' => 'Julian Bashir']);

8) Checked / Selected Blade Directives

Ash Allen and Taylor Otwell contributed, checked, and selected Blade directives. In the older version, we need to write a specific condition for the selection of the checkbox and dropdown.

However, Laravel version 9 solves this problem by introducing @checked and @selected blade components for selection and it will only select data if a particular condition is true which we write in those components.

@checked:- it will echo checked if the provided condition is true.


< input type="checkbox" name="active" value="active" @checked(old('active', $user-> active)) / >

@selected:- it will select a particular option if the provided condition is true.


< select name="version" >
	@foreach ($product->versions as $version)
		< option value="{{ $version }}" @selected(old('version') == $version) >
			{{ $version }}
		< /option >
< /select >

9) Bootstrap 5 Pagination Views

If you’ve ever suffered from pagination in your projects, you’ll appreciate how useful it is to have a built-in framework to take care of it. Laravel eliminates the need for manual pagination by providing automatic pagination.

On the other hand, Laravel 9.0 further eases this task. Jared Lewis contributed Bootstrap 5 pagination views. In laravel 9 pagination view will be built using Bootstrap 5. You may call useBootstrapFive method in boot method of your App\Providers\AppServiceProvider class.

10) Improved Validation Of Nested Array Data

Steve Bauman contributed to improved validation of nested array inputs. Sometimes you need to validate an array element and you may need to access the value from the array element when you assign the rule to the attribute.

For this task also, Laravel 9 has a solution as it introduces Rule:foreach method. This method accepts a closure that will be invoked for each iteration of the array attribute under validation and will receive the attribute’s value and explicit, fully expanded attribute name.


use App\Rules\HasPermission;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;

$validator = Validator::make($request->all(), [
	'companies.*.id' => Rule::forEach(function ($value, $attribute) {
		return [
			Rule::exists(Company::class, 'id'),
			new HasPermission('manage-company', $value),

11) Improved Ignition Exception Page

Ignition, Spatie’s open-source exceptions debugging page, has been revamped from the bottom up with some new features to provide users with a multitude of advantages. Light/dark themes, customizable “open in editor” capability and much more are among the new and improved features in Laravel release 9.

12) Improved route:list CLI Output

Another important feature of Laravel is the command-line interface (CLI). It allows you to create or alter any aspect of Laravel without needing to browse through folders and files from the command line. It can also assist you in interacting with your databases from the command line.

With version 9 it even got better, as the new version introduces a new design of route list in the command line interface.

13) Test Coverage Using Artisan Command

In Laravel 9, there is a new–coverage option. A new artisan test coverage option will display the test coverage on the terminal immediately. It will display the proportion of code that has been tested.

php artisan test –coverage

It also has a minimum option that you may use to specify the minimum coverage level to enforce.

php artisan test --coverage –min=80.3

14) New Helpers

Laravel 9 introduces some new helper functions that will help you for easiness.

  • Str

For the provided string, the str method returns a new IlluminateSupportStringable object. This method is the same as the Str::of method:

If the str function is used without an argument, it returns an instance of IlluminateSupportStr:


-> str function returns a new string instance for a given string.

$string = str('Taylor')->append(' Otwell'); // output :- 'Taylor Otwell'
		$snake = str()->snake('LaravelFramework'); // output :- laravel_framework
  • to_route

The to route approach produces an HTTP reroute reaction for a given named route, allowing you to redirect to named paths from your routes and controllers in a more exceptional manner:

As the 3rd and 4th arguments to the route function, you can specify the HTTP status code that should be allocated to the redirect as well as any additional response headers if needed:


-> to_route function generates HTTP URL and redirect for a given named route. It works like the route function which we use in Laravel 9.

return to_route('', ['user' => 1]);

-> you can pass HTTP status code and any additional headers in to_route function.

return to_route('', ['user' => 1], 302, ['X-Framework' => 'Laravel']);

15) Anonymous Stub Migration

When you perform the latest migration function, Laravel sets anonymous stub migration as the default behavior:

To address this GitHub problem, Laravel 8.37 introduced the anonymous migration feature. When attempting to rebuild the database from start, numerous migrations with a similar class name can pose problems. Migration class name collisions are no longer an issue thanks to the latest stub migration feature.

The platform now allows anonymous class migration files as of Laravel 8.37, and it’ll be the default behavior in Laravel 9.


use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; 
return new class extends Migration { 
	public function up() { 
		Schema::table('users', function (Blueprint $table) { 

How to Install the Latest Laravel 9.0?

You can quickly install and run Laravel 9 on your local device for development and testing reasons. Only the PHP v8 engine is supported by Laravel. As a result, before installing and testing, double-check your PHP version. Remove the previous version and start a new installation to make things easier.

Execute the Following Commands to Deploy Laravel 9 Utilizing Composer

composer create-project --prefer-dist laravel/laravel laravel-9-dev dev-develop

You may utilize the code above to develop a fresh Laravel project with the name laravel-9-dev and the newest Laravel 9.

To build a new Laravel project, another option would be to use the Laravel Global CLI. Then, using the developer branch as a starting point, build a new project.

After you’ve finished installing Laravel 9, go to the new directory (laravel-dev) and evaluate the current version with the artisan command.

cd laravel-9-dev
php artisan --version

And, Ta-Da! It’s done. Now you can enjoy the updated version of Laravel.

Wrapping up!

So, here is the complete roundup of information about the updated features in Laravel version 9. These updated versions will make the work easier and faster for developers & companies.

For further queries, you can reach out to us and we’ll help you out. Hope you find this blog helpful.

Hire the right Laravel Development Company with confidence!

Recent Articles

Browse some of our latest articles...