Interested in generating passive income? Join our partnership program and receive a commission on each new client referral. Learn more.
12 min read
Interested in generating passive income? Join our partnership program and receive a commission on each new client referral. Learn more.
Laravel 10 is here, and it's loaded with lots of awesome updates!
Laravel never fails to surprise us with its latest updates, and Laravel 10 is no exception. In this article, we'll take you through everything you need to know about Laravel 10, from its impressive new features and functionalities to the deprecated methods and packages. So join us as we dive into what Laravel has to offer with its newest iteration.
Previously, Laravel released major versions every six months, but with Laravel 9, the team switched to an annual release schedule. Laravel 10 release date was on February 14, 2023, and it brings updates worth examining.
Laravel 10, as well as every new version, offers two official documents:
The two high-impact changes involve updating dependencies and minimum stability, with PHP 8.1+ and Composer 2.2+ now required. Ensure "minimum-stability" is set to "stable." Other changes have medium, low, very low, or optional impacts. Official guide: https://laravel.com/docs/10.x/upgrade
You won’t be able to work with PHP 8.0 or below versions when it comes to Laravel 10. Laravel 10 only supports PHP 8.1 or newer versions so it's also compatible with the recently released PHP 8.2. Additionally, if you are using Laravel 9, PHP 8.2 is also a viable option for your project.
Laravel 10. x thoroughly updated the skeleton of the application and all stubs utilized by the framework to introduce argument and return types to all method signatures. “Doc Block” type-hinted information has been deleted as well.
Here is an example:
Laravel 9:
/**
* Get the path the user should be redirected to when they are not authenticated.
*
* @param \Illuminate\Http\Request $request
* @return string|null
*/
protected function redirectTo($request)
{
if (! $request->expectsJson()) {
return route('login');
}
}
Laravel 10:
/**
* Get the path the user should be redirected to when they are not authenticated.
*/
protected function redirectTo(Request $request): ?string
{
return $request->expectsJson() ? null : route('login');
}
From the examples, we see that parameter types and return types have been added to all methods in the new version, enhancing readability, understanding, and error prevention. It is also a good idea to implement these features while writing your own methods.
The author (nunomaduro) updated parameter declarations, return types, and doc-blocks across all files and repositories in this comprehensive PR, which is considered highly valuable and important.
The new Process facade allows us to invoke or trigger any external process, such as the command line scripts. Like the HTTP facade makes working with APIs easier and more comfortable, the Process facade will make working with testing and running CLI processes a breeze.
The most basic usage of this feature:
use Illuminate\Support\Facades\Process;
$result = Process::run('ls -la');
$result->successful(); // determine if the process was successful
$result->failed(); // determine if the process failed
$result->exitCode(); // get the exitcode of the process
$result->output(); // get the standart output of the process
$result->errorOutput(); // get the error output of the process
$result->throw(); // throw an exception if the process failed
$result->throwIf(condition); // throw an exception if the process failed and the given condition is true
For example, we need to run pwd command and print the current directory.
$result = Process::run('pwd');
return $result->output();
If we check the output, we will see: /pathtoproject/projectname/public
If we run the command that does not exist:
$result = Process::run('ll');
return $result->errorOutput();
we will see: sh: ll: command not found
The Process layer includes a lot of features out of the box, such as:
If we need to run processes that take a long time, such as npm run build, we can monitor them and check if the command is running, waiting for them to complete or print output as they run.
In addition, we also have the fake() method on the Process facade, as on many other facades, it helps us in testing to fake processes. So, if running the command below takes several seconds:
\Illuminate\Support\Facades\Process::run('npm run build')->output();
The code below executes instantly:
\Illuminate\Support\Facades\Process::fake();
$this->info(\Illuminate\Support\Facades\Process::run('npm run build')->output());
To sum up, the new process facade helps us run any command we might need to trigger programmatically from a PHP file.
Laravel Pennant is a first-party package maintained by Laravel core team member Tim McDonald, which simplifies the challenge of managing feature flags in frequently updated projects. It offers a user-friendly solution, including an in-memory array driver and a database.
To get started, simply:
After running migrations, a new "features" table is added to the database. Pennant can use an in-memory array or a database for resolving feature flags, with the default being the database.
What's a feature flag, you might ask.
Laravel Feature flags help test new styles, pages, or functionalities visible only to specific user groups, such as company users or administrators. Essentially, they enable selective functionality during runtime without deploying new code, allowing for controlled experimentation during the feature lifecycle.
To define a feature, use the Feature facade's define method, providing a name and a closure for the initial value. Features should be defined in service providers, like AppServiceProvider.
public function boot(): void
{
Feature::define('new-dashboard-text, function () {
return true;
});
}
Here we define the new feature called “new-dashboard-text”. If we return true from the closure, this means that everyone has access to this feature. If we need to activate this feature only for certain kinds of people, for example, for our employees and administrators, we can define it so:
Feature::define('new-dashboard-text', fn (User $user) => $user->isAdmin() || $user->isEmployee());
In the blade, we can use the @feature directive to define the part of code that we need to be accessible within the feature, for example:
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
@feature('new-dashboard-text')
<!-- 'new-style' is active -->
<div class="p-6 text-gray-500">
{{ __("Welcome to the page!") }}
</div>
@else
<!-- 'new-style' is inactive -->
<div class="p-6 text-gray-900">
{{ __("You're logged in!") }}
</div>
@endfeature
</div>
If we log in with the administrator or employee user, we will see “Welcome to the page!” and all the other users will see “You’re logged in!”. But how does that work? We need to look at the features table first, which looks like this:
Here we see that the user with id 1, which is administrator, has value -> true, which means that this user has access to this feature and the other user with id 2, which is an employee, also has access to this feature. If I log in with a user who is not an administrator or employee, the new record will be added to the table:
What if a user with id 22 became our employee and also needed to have access to this feature? If this record is saved in the DB and its value is false, it won’t be updated when the user logs in. Instead:
1. Do we need to remove an existing record from the table manually or
2. Activate the feature for this user with the code
\Laravel\Pennant\Feature::activate('new-dashboard-text');
After revisiting the dashboard page, the new dashboard text will appear, and the record in the DB will also update. In addition, if we need to check if the current feature is active for the authenticated user, we can write the condition below:
if (Feature::active('new-dashboard-text')) {
return to_route('dashboard');
}
To summarize, we now have a well-built and well-tested package with great functionality.
The artisan test command has a new option –profile which helps us to find slower tests in our application and fix them.
For example, if we have:
test('sleep for 3 seconds', function () {
sleep(3);
});
If we run php artisan test --profile, we can identify which tests took more time to execute, helping us identify the slowest ones.
After the Laravel 10 release, the built-in make commands no longer require any input. When we invoke these commands without input, we will be prompted for the required arguments, such as:
➜ php artisan make:model
What should the model be named?
❯ Post
Would you like any of the following? [none]
none ................................................................................................................................. 0
all ...................................................................................................................................... 1
factory ............................................................................................................................... 2
form requests .................................................................................................................... 3
migration …........................................................................................................................ 4
policy ................................................................................................................................. 5
resource controller ............................................................................................................. 6
seed ................................................................................................................................... 7
❯ 2,3,4
INFO Model [app/Models/Post.php] created successfully.
INFO Factory [database/factories/PostFactory.php] was created successfully.
INFO Migration [database/migrations/2023_03_27_151438_create_posts_table.php] was created successfully.
The Str::password method can generate a secure, random password of a given length. The password will consist of a combination of letters, numbers, symbols, and spaces. By default, passwords are 32 characters long and contain letters, numbers and symbols. We can generate it as we wish, with or without letters, numbers, and symbols.
Here is the method definition:
public static function password($length = 32, $letters = true, $numbers = true, $symbols = true, $spaces = false)
Some examples:
> Str::password(10)
= "L>e~8Ns9;!"
> Str::password(letters: false)
= "{/\18{]69~_>:)%4//%61\9-%.-{~%|&"
> Str::password(numbers: false)
= "OomXSZUnWA,jWTgise%>hcEsQnB,D.\!"
Instead of using the Str class, we can also use the str() helper function.
> str()->password()
= "ZmJn^dib)GO)qutEER%QXmgt)fqJ\PiC"
There are many cases where this can be useful, such as generating a temporary password for a user.
Before Laravel 10, if we wanted to create a new project with Laravel Breeze and Pest, we needed to go through several steps:
1. Install the brand-new laravel project
2. Install Laravel Breeze
3. Install Laravel Pest
Laravel installer has two new important small features. When we create a new laravel project with the “laravel new” command, we can use the “–breeze” flag option to create a new project with Laravel Breeze.
If you use the Pest framework instead of the default phpunit for testing, there is also a small change about it too. Instead of using “laravel new example-app” and then “composer require pestphp/pest” we can use “laravel new example-app –pest” from now.
Here is an example of a new project installation with breeze and pest in just one command:
Methods marked as deprecated in Laravel 9 are being removed in Laravel 10. If you’re going to migrate a current project to Laravel 10, any code that uses a deprecated method should be rewritten in a new approach to achieve the same result.
Here are some of the deprecations:
We are a 200+ people agency and provide product design, software development, and creative growth marketing services to companies ranging from fresh startups to established enterprises. Our work has earned us 100+ international awards, partnerships with Laravel, Vue, Meta, and Google, and the title of Georgia’s agency of the year in 2019 and 2021.