Modernizing PHP: A Deep Dive into Laravel 11, Herd, Folio, and Volt
Overview
Building full-stack web applications requires a delicate balance between powerful backend logic and snappy, interactive frontends.
Prerequisites
To get the most out of these new features, you should have a firm grasp of the following:
- PHP 8.2+: Many of the new features, especially in Laravel 11, rely on modern PHP type-hinting and syntax.
- Blade Templating: Understanding the basics of Bladecomponents and directives.
- Eloquent ORM: Familiarity with how Laravelhandles database models and relationships.
- Command Line Interface (CLI): Comfort using Artisancommands for scaffolding and migrations.
Key Libraries & Tools
- Laravel Herd: A zero-dependency, lightning-fast PHP development environment for macOS that bypasses Homebrew.
- Laravel Folio: A page-based routing system that eliminates the need for manual route definitions in
web.php. - Laravel Volt: An add-on forLivewire 3that allows for single-file, functional PHP/Blade components.
- Laravel 11: The upcoming major version of the framework featuring a minimalist application skeleton.
The Laravel 11 Skeleton: Minimalist by Design
The Vanishing Middleware and Kernel
One of the most jarring changes is the removal of the app/Http/Middleware directory and the Kernel.php files. In previous versions, the framework shipped with nine default middlewares. In
Instead of a kernel, you now configure your application middleware and routing within the bootstrap/app.php file using a fluent, functional interface:
->withMiddleware(function (Middleware $middleware) {
$middleware->web(append: [
\App\Http\Middleware\LaraconMiddleware::class,
]);
})
Models and Method-Based Casts
Eloquents models are also seeing a syntax upgrade. While property-based casting (the $casts protected property) still works,
protected function casts(): array
{
return [
'options' => AsEnumCollection::of(UserOption::class),
];
}
Page-Based Routing with Laravel Folio
resources/views/pages/about.blade.php, it is automatically accessible at /about.
Dynamic Segments and Route Model Binding
Folio handles dynamic parameters using a bracket syntax in the filename. To bind a route to a specific [User].blade.php. Folio automatically detects this and performs route model binding behind the scenes.
// resources/views/pages/users/[User].blade.php
<div>
<h1>User Profile</h1>
<p>Name: {{ $user->name }}</p>
</div>
For more complex needs, Folio supports middleware declaration directly inside the Blade file. By using a <?php block at the top of the template, you can assign middleware like auth or can without ever touching a separate routes file.
Single-File Interactivity with Laravel Volt
The Functional API
Volt utilizes a functional API to define state, actions, and validation. Here is a look at a simple counter component written entirely within a single .blade.php file:
<?php
use function Laravel\Volt\{state};
state(['count' => 0]);
$increment = fn () => $this->count++;
?>
<div>
<h1>{{ $count }}</h1>
<button wire:click="increment">+</button>
</div>
This approach eliminates the context-switching required when bouncing between a Component.php class and a component.blade.php template. It supports the full
Anonymous Components
One of Volt's most powerful features is the volt directive. It allows you to turn a fragment of a standard Blade page into a reactive Livewire directory. This is ideal for small pieces of interactivity, such as a live search box or a polling notification list.
Syntax Notes
- Trailing Closures: Many new LaravelAPIs utilize trailing closures in their configuration files to keep the syntax clean.
- Wildcard Directories: In Laravel Folio, use
[...]for multi-segment parameters and[Model:slug]for scoped child binding. - State Management: In Laravel Volt, the
state()function accepts an associative array to initialize component properties.
Practical Examples
Implementing a Live Search with Volt
By combining the state and provide functions, you can create a high-performance search interface. Using the ->url() method on the state ensures that the search term stays in the browser's address bar, allowing users to share specific search results.
<?php
use App\Models\User;
use function Laravel\Volt\{state, provide};
state(['search' => ''])->url();
provide(['users' => fn () =>
User::where('name', 'like', "%{$this->search}%")->get()
]);
?>
<div>
<input wire:model.live="search" type="text" placeholder="Search users...">
<ul>
@foreach($users as $user)
<li>{{ $user->name }}</li>
@endforeach
</ul>
</div>
Tips & Gotchas
- PHP Version Matters: Laravel Herdmakes switching PHP versions trivial, but ensure your production environment matches the version you used during development to avoid type-hinting errors.
- Folio vs. Traditional Routes: You don't have to choose one. You can use Laravel Foliofor simple marketing pages and traditional routes/controllers for complex business logic.
- Validation in Volt: Always call
$this->validate()inside your action closures if you have definedrules()at the top of your Volt component. - Skeleton Upgrades: Upgrading to Laravel 11does not require you to adopt the new minimalist skeleton. Your existingLaravel 10structure will work perfectly fine after the upgrade.
