Laravel
Laravel 是目前全球最流行的 PHP 全栈框架,以其优雅的语法、丰富的生态系统和开箱即用的功能著称。它由 Taylor Otwell 创建并维护,遵循 MVC(Model-View-Controller)架构模式,提供了路由、数据库 ORM、认证、队列、事件等完整的 Web 开发工具链。本节将从安装配置、核心概念、常用组件等方面全面介绍 Laravel 框架。
前置知识
阅读本节前,建议先了解:
- Composer 基本命令(参见 Composer 基本命令)
- PHP OOP 基础(参见 类基础)
- PHP 命名空间(参见 命名空间定义)
- PSR 规范概览(参见 其他 PSR 规范概览)
基础概念
Laravel 的特点
| 特性 | 说明 |
|---|---|
| 优雅的语法 | 链式调用、流畅接口、表达式语法 |
| Eloquent ORM | 强大的 ActiveRecord ORM |
| Blade 模板 | 轻量级模板引擎,支持组件和布局 |
| Artisan CLI | 强大的命令行工具 |
| 丰富生态 | Forge、Vapor、Nova、Socialite 等 |
| 队列系统 | 支持多种队列驱动 |
| 中间件 | HTTP 中间件,符合 PSR-15 |
| 事件系统 | 观察者模式,符合 PSR-14 |
| 开箱即用 | 认证、授权、缓存、Session、邮件等 |
版本对应关系
| Laravel | PHP 最低版本 | 支持状态 |
|---|---|---|
| Laravel 11 | PHP 8.2 | 当前 LTS(长期支持) |
| Laravel 10 | PHP 8.1 | 维护中 |
| Laravel 9 | PHP 8.0 | 已结束支持 |
详细说明
项目安装与创建
bash
# 创建新项目
composer create-project laravel/laravel myapp
# 指定版本
composer create-project laravel/laravel:^11.0 myapp
# 使用 Laravel 安装器
composer global require laravel/installer
laravel new myapp目录结构
laravel-project/
├── app/ # 应用核心代码
│ ├── Http/ # 控制器、中间件、请求
│ │ ├── Controllers/
│ │ ├── Middleware/
│ │ └── Requests/
│ ├── Models/ # Eloquent 模型
│ ├── Providers/ # 服务提供者
│ └── Services/ # 业务服务层
├── bootstrap/ # 框架引导文件
│ └── cache/ # 框架缓存文件
├── config/ # 配置文件
├── database/ # 数据库相关
│ ├── factories/ # 模型工厂
│ ├── migrations/ # 数据库迁移
│ └── seeders/ # 数据填充
├── public/ # Web 根目录
│ └── index.php # 入口文件
├── resources/ # 视图和前端资源
│ ├── views/ # Blade 模板
│ ├── css/
│ └── js/
├── routes/ # 路由定义
│ ├── web.php # Web 路由
│ └── api.php # API 路由
├── storage/ # 存储目录(日志、缓存、上传)
├── tests/ # 测试文件
├── composer.json
├── .env # 环境配置(不纳入版本控制)
└── artisan # CLI 入口路由
php
<?php
// routes/web.php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\UserController;
// 基本路由
Route::get('/', fn() => view('welcome'));
Route::get('/hello', fn() => 'Hello World');
// 控制器路由
Route::get('/users', [UserController::class, 'index']);
Route::get('/users/{id}', [UserController::class, 'show']);
// 资源路由
Route::resource('posts', PostController::class);
// API 路由(带认证)
Route::middleware('auth:sanctum')->group(function () {
Route::get('/api/user', fn(Request $request) => $request->user());
});控制器
php
<?php
declare(strict_types=1);
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
class UserController extends Controller
{
public function index(): JsonResponse
{
$users = User::query()
->where('is_active', true)
->orderBy('created_at', 'desc')
->paginate(20);
return response()->json($users);
}
public function show(int $id): JsonResponse
{
$user = User::findOrFail($id);
return response()->json([
'data' => $user,
]);
}
public function store(Request $request): JsonResponse
{
$validated = $request->validate([
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users',
'password' => 'required|string|min:8',
]);
$user = User::create($validated);
return response()->json($user, 201);
}
public function update(Request $request, int $id): JsonResponse
{
$user = User::findOrFail($id);
$user->update($request->validate([
'name' => 'sometimes|string|max:255',
]));
return response()->json($user);
}
public function destroy(int $id): JsonResponse
{
User::findOrFail($id)->delete();
return response()->json(null, 204);
}
}Eloquent ORM
php
<?php
declare(strict_types=1);
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
class User extends Model
{
use HasFactory;
protected $fillable = ['name', 'email', 'password'];
protected $hidden = ['password', 'remember_token'];
// 类型转换
protected $casts = [
'email_verified_at' => 'datetime',
'password' => 'hashed',
'is_active' => 'boolean',
];
// 一对多关系
public function posts(): HasMany
{
return $this->hasMany(Post::class);
}
// 多对多关系
public function roles(): BelongsToMany
{
return $this->belongsToMany(Role::class)->withTimestamps();
}
// 作用域
public function scopeActive($query)
{
return $query->where('is_active', true);
}
// 访问器
public function getFullNameAttribute(): string
{
return "{$this->first_name} {$this->last_name}";
}
}Artisan 命令
bash
# 常用 Artisan 命令
php artisan serve # 启动开发服务器
php artisan make:model Post -mf # 创建模型(含迁移和工厂)
php artisan make:controller PostController --resource
php artisan make:migration create_posts_table
php artisan make:seeder UserSeeder
php artisan make:middleware Auth
php artisan make:command SendEmails
php artisan migrate # 运行数据库迁移
php artisan migrate:fresh --seed # 重置数据库并填充
php artisan db:seed # 运行数据填充
php artisan route:list # 查看所有路由
php artisan config:cache # 缓存配置
php artisan route:cache # 缓存路由
php artisan view:cache # 缓存视图数据库迁移
php
<?php
// database/migrations/2024_01_01_000000_create_users_table.php
declare(strict_types=1);
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->boolean('is_active')->default(true);
$table->rememberToken();
$table->timestamps();
$table->softDeletes();
});
}
public function down(): void
{
Schema::dropIfExists('users');
}
};认证与授权
php
<?php
// Laravel 内置的认证脚手架
// 安装 Laravel Breeze(轻量级)
composer require laravel/breeze --dev
php artisan breeze:install
// 或安装 Laravel Jetstream(功能更丰富)
composer require laravel/jetstream
php artisan jetstream:install livewire
// 路由保护
Route::middleware('auth')->group(function () {
Route::get('/dashboard', [DashboardController::class, 'index']);
Route::get('/profile', [ProfileController::class, 'edit']);
});
// API 认证(Sanctum)
composer require laravel/sanctum
php artisan sanctuary:install
// 路由保护
Route::middleware('auth:sanctum')->group(function () {
Route::get('/api/user', fn(Request $request) => $request->user());
});队列与任务调度
bash
# 队列配置
# .env
QUEUE_CONNECTION=redis # 推荐 Redis
# QUEUE_CONNECTION=database # 使用数据库
# QUEUE_CONNECTION=sync # 同步(不推荐生产)
# 创建任务
php artisan make:job ProcessVideo
php artisan make:job SendNotificationEmailphp
<?php
// app/Jobs/SendNotificationEmail.php
declare(strict_types=1);
namespace App\Jobs;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class SendNotificationEmail implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function __construct(
public readonly User $user,
public readonly string $message,
) {}
public function handle(): void
{
// 发送邮件逻辑
Mail::to($this->user->email)->send(new NotificationMail($this->message));
}
}
// 分发任务
SendNotificationEmail::dispatch($user, 'Welcome!');
// 延迟分发
SendNotificationEmail::dispatch($user, 'Reminder')
->delay(now()->addHours(2));
// 链式任务
SendNotificationEmail::dispatch($user, 'Step 1')
->chain([
new UpdateUserStatus($user, 'active'),
new LogActivity($user, 'email_sent'),
]);事件与监听器
php
<?php
// 定义事件
namespace App\Events;
class UserRegistered
{
public function __construct(
public readonly \App\Models\User $user,
) {}
}
// 定义监听器
namespace App\Listeners;
class SendWelcomeEmail
{
public function __construct() {}
public function handle(UserRegistered $event): void
{
// 发送欢迎邮件
}
}
// 注册事件-监听器映射
// app/Providers/EventServiceProvider.php
protected $listen = [
UserRegistered::class => [
SendWelcomeEmail::class,
LogUserActivity::class,
CreateDefaultProfile::class,
],
];缓存系统
php
<?php
use Illuminate\Support\Facades\Cache;
// 基本缓存操作
Cache::put('key', 'value', 3600); // 存储一小时
Cache::get('key', 'default'); // 获取(带默认值)
Cache::remember('key', 3600, fn() => expensiveQuery()); // 记忆化
Cache::forget('key'); // 删除
Cache::has('key'); // 检查是否存在
Cache::increment('counter'); // 自增
Cache::decrement('counter', 5); // 自减
// 标签缓存(Redis/Memcached 驱动)
Cache::tags(['users', 'user:1'])->put('profile', $profileData, 3600);
Cache::tags(['user:1'])->flush(); // 清除所有 user:1 相关缓存实战示例
场景一:创建一个完整的 RESTful API
bash
# 1. 创建项目
composer create-project laravel/laravel:^11.0 api-project
cd api-project
# 2. 创建模型和迁移
php artisan make:model Product -mcr
# 3. 编辑迁移文件
# 4. 创建控制器
php artisan make:controller ProductController --api
# 5. 定义路由
# routes/api.phpphp
<?php
// routes/api.php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\ProductController;
Route::apiResource('products', ProductController::class);
// 带认证的路由
Route::middleware('auth:sanctum')->group(function () {
Route::apiResource('orders', OrderController::class);
});场景二:中间件实现
php
<?php
declare(strict_types=1);
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class RateLimiterMiddleware
{
public function handle(Request $request, Closure $next): Response
{
$key = 'rate_limit:' . $request->ip();
$maxAttempts = 60;
$decaySeconds = 60;
$attempts = cache()->increment($key);
if ($attempts === 1) {
cache()->put($key, 1, $decaySeconds);
}
if ($attempts > $maxAttempts) {
return response()->json([
'error' => 'Too Many Requests',
'retry_after' => cache()->ttl($key),
], 429);
}
$response = $next($request);
$response->headers->set('X-RateLimit-Remaining', $maxAttempts - $attempts);
return $response;
}
}注意事项
1. 环境配置
bash
# .env 文件必须配置
APP_NAME=MyApp
APP_ENV=local
APP_DEBUG=true
APP_URL=http://localhost:8000
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=myapp
DB_USERNAME=root
DB_PASSWORD=
# .env 文件不要纳入版本控制
# .env.example 纳入版本控制作为模板2. 安全最佳实践
- 生产环境
APP_DEBUG=false - 使用
php artisan key:generate生成应用密钥 - 使用 Laravel 的输入验证和 CSRF 保护
- 使用 Sanctum 或 Passport 进行 API 认证
最佳实践
1. 使用 Service 层
php
<?php
declare(strict_types=1);
namespace App\Services;
use App\Models\User;
use Illuminate\Support\Facades\Hash;
class UserService
{
public function createUser(array $data): User
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
}
public function deactivateUser(int $userId): void
{
User::findOrFail($userId)->update(['is_active' => false]);
}
}下一节
继续学习:Symfony 框架 — 了解 Laravel 的底层框架 Symfony。