Laravel 9 represents the biggest framework update in years. PHP 8 minimum requirement enables modern language features. At ZIRA Software, we've upgraded all projects to Laravel 9 for improved performance and developer experience.
Installation
# New project
composer create-project laravel/laravel myapp
# Upgrade existing
composer require laravel/framework:^9.0
PHP 8 Minimum
Required features now available:
// Constructor property promotion
class UserService
{
public function __construct(
private UserRepository $users,
private CacheManager $cache,
private LoggerInterface $logger,
) {}
}
// Named arguments
User::create(
name: 'John Doe',
email: 'john@example.com',
role: 'admin',
);
// Match expressions
$status = match($order->status) {
'pending' => 'Awaiting payment',
'processing' => 'Being prepared',
'shipped' => 'On the way',
'delivered' => 'Completed',
default => 'Unknown',
};
New Query Builder Interface
// Improved query builder with IDE support
use Illuminate\Database\Query\Builder;
$users = DB::table('users')
->select('id', 'name', 'email')
->where('active', true)
->orderBy('created_at', 'desc')
->get();
// Subquery improvements
$posts = Post::addSelect([
'last_comment_at' => Comment::select('created_at')
->whereColumn('post_id', 'posts.id')
->latest()
->limit(1)
])->get();
Controller Route Groups
use App\Http\Controllers\PostController;
Route::controller(PostController::class)->group(function () {
Route::get('/posts', 'index');
Route::post('/posts', 'store');
Route::get('/posts/{post}', 'show');
Route::put('/posts/{post}', 'update');
Route::delete('/posts/{post}', 'destroy');
});
// With middleware
Route::controller(AdminController::class)
->middleware(['auth', 'admin'])
->prefix('admin')
->group(function () {
Route::get('/dashboard', 'dashboard');
Route::get('/users', 'users');
});
Improved Accessors and Mutators
use Illuminate\Database\Eloquent\Casts\Attribute;
class User extends Model
{
// New unified syntax
protected function firstName(): Attribute
{
return Attribute::make(
get: fn (string $value) => ucfirst($value),
set: fn (string $value) => strtolower($value),
);
}
// With caching
protected function fullName(): Attribute
{
return Attribute::make(
get: fn () => "{$this->first_name} {$this->last_name}",
)->shouldCache();
}
}
Enum Casting
enum UserStatus: string
{
case Active = 'active';
case Inactive = 'inactive';
case Suspended = 'suspended';
}
class User extends Model
{
protected $casts = [
'status' => UserStatus::class,
];
}
// Usage
$user->status = UserStatus::Active;
$user->save();
// Route binding
Route::get('/users/{status}', function (UserStatus $status) {
return User::where('status', $status)->get();
});
Full-Text Search
// Migration
Schema::create('articles', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('body');
$table->fullText(['title', 'body']);
});
// Query
$articles = Article::whereFullText(
['title', 'body'],
'Laravel development'
)->get();
// With relevance ordering
$articles = Article::whereFullText(
['title', 'body'],
'Laravel',
['mode' => 'boolean']
)->orderByRaw('MATCH(title, body) AGAINST(? IN BOOLEAN MODE) DESC', ['Laravel'])
->get();
Scout Database Engine
// config/scout.php
'driver' => env('SCOUT_DRIVER', 'database'),
// Model
class Post extends Model
{
use Searchable;
public function toSearchableArray()
{
return [
'title' => $this->title,
'content' => $this->content,
];
}
}
// Search without external service
Post::search('Laravel tutorial')->get();
Conclusion
Laravel 9 modernizes the framework with PHP 8 features, improved syntax, and better developer experience. The upgrade path is smooth for most applications.
Planning Laravel 9 upgrade? Contact ZIRA Software for migration assistance.