Skip to content

Laravel

Laravel 是目前全球最流行的 PHP 全栈框架,以其优雅的语法、丰富的生态系统和开箱即用的功能著称。它由 Taylor Otwell 创建并维护,遵循 MVC(Model-View-Controller)架构模式,提供了路由、数据库 ORM、认证、队列、事件等完整的 Web 开发工具链。本节将从安装配置、核心概念、常用组件等方面全面介绍 Laravel 框架。

前置知识

阅读本节前,建议先了解:

基础概念

Laravel 的特点

特性说明
优雅的语法链式调用、流畅接口、表达式语法
Eloquent ORM强大的 ActiveRecord ORM
Blade 模板轻量级模板引擎,支持组件和布局
Artisan CLI强大的命令行工具
丰富生态Forge、Vapor、Nova、Socialite 等
队列系统支持多种队列驱动
中间件HTTP 中间件,符合 PSR-15
事件系统观察者模式,符合 PSR-14
开箱即用认证、授权、缓存、Session、邮件等

版本对应关系

LaravelPHP 最低版本支持状态
Laravel 11PHP 8.2当前 LTS(长期支持)
Laravel 10PHP 8.1维护中
Laravel 9PHP 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 SendNotificationEmail
php
<?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.php
php
<?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。

参考链接