DEV Community

Cover image for Laravel 9, what's new?!
saeedeldeeb
saeedeldeeb

Posted on

Laravel 9, what's new?!

Laravel and its other first-party packages follow Semantic Versioning. Major framework releases are released every year (~February), while minor and patch releases may be released as often as every week. Minor and patch releases should never contain breaking changes.

When referencing the Laravel framework or its components from your application or package, you should always use a version constraint such as ^9.0, since major releases of Laravel do include breaking changes. However, we strive to always ensure you may update to a new major release in one day or less.


From 8.x to 9.x important changes:

  • php is beginning transition to require function return type.
  • Belongs to many methods (firstOr..., UpdateOr...) now comparing against the related model not pivot.
  • They moved from swiftMailer to symfonyMailer.
  • lang directory have located to project root directory.
  • Use current_password validation rule instead of password

New features in 9.x:

  • Route controller group.
  • Anonymous migration class.
  • New helper functions.
  • Refreshed ignition error page.
  • Render blade string.
  • Forced scope bindings.
  • Laravel scout DB engine.
  • Full text indexing.
  • Enum attribute casting.
  • Simplified accessors and mutators.

we will discuss every point below:

Route controller group

If a group of routes all utilize the same controller, you may use the controller method to define the common controller for all of the routes within the group. Then, when defining the routes, you only need to provide the controller method that they invoke:

use App\Http\Controllers\OrderController;

Route::controller(OrderController::class)->group(function  () {
Route::get('/orders/{id}', 'show');
Route::post('/orders', 'store');
    });
Enter fullscreen mode Exit fullscreen mode

They don't stop here but also made new console format when listing
project routes php artisan route:list

enter image description here


Anonymous migration class

Migration file now not class with name but anonymous one.

<?php
...
return  new  class  extends  Migration
{
    /**
    * Run the migrations.
    *
    * @return  void
    */
    public  function  up()
    {
    ...
    });
}

    /**
    * Reverse the migrations.
    *
    * @return  void
    */
    public  function  down()
    {
    ...
    }
};
Enter fullscreen mode Exit fullscreen mode

New helper functions

  • str('__') /** equals to */ Str::of('__'); and it's good specially in blade as we don't need to use name space qualifier of Str class.
  • to_route('__'); /** equals to */ redirect()->route('__');

Refreshed ignition error page

enter image description here


Render blade string

Sometimes you may need to transform a raw Blade template string into valid HTML.

use Illuminate\Support\Facades\Blade;

return  Blade::render('Hello, @if(true) {$name} @endif', ['name'  =>  'Julian Bashir']);
Enter fullscreen mode Exit fullscreen mode

Forced scope bindings

To bind models only belong to another model.

Route::get('/users/{user}/posts/{post:id}', function(User $user, Post $post){
...
})
Enter fullscreen mode Exit fullscreen mode

we use post:id to see if user has this post , if not returns 404 but this can be dis-informative so explicitly:

Route::get('/users/{user}/posts/{post}', function(User $user, Post $post){
    ...
    })->scopeBindings();
Enter fullscreen mode Exit fullscreen mode

Laravel scout DB engine

Scout package performs full text search, It used to using services but now for small projects we can use our DB engine.


Full text indexing

  • In migration class: $table->text('body')->fullText();
  • When searching: Post::whereFullText('body', '__')->get();

Enum attribute casting

Eloquent also allows you to cast your attribute values to PHP "backed" enums.

use App\Enums\ServerStatus;

/**
* The attributes that should be cast.
*
* @var  array
*/
protected  $casts  = [
'status'  =>  ServerStatus::class,
];
Enter fullscreen mode Exit fullscreen mode

also Laravel allows you to type-hint an Enum on your route definition and Laravel will only invoke the route if that route segment corresponds to a valid Enum value. Otherwise, a 404 HTTP response will be returned automatically.

<?php

namespace App\Enums;

enum  Category:  string 
{
    case  Fruits  =  'fruits';    
    case  People  =  'people';    
}
Enter fullscreen mode Exit fullscreen mode

use App\Enums\Category;
use Illuminate\Support\Facades\Route;

Route::get('/categories/{category}', function  (Category  $category) {
    return  $category->value;    
});
Enter fullscreen mode Exit fullscreen mode

Simplified accessors and mutators

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;

class  User  extends  Model    
{    
    /**    
    * Interact with the user's first name.    
    *    
    * @param  string $value    
    * @return  \Illuminate\Database\Eloquent\Casts\Attribute    
    */    
    protected  function  firstName():  Attribute
    {    
        return  new  Attribute(    
        get: fn  ($value) => ucfirst($value),    
        set: fn  ($value) => strtolower($value),    
         );    
    }    
}
Enter fullscreen mode Exit fullscreen mode

Latest comments (0)