The next major version of Laravel, 10.0, is now available. Follow the upgrade guide or start a new project on Laravel 10 to jump right in.
For existing projects, it's estimated to take 10 minutes to upgrade. Though mileage may vary.
When is the Release Date?
Laravel 10 was released on 14th February, 2023. It is to receive bug fixes until August 6th 2024, and security fixes until February 4th, 2025.
It'll officially support PHP 8.1 and PHP 8.2. Laravel 9 supports PHP 8.0 to PHP 8.2, so it's not a bad idea to upgrade to PHP 8.1 or 8.2 early if you are on 8.0 currently.
Deprecations Removed
- Removed Redirect::home
- Removed deprecation handler
- Removed deprecated dates
- Removed dispatchNow
- Removed assertTimesSent
- Removed getBaseQuery, MaintenanceModeException, MocksApplicationServices
Dependency Updates
New Features
Laravel Pennant
Laravel Pennant is a new first-party package to help you manage features that are conditionally enabled based on your own parameters. The state of flags will be stored against the active user and can be used for gradually rolling out new features and A/B testing amongst others.
To get started, install Laravel Pennant via Composer and follow the install guide:
$ composer require laravel/pennant
An example of Laravel Pennant in action - defining a new-api feature which is enabled for all internal team members, excluding high traffic customers, and then the rest have a 1/100 chance of being rolled in.
<?php
namespace App\Providers;
use App\Models\User;
use Illuminate\Support\Lottery;
use Illuminate\Support\ServiceProvider;
use Laravel\Pennant\Feature;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Feature::define('new-api', fn (User $user) => match (true) {
$user->isInternalTeamMember() => true,
$user->isHighTrafficCustomer() => false,
default => Lottery::odds(1 / 100),
});
}
}
Then you can check if the feature is enabled and conditionally fire off the respective logic.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Laravel\Pennant\Feature;
class PodcastController
{
/**
* Display a listing of the resource.
*/
public function index(Request $request): Response
{
return Feature::active('new-api')
? $this->resolveNewApiResponse($request)
: $this->resolveLegacyApiResponse($request);
}
// ...
}
Processes Facade
New for Laravel 10 is the Processes Facade. Handy if your application interacts with a shell underneath.
An example provided by the Laravel documentation:
use Illuminate\Support\Facades\Process;
$result = Process::run('ls -la');
return $result->output();
This will output the results of running ls -la
. For those that don't know, it will list all files (including hidden ones) within the current working directory alongside permissions and ownership.
Check out the documentation to see a more in-depth guide of what the Processes Facade is capable of.
Horizon/Telescope UI Facelift
Horizon and Telescope have received updates to their user interface. Bringing both up to modern trends.
Laravel Horizon (Before):
Laravel Horizon (After):
Test Profiling
It is now possible to profile tests using the new --profile option when running tests.
$ php artisan test --profile
The top 10 slowest tests are listed, with the slowest at the top.
Faster View Hashing
PHP8.1 comes with native support for xxh128 hashing and other variants. The algorithm is not designed for security but for randomness and speed.
It is in fact the fastest hashing algorithm supported by PHP to date.
Laravel 10 has migrated away from sha1 to xxh128 for hashing blade view paths.
Custom Validation Rules will now use __invoke by default
Invokable validation classes were added in Laravel 9, removing a bunch of boilerplate from the validation class.
All you had to do was add the --invokable
flag when calling php artisan make:rule InvokableQuantity --invokable
. In Laravel 10 this is now the default behaviour and --invokable
is no longer required.
Native Type Declarations Instead of DocBlocks
Early PHP depended on DocBlocks to annotate return and method argument types. As PHP has evolved and made this part of the language itself, the need for DocBlocks has become less necessary.
Starting from Laravel 10, DocBlocks will be removed in favour of native type declarations. To give an example of what this would look like.
/**
* @param int $id
* @return User
*/
public function getUser($id)
{
return User::find($id);
}
Becomes:
public function getUser(int $id): User
{
return User::find($id);
}
Much better, right?
Filesystem $path Is Now Optional
Laravel 9.x introduced scoped filesystem drivers enabling filesystems to reuse an existing driver. In Laravel 10, several of the Filesystem methods that required a path variable are now optional.
This means you can use scoped filesystem drivers to define common paths and leave out the $path when using putFile
, putFileAs
, store
and others.
Optimised Eager Loading
More a bug than a feature. Gary Green raised an issue where queries were being run for impossible eager loaded relations.
Given his example:
class User {
public function picture()
{
return $this->belongsTo(Picture::class);
}
}
User::create(['picture_id' => null]),
User::create(['picture_id' => null])
$users = User::all()->load(['picture']);
This would try and load the pictures relationship even though the relation's id is null.
select * from `pictures` where 0 = 1
This is now fixed in Laravel 10, where a null relation will no longer be queried.
Collection->random Can Now Preserve Keys
NathanaelGT added a preserve keys option to the collection's random method.
// Before
Arr::random($collection->all(), 2, true);
// After
$collection->random(2, true);