06 06

retour à la liste des articles

Les nouveautés de Laravel 9

• écrit par [Wilfried]
Lead développeur

Logo Laravel 9

Quelles sont les nouveautés de Laravel 9 ?

Comme pour chaque nouvelle version majeure de Laravel, la version 9 arrive avec son lot de nouvelles fonctionnalités et de changements plus ou moins impactants.

Nous avons sélectionné les nouveautés qui nous paraissent les plus intéressantes.

Le support des énumérations

L'une des principales nouveautés de PHP 8.1 est l'ajout des énumérations.

À condition d'être en PHP 8.1, Laravel apporte plusieurs nouvelles fonctionnalités basées sur les énumérations.

Les propriétés castées en Enum

De la même manière que les propriétés des models peuvent être castées en booléen, date, datetime, ... Il est désormais possible de les caster en Enum.

use App\Enums\ServerStatus;

protected $casts = [
    'status' => ServerStatus::class,
];

De cette façon, il est possible d'utiliser ou de modifier la propriété castée directement comme étant une Enum.

if ($server->status === ServerStatus::PROVISIONED) {
    $server->status = ServerStatus::READY;

    $server->save();
}

 

Les Enum et le route binding

Laravel permet de lier implicitement des models à des paramètres de routes. Le framework arrive à récupérer l'instance du model lié s'il existe, ou renvoie automatiquement une erreur 404 dans le cas contraire.

Cette fonctionnalité a été étendue pour permettre de faire la même chose avec des Enum.

Si on considère qu'on a défini la structure suivante : 

enum ServerStatus: string
{
    case PROVISIONED = 'provisioned';
    case READY = 'ready';
}

On peut définir des routes qui ont des paramètres de type ServerStatus, et qui se comporteront de la sorte :

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

Route::get('status/{status}', function (ServerStatus $status) {
    die($status->value);
});

# GET laravel.test/status/provisioned => HTTP 200, affiche "provisioned"
# GET laravel.test/status/ready       => HTTP 200, affiche "ready"
# GET laravel.test/status/other       => HTTP 404

🔗 Lien vers la documentation PHP sur les énumérations :

  • https://www.php.net/manual/en/language.types.enumerations.php

🔗 Liens vers la documentation Laravel :

  • https://laravel.com/docs/9.x/releases#enum-casting
  • https://laravel.com/docs/9.x/routing#implicit-enum-binding

 

La commande artisan route:list

Avec l'arrivée de la version 9 de Laravel, la commande artisan route:list a été remise à neuf, avec un affichage plus compact. 

route-list-9

La commande n'affiche plus la liste des middlewares par défaut, il faut ajouter l'option -v pour avoir également la liste des middlewares appliqués à chaque route.

route liste 9 (2)

💡 Pour connaitre toute les (nouvelles) options, utiliser la commande php artisan route:list -h (ou php artisan r:l -h si on préfère les raccourcis).

 

Les Accessors / Mutators

Les accessors et les mutators ont été simplifiés, ils peuvent se définir en même temps pour une même propriété avec une seule méthode :

use Illuminate\Database\Eloquent\Casts\Attribute;

public function serializedData(): Attribute
{
    return Attribute::make(
        get: fn ($value) => unserialize($value)),
        set: fn ($value) => serialize($value),
    );
}

Dans cet exemple, on a généré sur notre model une propriété serialized_data qui utilise à la fois un accessor et un mutator personnalisés.

Dans le cas où certaines actions à effectuer dans l'accessor seraient trop longues, on peut également appeler la méthode shouldCache() sur l'attribut créé, pour n'avoir à exécuter l'accessor qu'une seule fois le temps de la requête :

use Illuminate\Database\Eloquent\Casts\Attribute;

public function someAttribute(): Attribute
{
    return Attribute::make(
        get: function ($value) {
            sleep(10); // On attend ici, pour une raison quelconque
            return $value;
        }
    )->shouldCache();
}

// ...

// On exécute le sleep, et on attend 10s
$value = $model->some_attribute;

// Instantané, l'attribut a été mis en cache temporairement !
$otherValue = $model->some_attribute;

🔗 Lien vers la documentation Laravel : https://laravel.com/docs/9.x/eloquent-mutators#accessors-and-mutators

 

Les Controller Route Groups

Les Controller Route Groups permettent de définir un ensemble de routes qui invoquent toutes le même controller, en définissant pour chacune d'entre elles seulement le nom de la méthode qui sera appelée.

use App\Http\Controllers\OrderController;

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

🔗  Lien vers la documentation Laravel : https://laravel.com/docs/9.x/releases#controller-route-groups

 

Le driver "database" pour Laravel Scout

Laravel Scout est une "extension" de Laravel permettant d'effectuer simplement et rapidement des recherches sur les models.

À l'origine, il était utilisable avec des providers externes comme Algolia ou Meilisearch.

Depuis Laravel 9, un nouveau driver a été ajouté permettant d'utiliser Laravel Scout directement avec la base de données du projet (MySQL / PostgreSQL).

Pour l'utiliser, il suffit de renseigner le SCOUT_DRIVER=database dans le fichier .env , et de configurer les models à rendre "Searchable" comme pour les autres drivers.

🔗  Lien vers la documentation Laravel : https://laravel.com/docs/9.x/scout#database-engine

 

L'ajout de typage

Avec Laravel 9, les méthodes du coeur du framework se sont vu dotées de plus de typage, autant pour les paramètres que pour les retours des méthodes.

Ces ajouts sont gages de qualité mais peuvent nécessiter pas mal d'ajustements. C'est le cas notamment lorsqu'on utilise des outils d'analyse statique comme PHPStan (via le package Larastan) car on découvre que beaucoup des typages ajoutés sont mixed.

Comme par exemple la méthode validated() des FormRequest qui jusqu'ici retournait un tableau et retourne maintenant mixed, ce qui nous oblige à spécifier le typage avec de la PHPDoc si notre code nous impose d'avoir un tableau.

/** @var array $validated */
$validated = $request->validated();

Toujours dans les typages, la définition des types 'generics' a été ajouté au Collection. Cela permet à l'IDE (ex: PHPStorm) et aux outils d'analyse statique (ex: PHPStan) de mieux comprendre le contenu des Collection.

💡 La généricité avec PHP et PHPStan : https://phpstan.org/blog/generics-in-php-using-phpdocs