Laravel 11 – Overview of changes Part 1

Since Laravel 9, the release cycle of new Laravel versions has been standardized to one major update at the beginning of each year. This year is no different. In March, Laravel 11 was released. Laravel 11 requires PHP version 8.2 to operate.

Projects initiated with Laravel 11 will undergo significant slimming down. For instance, support for API endpoints and WebSockets has also been omitted. However, there’s no need to worry. These functionalities can be restored using new artisan commands.

Database related changes

Until now, initializing a project assumed that MySQL was the default database system. After the update, it changed, and SQLite became the default database. The SQLite database file is created in the /database folder. However, if SQLite doesn’t meet our expectations, nothing is lost. During project initialization, we can still choose one of the supported database systems: SQLite, MySQL, MariaDB, pgSQL, SQL Server.

Another database-related change is the update of default migrations in the project. They have been rewritten, and their names have changed. They no longer consist of timestamps but are counted from zero. This is to ensure that these migrations always run first. New migrations will still be created with the old naming convention, consisting of a timestamp and the given name. Default migrations will now create several tables within one migration that are logically related to each other. For example, the users migration creates the users, password_reset_tokens, and sessions tables. The cache migration creates cache and cache_locks tables. The jobs migration creates jobs, job_batches, and failed_jobs tables.

Eager loading limit

From now on, when we perform eager loading on a relationship in the model, we can use the limit function. In such a case, the limit function will restrict how many records are loaded.

Shop::with([
   'products' => fn ($query) => $query->limit(3)
])->get();

Model cast changes

Until now, attribute casting in models was done by adding an attribute $casts to the model. From now on, we can achieve this by adding a new method casts() to the model. This allows us to more easily define types that require the use of a static method on a built-in type. This attribute and method do not conflict with each other, and we can use both within the same model.

//Pre Laravel 11

/**
* The attributes that should be cast.
*
* @var array
*/
protected $casts = [
   'email_verified_at' => 'datetime',
   'password' => 'hashed',
];
//Introduced in Laravel 11

/**
* Get the attributes that should be cast.
*
* @return array<string, string>
*/
protected function casts(): array
{
   return [
       'email_verified_at' => 'datetime',
       'password' => 'hashed',
   ];
}