Laravel 框架入门教程 — 现代PHP开发首选

前置要求:PHP基础、Composer基础、MySQL基础
学习时长:约3-5天(每天4小时)
Laravel版本:11.x(最新稳定版)
适用场景:中大型Web应用、API开发、后台管理系统

一、Laravel 是什么?

Laravel 是 PHP 生态中最流行的框架,提供了优雅的语法、完善的工具链和庞大的社区生态。

特点说明
设计哲学优雅、简洁、表达力强
核心优势Eloquent ORM、Blade模板、Artisan命令行、队列系统
学习资源官方文档质量极高,中文社区活跃
就业市场PHP岗位中Laravel需求占比最高
薪资水平初级12-18K,中级18-30K,高级30K+

二、环境搭建与安装

2.1 环境要求

# 必需
PHP >= 8.2
Composer >= 2.x
MySQL >= 5.7 或 PostgreSQL >= 10

# 推荐
Node.js >= 18(前端资源编译)
Redis(队列、缓存)

2.2 安装 Laravel

# 方式1:Composer 全局安装(推荐)
composer global require laravel/installer

# 创建新项目
laravel new my-project

# 方式2:Composer 直接创建
composer create-project laravel/laravel my-project

# 进入项目
cd my-project

# 启动开发服务器
php artisan serve
# 访问 http://localhost:8000

2.3 宝塔面板部署

# Nginx 配置(站点根目录指向 public/)
server {
    listen 80;
    server_name your-domain.com;
    root /www/wwwroot/your-site/public;
    index index.php index.html;
    
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    
    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }
}


三、项目结构

my-project/
├── app/
│   ├── Http/
│   │   ├── Controllers/    # 控制器
│   │   ├── Middleware/      # 中间件
│   │   └── Requests/       # 表单请求验证
│   ├── Models/             # 数据模型(Eloquent)
│   ├── Services/           # 业务逻辑层
│   └── Providers/          # 服务提供者
├── config/                 # 配置文件
├── database/
│   ├── migrations/         # 数据库迁移
│   └── seeders/            # 测试数据填充
├── public/                 # 网站入口(Nginx根目录)
├── resources/
│   ├── views/              # Blade模板
│   └── css/js/             # 前端资源
├── routes/
│   ├── web.php             # Web路由
│   └── api.php             # API路由
├── storage/                # 日志、缓存、上传文件
├── .env                    # 环境配置(数据库密码等)
└── artisan                 # 命令行工具


四、路由系统

<?php
// routes/web.php
use App\Http\Controllers\UserController;
use App\Http\Controllers\PostController;

// 基本路由
Route::get('/', function () {
    return view('welcome');
});

// 带参数的路由
Route::get('/user/{id}', function ($id) {
    return "用户ID:$id";
});

// 控制器路由
Route::get('/users', [UserController::class, 'index']);
Route::post('/users', [UserController::class, 'store']);
Route::get('/users/{user}', [UserController::class, 'show']);
Route::put('/users/{user}', [UserController::class, 'update']);
Route::delete('/users/{user}', [UserController::class, 'destroy']);

// 资源路由(自动生成CRUD路由)
Route::resource('posts', PostController::class);

// 路由组
Route::prefix('admin')->middleware('auth')->group(function () {
    Route::get('/dashboard', [AdminController::class, 'dashboard']);
    Route::get('/users', [AdminController::class, 'users']);
});

// 命名路由
Route::get('/profile', [UserController::class, 'profile'])->name('profile');
// 生成URL:route('profile')

// ====================
// routes/api.php
// ====================
Route::prefix('v1')->group(function () {
    Route::apiResource('users', UserController::class);
    Route::apiResource('posts', PostController::class);
});
// 自动生成:GET /api/v1/users, POST /api/v1/users, GET /api/v1/users/{id}...


五、控制器

<?php
// app/Http/Controllers/UserController.php
namespace App\Http\Controllers;

use App\Models\User;
use App\Http\Requests\StoreUserRequest;
use Illuminate\Http\Request;

class UserController extends Controller
{
    // 列表(支持分页)
    public function index(Request $request)
    {
        $query = User::query();
        
        // 搜索
        if ($keyword = $request->input('keyword')) {
            $query->where('username', 'like', "%{$keyword}%")
                  ->orWhere('email', 'like', "%{$keyword}%");
        }
        
        // 排序
        $sortBy = $request->input('sort', 'created_at');
        $order = $request->input('order', 'desc');
        $query->orderBy($sortBy, $order);
        
        $users = $query->paginate($request->input('per_page', 15));
        
        return response()->json($users);
    }

    // 创建
    public function store(StoreUserRequest $request)
    {
        // 验证已在 StoreUserRequest 中完成
        $validated = $request->validated();
        
        $user = User::create([
            'username' => $validated['username'],
            'email' => $validated['email'],
            'password' => bcrypt($validated['password']),
        ]);
        
        return response()->json($user, 201);
    }

    // 详情
    public function show(User $user)
    {
        return response()->json($user);
    }

    // 更新
    public function update(Request $request, User $user)
    {
        $validated = $request->validate([
            'username' => 'sometimes|string|max:50',
            'email' => 'sometimes|email|unique:users,email,' . $user->id,
        ]);
        
        $user->update($validated);
        return response()->json($user);
    }

    // 删除
    public function destroy(User $user)
    {
        $user->delete();
        return response()->json(['message' => '删除成功']);
    }
}


六、Eloquent ORM(核心重点)

<?php
// app/Models/User.php
namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable
{
    use HasFactory, Notifiable;

    protected $fillable = ['username', 'email', 'password', 'role'];
    protected $hidden = ['password', 'remember_token'];
    protected $casts = [
        'email_verified_at' => 'datetime',
        'is_active' => 'boolean',
    ];

    // ====================
    // 关联关系
    // ====================
    
    // 一对多:用户有多篇文章
    public function posts()
    {
        return $this->hasMany(Post::class);
    }

    // 多对多:用户有多个角色
    public function roles()
    {
        return $this->belongsToMany(Role::class);
    }

    // 一对一:用户有一个个人资料
    public function profile()
    {
        return $this->hasOne(Profile::class);
    }

    // ====================
    // 访问器(获取时自动转换)
    // ====================
    public function getDisplayNameAttribute()
    {
        return $this->nickname ?? $this->username;
    }

    // ====================
    // 修改器(设置时自动转换)
    // ====================
    public function setEmailAttribute($value)
    {
        $this->attributes['email'] = strtolower($value);
    }

    // ====================
    // 作用域(查询复用)
    // ====================
    public function scopeActive($query)
    {
        return $query->where('is_active', true);
    }

    public function scopeSearch($query, $keyword)
    {
        return $query->where('username', 'like', "%{$keyword}%")
                     ->orWhere('email', 'like', "%{$keyword}%");
    }
}

// ====================
// 使用示例
// ====================

// 创建
$user = User::create([
    'username' => '张三',
    'email' => 'zhangsan@example.com',
    'password' => bcrypt('123456'),
]);

// 查询
$users = User::active()->search('张')->paginate(15);
$user = User::find(1);
$user = User::where('email', 'zhangsan@example.com')->firstOrFail();

// 更新
$user->update(['username' => '李四']);
$user->username = '王五';
$user->save();

// 删除
$user->delete();
User::destroy([1, 2, 3]);  // 批量删除

// 关联查询
$user->posts()->create(['title' => '第一篇文章', 'content' => '...']);
$user->posts()->where('status', 'published')->get();
$user->load('posts');  // 预加载(避免N+1问题)

// 聚合
$count = User::count();
$avgAge = User::avg('age');
$maxId = User::max('id');


七、数据库迁移

# 创建迁移
php artisan make:migration create_posts_table

# 执行迁移
php artisan migrate

# 回滚迁移
php artisan migrate:rollback

<?php
// database/migrations/xxxx_create_posts_table.php
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('posts', function (Blueprint $table) {
            $table->id();
            $table->foreignId('user_id')->constrained()->cascadeOnDelete();
            $table->string('title');
            $table->string('slug')->unique();
            $table->text('content');
            $table->enum('status', ['draft', 'published', 'archived'])->default('draft');
            $table->timestamp('published_at')->nullable();
            $table->timestamps();  // created_at + updated_at
            $table->softDeletes(); // deleted_at(软删除)
            
            // 索引
            $table->index(['user_id', 'status']);
            $table->index('published_at');
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('posts');
    }
};


八、表单验证

<?php
// app/Http/Requests/StoreUserRequest.php
namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StoreUserRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;  // 权限检查
    }

    public function rules(): array
    {
        return [
            'username' => 'required|string|min:3|max:50|unique:users',
            'email' => 'required|email|unique:users',
            'password' => 'required|string|min:8|confirmed',
            'role' => 'in:admin,editor,user',
        ];
    }

    public function messages(): array
    {
        return [
            'username.required' => '用户名不能为空',
            'username.unique' => '用户名已被使用',
            'email.email' => '邮箱格式不正确',
            'password.min' => '密码至少8位',
            'password.confirmed' => '两次密码不一致',
        ];
    }
}


九、中间件

<?php
// app/Http/Middleware/CheckAdmin.php
namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class CheckAdmin
{
    public function handle(Request $request, Closure $next)
    {
        if (!auth()->user() || auth()->user()->role !== 'admin') {
            return response()->json(['message' => '无权限访问'], 403);
        }
        return $next($request);
    }
}

// 注册中间件(app/bootstrap/app.php)
// ->withMiddleware(function (Middleware $middleware) {
//     $middleware->alias(['admin' => CheckAdmin::class]);
// })

// 使用中间件
Route::middleware(['auth', 'admin'])->group(function () {
    Route::get('/admin/users', [AdminController::class, 'users']);
});


十、Blade 模板引擎

<!-- resources/views/layouts/app.blade.php -->
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>@yield('title', '我的网站')</title>
    <style>
        body { font-family: Arial; margin: 0; }
        .navbar { background: #333; color: white; padding: 15px; }
        .container { max-width: 1200px; margin: 0 auto; padding: 20px; }
    </style>
</head>
<body>
    <nav class="navbar">
        <a href="/" style="color:white">首页</a>
        @auth
            <a href="/profile" style="color:white">{{ auth()->user()->username }}</a>
        @endauth
    </nav>
    
    <div class="container">
        @if(session('success'))
            <div class="alert alert-success">{{ session('success') }}</div>
        @endif
        
        @yield('content')
    </div>
</body>
</html>

<!-- resources/views/users/index.blade.php -->
@extends('layouts.app')

@section('title', '用户列表')

@section('content')
<h1>用户列表</h1>

<form method="GET">
    <input type="text" name="keyword" value="{{ request('keyword') }}" placeholder="搜索用户...">
    <button type="submit">搜索</button>
</form>

<table>
    <thead>
        <tr>
            <th>ID</th>
            <th>用户名</th>
            <th>邮箱</th>
            <th>注册时间</th>
            <th>操作</th>
        </tr>
    </thead>
    <tbody>
        @forelse($users as $user)
        <tr>
            <td>{{ $user->id }}</td>
            <td>{{ $user->username }}</td>
            <td>{{ $user->email }}</td>
            <td>{{ $user->created_at->format('Y-m-d H:i') }}</td>
            <td>
                <a href="/users/{{ $user->id }}">查看</a>
                <form method="POST" action="/users/{{ $user->id }}" style="display:inline">
                    @csrf
                    @method('DELETE')
                    <button type="submit" onclick="return confirm('确定删除?')">删除</button>
                </form>
            </td>
        </tr>
        @empty
        <tr>
            <td colspan="5">暂无数据</td>
        </tr>
        @endforelse
    </tbody>
</table>

{{ $users->links() }}
@endsection


十一、Artisan 常用命令

# 创建控制器
php artisan make:controller UserController --resource --model=User

# 创建模型(带迁移和工厂)
php artisan make:model Post -mf

# 创建请求
php artisan make:request StorePostRequest

# 创建中间件
php artisan make:middleware CheckAdmin

# 创建队列任务
php artisan make:job SendEmail

# 数据库操作
php artisan migrate              # 执行迁移
php artisan migrate:fresh --seed # 重建并填充数据
php artisan db:seed              # 填充测试数据

# 缓存优化(生产环境)
php artisan config:cache         # 缓存配置
php artisan route:cache          # 缓存路由
php artisan view:cache           # 缓存视图

# 清除缓存
php artisan cache:clear
php artisan config:clear
php artisan route:clear

# 队列处理
php artisan queue:work           # 处理队列任务

# 查看所有路由
php artisan route:list


十二、API 开发完整示例

<?php
// routes/api.php
Route::prefix('v1')->group(function () {
    Route::post('/auth/login', [AuthController::class, 'login']);
    Route::post('/auth/register', [AuthController::class, 'register']);
    
    Route::middleware('auth:sanctum')->group(function () {
        Route::get('/user', [AuthController::class, 'user']);
        Route::apiResource('posts', PostController::class);
    });
});

// app/Http/Controllers/PostController.php
class PostController extends Controller
{
    public function index(Request $request)
    {
        $posts = Post::with('user')
            ->when($request->keyword, fn($q, $k) => 
                $q->where('title', 'like', "%{$k}%"))
            ->when($request->status, fn($q, $s) => 
                $q->where('status', $s))
            ->latest()
            ->paginate(15);
        
        return PostResource::collection($posts);
    }

    public function store(StorePostRequest $request)
    {
        $post = auth()->user()->posts()->create($request->validated());
        return new PostResource($post);
    }
}

// app/Http/Resources/PostResource.php
class PostResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        return [
            'id' => $this->id,
            'title' => $this->title,
            'content' => $this->content,
            'status' => $this->status,
            'author' => new UserResource($this->whenLoaded('user')),
            'created_at' => $this->created_at->toIso8601String(),
        ];
    }
}


学习建议

  1. 先跑通官方文档的Quickstart,对整体流程有概念
  2. 重点掌握Eloquent ORM,80%的开发时间都在和数据库打交道
  3. 理解路由→控制器→模型→响应的请求生命周期
  4. 学会使用Artisan命令,大幅提高开发效率
  5. 做一个完整项目(博客系统或TODO API)巩固所学

下一步学习

返回首页