Laravel 10 represents a significant modernization of the framework with native PHP type declarations. PHP 8.1 minimum enables stricter typing across the codebase. At ZIRA Software, Laravel 10 improves code quality and IDE support in all projects.
Installation
# New project
composer create-project laravel/laravel myapp
# Upgrade from Laravel 9
composer require laravel/framework:^10.0
PHP 8.1 Minimum
Required PHP version:
- PHP 8.1 or higher
- Full enum support
- Intersection types
- First-class callables
// Modern PHP features throughout
public function handle(Request $request): Response
{
// Fully typed method signatures
}
// Readonly properties
class Config
{
public function __construct(
public readonly string $appName,
public readonly string $environment,
) {}
}
Native Type Declarations
// Before Laravel 10
/**
* @param string $key
* @param mixed $default
* @return mixed
*/
public function get($key, $default = null)
{
// ...
}
// Laravel 10 - Native types
public function get(string $key, mixed $default = null): mixed
{
// ...
}
Improved Artisan Prompts
// app/Console/Commands/CreateUser.php
class CreateUser extends Command
{
protected $signature = 'user:create';
public function handle(): int
{
// Text input with validation
$name = text(
label: 'What is your name?',
required: true,
validate: fn ($value) => match (true) {
strlen($value) < 2 => 'Name must be at least 2 characters.',
default => null,
}
);
// Password input (hidden)
$password = password(
label: 'Create a password',
validate: fn ($value) => match (true) {
strlen($value) < 8 => 'Password must be at least 8 characters.',
default => null,
}
);
// Select from options
$role = select(
label: 'What role should the user have?',
options: ['admin', 'editor', 'viewer'],
default: 'viewer'
);
// Multi-select
$permissions = multiselect(
label: 'Select permissions',
options: ['create', 'read', 'update', 'delete'],
default: ['read']
);
// Confirmation
$confirmed = confirm(
label: 'Create this user?',
default: true
);
if ($confirmed) {
User::create([
'name' => $name,
'password' => Hash::make($password),
'role' => $role,
]);
info('User created successfully!');
}
return Command::SUCCESS;
}
}
Process Interaction
use Illuminate\Support\Facades\Process;
// Run external processes
$result = Process::run('npm run build');
echo $result->output();
echo $result->errorOutput();
echo $result->exitCode();
// With timeout
$result = Process::timeout(120)->run('composer install');
// With working directory
$result = Process::path('/var/www/app')->run('php artisan migrate');
// Async processes
$process = Process::start('npm run build');
// Do other work...
$result = $process->wait();
// Process pools
$results = Process::concurrently(function ($pool) {
$pool->command('npm run build');
$pool->command('php artisan optimize');
$pool->command('php artisan route:cache');
});
Improved Test Assertions
// tests/Feature/UserTest.php
class UserTest extends TestCase
{
public function test_user_can_view_profile(): void
{
$user = User::factory()->create();
$response = $this->actingAs($user)
->get('/profile');
$response->assertOk()
->assertViewIs('profile.show')
->assertViewHas('user', $user);
}
public function test_password_validation(): void
{
// Test password rules
$rules = Password::min(8)
->letters()
->mixedCase()
->numbers()
->symbols();
$this->assertTrue($rules->passes('Password123!'));
$this->assertFalse($rules->passes('password'));
}
}
Laravel Pennant Integration
// config/pennant.php - Feature flags built-in
use Laravel\Pennant\Feature;
// Define features
Feature::define('new-dashboard', function (User $user) {
return $user->is_beta_tester;
});
// Check features
if (Feature::active('new-dashboard')) {
return view('dashboard.new');
}
Invokable Validation Rules
// app/Rules/Uppercase.php
class Uppercase implements ValidationRule
{
public function validate(string $attribute, mixed $value, Closure $fail): void
{
if (strtoupper($value) !== $value) {
$fail('The :attribute must be uppercase.');
}
}
}
// Usage
$request->validate([
'code' => ['required', new Uppercase],
]);
Improved Eloquent
// Improved query builder return types
$users = User::query()
->where('active', true)
->orderBy('name')
->get(); // Returns Collection<User>
// Strict model configuration
Model::shouldBeStrict();
// Equivalent to:
Model::preventLazyLoading();
Model::preventSilentlyDiscardingAttributes();
Model::preventAccessingMissingAttributes();
Deprecation Handling
// config/logging.php
'deprecations' => [
'channel' => env('LOG_DEPRECATIONS_CHANNEL', 'null'),
'trace' => false,
],
// Log deprecations in development
// .env
LOG_DEPRECATIONS_CHANNEL=stack
Upgrade Guide
# Step 1: Update PHP to 8.1+
php -v
# Step 2: Update composer.json
"require": {
"php": "^8.1",
"laravel/framework": "^10.0"
}
# Step 3: Update dependencies
composer update
# Step 4: Review breaking changes
# - Return type declarations added
# - Some method signatures changed
# - Deprecated methods removed
Conclusion
Laravel 10 modernizes the framework with native PHP type declarations and improved developer tools. The upgrade brings better IDE support, code quality, and development experience.
Planning Laravel 10 upgrade? Contact ZIRA Software for migration assistance.