Laravel - PHP

Laravel 10: release date and upcoming features

Taylor Otwell, tweeted Laravel 10 will be released at 14. February 2023 🥳

You already can checkout Laravel 10 from the master branch. Install Laravel 10 is super easy. Just use the --dev flag.

laravel new myapp --dev

of course you can install Laravel 10 with composer:

composer create-project --prefer-dist laravel/laravel hello-world dev-master

One big announcement is Laravel Penant. Manage Feature flags with ease in your Laravel 10 project. A first-party package official maintained by Laravel. I'm so excited!

Feature flags are a powerful tool that allow developers to incrementally roll out new features and A/B test interface designs with confidence. However, many feature flag packages come with a lot of unnecessary complexity. That's where Laravel Pennant comes in - it's a simple and lightweight package that provides all the functionality you need without any of the cruft. With Laravel Pennant, you can easily implement feature flags in your applications and take advantage of their benefits, whether you're using a trunk-based development strategy or exploring new possibilities for your user interface. Give it a try and see how it can simplify your development process!

Grab the package via composer:

composer require laravel/pennant

Rollout a feature for a set of users:

use Laravel\Pennant\Feature;
use Illuminate\Support\Lottery;
 
Feature::define('awesome-feature', function () {
    return Lottery::odds(1, 20);
});

Check if the current user has access to this feature:

if (Feature::active('awesome-feature')) {
    // ...
}

You also can check in your blade views:

@feature('new-onboarding-flow')
    …
@endfeature

Read more about Laravel Pennant in the official documentation.

Laravel 10 now has it's own Process API for the Symfony Process component. Run processes the "laravel way". The component is super easy to use.

Here are some examples:

use Illuminate\Support\Facades\Process;

$result = Process::run('ls -la');

return $result->output();

Set a working directory:

$result = Process::path(__DIR__)->run('ls -la');

Asynchronous processing has become increasingly important in modern web development, and Laravel provides an excellent solution for managing concurrent processes. With Laravel, it's easy to execute many tasks simultaneously using a pool of asynchronous processes:

use Illuminate\Process\Pool;
use Illuminate\Support\Facades\Process;
 
$pool = Process::pool(function (Pool $pool) {
    $pool->path(__DIR__)->command('bash import-1.sh');
    $pool->path(__DIR__)->command('bash import-2.sh');
    $pool->path(__DIR__)->command('bash import-3.sh');
})->start(function (string $type, string $output, int $key) {
    // ...
});
 
while ($pool->running()->isNotEmpty()) {
    // ...
}
 
$results = $pool->wait();

There's so much more what the process component has to offer. Read the official documentation.

Run your tests with the --profile option to identify slow tests:

php artisan test --profile

Example output:

If you're a Laravel developer, you may be familiar with invokable validation rules - a powerful feature that allows you to define custom validation logic in a single class. In Laravel 9, you could generate these rules using the --invokable flag with the php artisan make:rule command. However, with the release of Laravel 10, this flag is no longer necessary. This makes it easier than ever to create custom validation rules that are reusable, maintainable, and easy to understand. Whether you're building a complex web application or just need to add some custom validation logic to your forms, invokable validation rules in Laravel are a powerful tool that every developer should know how to use.

This is how a invokable validation rules looks like:

namespace App\Rules;
 
use Illuminate\Contracts\Validation\InvokableRule;
 
class Uppercase implements InvokableRule
{
    public function __invoke($attribute, $value, $fail)
    {
        if (strtoupper($value) !== $value) {
            $fail('The :attribute must be uppercase.');
        }
    }
}

The entire codebase now uses types instead of docblocks. A big step forward!

/**
 * Define the application's command schedule.
- * 
- * @param  Illuminate\Console\Scheduling\Schedule  $schedule
- * @return void
 */
- protected function schedule($schedule)
+ protected function schedule(Schedule $schedule): void

In an effort to improve the development experience for Laravel users, the team is planning to implement generic type annotations. By using these annotations, developers will see a significant improvement in autocompletion when writing code, assuming their code editor supports generics.

If you're looking to upgrade to Laravel 10, there are a few things to keep in mind when it comes to PHP versions. Firstly, Laravel 10 will no longer support PHP 8.0 and will require a minimum of PHP 8.1. This means that in order to upgrade, you'll need to move to at least PHP 8.1. However, there's another option as well - if you want to future-proof your code and ensure compatibility with the latest PHP features, you could consider moving to PHP 8.2 instead. Either way, it's important to be aware of these changes and plan your upgrade accordingly.

In Laravel 10, the deprecated dispatchNow() method has been removed and should be replaced with dispatchSync(). Remember to update this method in all your projects. Although this is a breaking change, it is a simple fix.

When releasing a major version, Laravel removes features deprecated in previous versions, so it's important to carefully test any application before migrating to version 10. Here are some of the PRs that take care of this process:

You no longer need doctrine/dbal to modify columns in Laravel migrations.

return new class extends Migration
{
    public function up()
    {
        Schema::table('name', function (Blueprint $table) {
            $table->unsignedBigInteger('foo')->change();
        });
    }
}

Previously, in Laravel 9, modifying columns in migrations required the installation of doctrine/dbal. However, in Laravel 10, migrations now support the native operations provided by most of the databases Laravel supports, removing the need for the package in this context.

In situations where you have multiple database connections and have already installed Doctrine DBAL, you can call Schema::useNativeSchemaOperationsIfPossible() to use native operations before falling back on the package if necessary. Note that some databases, such as SQLite, do not currently support this feature.

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Schema::useNativeSchemaOperationsIfPossible();
    }
}