Introduction
It's not a secret that Laravel has more than 10 features that I don't know about, I just don't want to make it as a very long article. Moreover, many of them are very insignificant. Some of them I will never probably use. I've chosen 10 features that I didn't know about, but now I'm using them in all projects.
10 Laravel features
- Prefix for route names.
- Customizing the route parameter key.
- Casting values from request.
- Check migration status.
- Migration names with spaces.
- Column modifier on timestamp method.
- Customizing Laravel stubs.
- Progress bar for artisan command.
- Method
mapInto
on Collections. - Method “every” on Collections.
1. Prefix for route names
Documentation. Prefixes on route names allow you to add a prefix on all the routes in a group. Here is the example from my app:
Route::middleware('auth')->prefix('admin')->name('admin.')->group(function () {
Route::resource('posts', AdminPostController::class)->except(['show']);
Route::resource('tags', AdminTagController::class)->except(['show']);
});
Now, all the routes in a group will have the admin.
prefix. For example, the route for all posts will be admin.posts.index
, and for a single post admin.posts.show
. Unfortunately, PHP Storm 2021.1.2 doesn't know about that, and you will not have the intellisense for prefixed routes.
2. Customizing the route parameter key
Documentation. Imagine you have a posts.show
route, it's gonna look like that:
Route::get('posts/{post}', [PostController::class, 'show'])->name('posts.show');
When the user accesses the route /posts/1
, in your show
method, you'll receive the instance of the post with the identifier 1
.
public function show(Post $post): View {}
But if you want to get a post by its slug instead of identifier, you can customize the route parameter key.
Route::get('posts/{post:slug}', [PostController::class, 'show'])->name('posts.show');
After this, we can visit /posts/10-features-in-laravel-that-i-didnt-know-existed
and get the post in our controller action.
3. Casting values from request
Documentation. Did you know you can get cast values from request? I used to get a boolean value from a checkbox like this:
$is_published = $request->get('is-published') === 'on';
Illuminate\Http\Request
class has a boolean
method, that you can use:
$is_published = $request->boolean('is-published');
The boolean
method returns true
for 1, “1”, true, “true”, “on”, and “yes” values. For all the other values, it will return false
.
You can do the same for integers, floats, strings, dates, and even ENUM types like this:
$post_id = $request->integer('post_id');
$is_published = $request->boolean('is-published');
$price = $request->float('price');
$created_date = $birthday = $request->date('created'); // Carbon instance
$status = $request->enum('status', Status::class); // Enum type
4. Check migrations status
Documentation. Artisan command that shows the list of all migrations with the additional information.
php artisan migrate:status
The result looks like this:
Very useful when you need to check if there are migrations that haven't been migrated yet.
5. Migration names with spaces
I couldn't find this features in the documentation, I've heard about it in a YouTube video Laravel Migrations: 12 Useful Tips in 12 Minutes. It's an artisan command that simplifies migration naming.
php artisan make:migration "create blog table"
You simply surround the name with quotes to use spaces in migration names. It's not really a feature, but I constantly use it in my apps.
6. Column modifier on timestamp method
Documentation. If you are like me, used DB::raw('CURRENT_TIMESTAMP')
to set a default timestamp for the current date, then this feature is for you. Here's how I did it before:
public function up(): void
{
Schema::create('social_shares', function (Blueprint $table) {
$table->id();
$table->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));
});
}
But you can actually use a useCurrent
method on a timestamp.
$table->timestamp('created_at')->useCurrent();
7. Customizing Laravel stubs
Documentation. We have an artisan command that allows us to edit all the templates that Laravel uses for creating controllers, models and other classes.
php artisan stub:publish
In your project, you're going to see a stubs
directory after executing this command. The directory contains many files that you can edit.
I'm a big fan of using types, so I can take for example factory.stub
and make it how I want it to look with return types and fewer comments.
Every time when I create a new factory, it's going to use my newly created template instead of Laravel's one. Let's create a factory for the model Tag
.
php artisan make:factory TagFactory --model Tag
Now, in my database/factories
directory, I have a TagFactory.php
file that looks like this:
<?php
namespace Database\Factories;
use App\Models\Tag;
use Illuminate\Database\Eloquent\Factories\Factory;
class TagFactory extends Factory
{
protected $model = Tag::class;
public function definition(): array
{
return [
//
];
}
}
8. Progress bar for artisan command
Documentation. I was once writing a console command in one project, that downloads files from multiple sources. I remember thinking “It would have been nice to make a progress bar here”, it is unclear to me why I haven't checked Laravel's documentation for that because it has a progress bar that I didn't know about.
There are 2 ways of handling a progress bar, one with loops and another with callbacks. I prefer loops because they are way faster. Here is the example of the command that checks the HTTP status of certain sites.
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Http;
class TestCommand extends Command
{
protected $signature = 'sites:status';
protected $description = 'Checks statuses of the sites';
private array $urls = [
'https://serhii.io',
'https://github.com',
'https://duckduckgo.com',
'https://shobar.com',
'https://twitter.com',
];
public function handle(): void
{
$results = collect();
$bar = $this->output->createProgressBar(count($this->urls));
$bar->start();
foreach ($this->urls as $url) {
$results->push(Http::get($url)->status());
$bar->advance();
}
$bar->finish();
$this->newLine();
$this->info('Statuses are: ' . $results->join(', '));
}
}
After running a php artisan sites:status
command in a console, we get a charming progress bar with our result.
9. Method "mapInto" on Collections
Documentation. This method iterates over the collection, and creates a new instance of the given class by passing the value into the constructor. So instead of having a collection of arrays, you can have a collection of classes.
For example, we have a collection like this:
$collection = collect([['Dress', 22.3], ['Hat', 2.12]]);
To wrap all the nested arrays into class instances, we can apply mapInto
method. Let's say we want to have a collection of products. Here is our Product
class:
class Product
{
private string $name;
private float $price;
function __construct(array $data)
{
$this->name = $data[0];
$this->price = $data[1];
}
}
That's what we should do:
$collection = collect([['Dress', 22.3], ['Hat', 2.12]]);
$collection->mapInto(Product::class)->dd();
The result in a console:
10. Method “every” on Collections
Documentation. Many of you might already use this method, but not me. I've discovered it just a day before writing this article.
The method every
loops through the collection and checks if every item passes the condition that you provide in a callback.
For example, we need to make sure that every animal has 3 letters in its name. That's how I would do it:
$animals = collect(['cat', 'dog']);
$result = $animals->filter(fn($animal) => strlen($animal) === 3)->count() === $animals->count();
// Variable $result is true
With the method every
you can do it like that:
$animals = collect(['cat', 'dog']);
$result = $animals->every(fn($animal) => strlen($animal) === 3);
// Variable $result is true
More readable and simpler to write.
Tip. If you are eager to learn more about Laravel and PHP, I highly recommend using Laracasts. I've been watching Laracasts for a while, and it's been growing very rapidly thanks to a remarkable team of content creators there.
Conclusion
There you go! Thanks to Laravel for providing all the cool features that it has. It's such a pleasure to work with the framework. I hope this article was helpful, and you've learned something new about Laravel.
Which Laravel feature do you think is worth people knowing about? Please let us know in the comment section below.
❤️ Thanks to Mohammad Rahmani for the beautiful photo for this post.
Keywords: collection, backend