Skip to content

laravel_quick_guide

Laravel 是一个拥有富有表现力、优雅语法的 Web 应用框架。它遵循 MVC (模型-视图-控制器) 架构模式,并提供庞大的工具和功能生态系统,例如强大的 ORM (对象关系映射器,Eloquent)、数据库迁移、健壮的路由系统、集成的测试套件以及 Artisan 命令行接口。Laravel 旨在使常见的 Web 开发任务,如认证、路由、会话和缓存,变得更轻松、更快速。

作为开源框架,Laravel 受益于庞大的社区支持,并提供丰富的特性集,显著提高 Web 开发速度和质量。对于熟悉 PHP 的开发者而言,Laravel 提供了一种结构化且高效的方式来构建应用,减少了样板代码,并通过缓解常见的 Web 漏洞增强了安全性。

  • Eloquent ORM: 一个先进的 ActiveRecord 实现,用于轻松进行数据库交互。
  • 路由系统: 定义应用路由的简单而富有表现力的方式。
  • Blade 模板引擎: 一个强大而简单的模板语言。
  • 迁移与数据填充 (Migrations & Seeding): 数据库模式的版本控制和便捷的数据填充。
  • Artisan 控制台: 带有常用任务实用命令的命令行接口。
  • 测试: 内置支持使用 PHPUnit 进行单元测试和功能测试。
  • 模块化与 Composer: 轻松管理依赖和集成包。
  • 安全性: 防御常见的 Web 漏洞,如 XSS、CSRF 和 SQL 注入。
  • 任务调度 (Task Scheduling): 用于调度重复任务的流畅 API。
  • 队列 (Queues): 用于将耗时任务推迟到后台处理。
  • 广播与 WebSockets: 用于构建实时应用。
  • 认证与授权 (Authentication & Authorization): 简化用户登录、注册和访问控制的设置。

Laravel 使用 Composer 进行依赖管理。请确保在继续之前已在系统上安装 Composer。

从 https://getcomposer.org/download/ 下载并安装 Composer。使用 composer --version 验证安装。

使用 Composer 创建新的 Laravel 项目:

composer create-project laravel/laravel example-app

将 example-app 替换为你的项目名称。这将下载 Laravel 及其依赖。

进入你的项目目录(cd example-app)并启动 Artisan 开发服务器:

php artisan serve

这通常会在 http://127.0.0.1:8000 启动服务器。

在浏览器中打开 http://127.0.0.1:8000。你应该会看到 Laravel 的欢迎页面。

有关详细的系统要求和替代安装方法,例如 Laravel Sail (Docker),请参阅Laravel 安装指南章节。

Laravel 应用的根目录包含几个关键文件夹:

  • app - 包含应用的核心代码(模型、控制器、服务提供者等)。
  • bootstrap - 包含框架引导和配置自动加载的文件,以及一个用于存放框架生成文件的 cache 目录。
  • config - 包含应用的所有配置文件。
  • database - 包含数据库迁移、模型工厂和数据填充器。
  • public - 应用的文档根目录。它包含 index.php 入口文件和静态资源(CSS、JS、图片)。
  • resources - 包含视图(Blade 模板)、原始资源(如 Sass 或 Less 文件,如果不使用 Vite/Mix 默认配置)、和语言文件。
  • routes - 包含应用的所有路由定义(例如 web.php、api.php)。
  • storage - 包含编译后的 Blade 模板、基于文件的会话、文件缓存、日志以及框架生成的其他文件。也用于存放用户上传的文件。
  • tests - 包含自动化测试(功能测试和单元测试)。
  • vendor - 包含 Composer 依赖。

app 目录是应用大部分代码的存放位置。主要子目录包括:

  • Console - 包含自定义 Artisan 命令。
  • Exceptions - 包含应用的自定义异常处理器。
  • Http - 包含控制器、中间件和表单请求。
  • Jobs - 包含可队列任务。
  • Listeners - 包含事件处理类。
  • Mail - 包含用于发送电子邮件的可邮寄类。
  • Models - (通常由开发者创建,并非总是默认)包含 Eloquent 模型类。
  • Notifications - 包含通知类。
  • Policies - 包含授权策略类。
  • Providers - 包含应用的所有服务提供者。

所有 Laravel 框架的配置文件都存储在 config 目录中。每个选项都有文档说明,因此请随时查阅文件并熟悉可用的选项。

Laravel 使用 DotEnv PHP 库。敏感配置值(数据库凭据、API 密钥等)应存储在项目根目录的 .env 文件中。此文件不应提交到版本控制。

Laravel 中包含了一个 .env.example 文件。你应该将其复制为 .env 并进行修改:

cp .env.example .env

主要 .env 变量:

  • APP_NAME: 应用名称。
  • APP_ENV: 当前环境(例如 local、production、testing)。
  • APP_KEY: 用于加密的唯一 32 字符字符串。使用 php artisan key:generate 生成。
  • APP_DEBUG: 在本地开发中设置为 true 以查看详细错误,生产环境中设置为 false。
  • APP_URL: 应用的基本 URL。
  • DB_CONNECTION, DB_HOST, DB_DATABASE 等: 数据库连接详情。
  • MAIL_MAILER, MAIL_HOST 等: 邮件配置。

你可以使用 config() 助手函数在应用的任何地方访问配置值:

$appName = config('app.name');
$databaseConnection = config('database.default');

为了提高生产环境的性能,请缓存你的配置文件:

php artisan config:cache

清除缓存:php artisan config:clear。

当应用处于维护模式时,所有请求都将显示自定义视图。这在更新应用或执行计划维护时非常有用。

启动维护模式:

php artisan down

你还可以提供重定向或秘密绕过等选项:

php artisan down --redirect=/maintenance --retry=60 --secret="your-bypass-token"

停止维护模式:

php artisan up

通过创建 resources/views/errors/503.blade.php 自定义维护模式视图。

最基本的 Laravel 路由接受一个 URI 和一个闭包,提供了一种非常简单且富有表现力的方式来定义路由。Web 界面路由通常定义在 routes/web.php 中,API 路由定义在 routes/api.php 中。

可用的路由器方法:

Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);

示例(routes/web.php):

use Illuminate\Support\Facades\Route;
Route::get('/', function () {
return view('welcome'); // 返回欢迎 Blade 视图
});
Route::get('/hello', function () {
return 'Hello World!';
});

路由到控制器:

use App\Http\Controllers\UserController;
Route::get('/users', [UserController::class, 'index']);
Route::get('/users/{id}', [UserController::class, 'show']);

有时你需要在路由中捕获 URI 的片段。例如,你可能需要从 URL 中捕获用户的 ID。

Route::get('/user/{id}', function (string $id) {
return 'User ID: ' . $id;
});

你还可以指定在 URI 路径中并非总是存在的路由参数。你可以通过在参数名称后放置一个 ? 标记,并为变量提供一个默认值来实现。

Route::get('/user/{name?}', function (string $name = 'Guest') {
return 'Username: ' . $name;
});

如果路由段名称与类型提示的变量名称匹配,Laravel 会自动将模型实例直接注入到你的路由或控制器中。例如,你可以注入匹配给定 ID 的整个 User 模型实例,而不是注入用户的 ID。

use App\Models\User;
Route::get('/users/{user}', function (User $user) { // {user} 匹配 $user
return $user->email;
});

命名路由允许你方便地为特定路由生成 URL 或重定向。

Route::get('/user/profile', [UserProfileController::class, 'show'])->name('profile.show');
// Generating URL:
// $url = route('profile.show', ['id' => 1]);
// Redirecting:
// return redirect()->route('profile.show', ['id' => 1]);

路由组允许你在大量路由之间共享路由属性,例如中间件或前缀,而无需在每个单独路由上定义这些属性。

Route::middleware(['auth', 'admin'])->prefix('admin')->name('admin.')->group(function () {
Route::get('/dashboard', [AdminDashboardController::class, 'index'])->name('dashboard');
Route::get('/users', [AdminUserController::class, 'index'])->name('users.index');
});

中间件提供了一种机制,用于过滤进入应用的 HTTP 请求。它们充当请求通过的层。

使用 php artisan make:middleware <MiddlewareName> 创建中间件。

在 app/Http/Kernel.php 中注册:

  • 全局:$middleware 数组。
  • 组:$middlewareGroups 数组(例如 web、api)。
  • 路由别名:$middlewareAliases 数组。

从路由向中间件传递参数,例如 middleware('role:editor')。handle 方法在 $next 之后接收这些参数。

在中间件中使用 terminate 方法在响应发送后执行任务。

有关详细示例,请参阅Laravel 中间件章节。

控制器将请求处理逻辑组织成类,通常存储在 app/Http/Controllers 中。

php artisan make:controller <ControllerName>

php artisan make:controller PhotoController --resource 生成一个包含 CRUD 方法的控制器。使用 Route::resource('photos', PhotoController::class); 来设置路由。

php artisan make:controller ProvisionServer --invokable 创建一个包含 __invoke 方法的控制器。

Laravel 通过其服务容器自动注入依赖(在构造函数或方法中进行类型提示)。

有关详细示例,请参阅Laravel 控制器章节。

Laravel 的 Illuminate\Http\Request 类提供了一种面向对象的方式来与当前 HTTP 请求交互,包括获取输入、cookies 和文件。

你可以在控制器方法中对 Illuminate\Http\Request 进行类型提示。

use Illuminate\Http\Request;
public function store(Request $request)
{
$path = $request->path(); // 'foo/bar'
$url = $request->url(); // 'http://example.com/foo/bar'
$fullUrl = $request->fullUrl(); // 'http://example.com/foo/bar?name=taylor'
$method = $request->method(); // 'GET', 'POST', etc.
$isPost = $request->isMethod('post');
// Check if path matches a pattern
if ($request->is('admin/*')) { /* ... */ }
}
$name = $request->input('name'); // 从查询字符串或表单数据中获取
$email = $request->input('email', 'default@example.com'); // 带默认值
// 将所有输入作为数组获取
$allInput = $request->all();
// 仅获取特定输入
$subset = $request->only(['username', 'password']);
$except = $request->except(['credit_card']);
// 动态属性
$name = $request->name;
if ($request->hasFile('photo') && $request->file('photo')->isValid()) {
$file = $request->file('photo');
$path = $file->store('avatars', 'public'); // 存储到 storage/app/public/avatars
}

有关表单中输入获取的实际示例,请参见验证章节或文件上传章节。

Laravel 提供了一个简单的 API 用于管理 HTTP cookies。所有 cookies 默认都经过加密和签名。

附加到响应:return response('Hello')->cookie('name', 'value', $minutes); 使用 facade 入队:Cookie::queue('name', 'value', $minutes);

从请求中获取:$value = $request->cookie('name'); 使用 facade:$value = Cookie::get('name');

附加过期设置:return response('Deleted')->withoutCookie('name'); 入队以忘记:Cookie::queue(Cookie::forget('name'));

有关详细示例,请参阅Laravel Cookie 章节。

所有路由和控制器都应返回一个响应,以便发送回用户的浏览器。Laravel 提供了几种返回响应的方式。

字符串和数组会自动转换为 HTTP 响应。

Route::get('/', function () { return 'Hello World'; });
Route::get('/array', function () { return [1, 2, 3]; }); // 转换为 JSON

为了获得更多控制权,请使用 response() 助手或 Illuminate\Http\Response 类。

return response('Custom content', 200)
->header('Content-Type', 'text/plain')
->header('X-Custom-Header', 'value');
return response()->json(['name' => 'Abigail', 'state' => 'CA']);
return response()->json(['error' => 'Not found'], 404);
return response()->download(storage_path('app/files/report.pdf'));
return response()->download(storage_path('app/files/report.pdf'), 'user-report.pdf', $headers);

视图响应和重定向在各自的章节中介绍。

视图包含由你的应用提供的 HTML,并将控制器/应用逻辑与展示逻辑分离。视图存储在 resources/views 目录中。

创建一个类似 resources/views/greeting.blade.php 的文件:

<!-- 视图存储在 resources/views/greeting.blade.php 中 -->
<html>
<body>
<h1>Hello, {{ $name }}</h1>
</body>
</html>
Route::get('/greet', function () {
return view('greeting', ['name' => 'James']);
});

数据可以作为数组作为 view() 的第二个参数传递,或使用 with() 方法。

return view('profile', ['user' => $user]);
// 或者
return view('profile')->with('user', $user)->with('posts', $posts);

在服务提供者(例如 AppServiceProvider)的 boot 方法中使用 View::share('key', 'value')。

Blade 是 Laravel 简单而强大的模板引擎。Blade 视图文件使用 .blade.php 扩展名。

主要 Blade 指令:

  • {{ $variable }}: 显示数据(默认转义)。
  • {!! $variable !!}: 显示未转义数据(谨慎使用)。
  • @if、@elseif、@else、@endif: 条件语句。
  • @foreach、@forelse、@while、@for: 循环。
  • @csrf: CSRF 令牌字段。
  • @method('PUT'): 表单方法欺骗。
  • @include('partials.header'): 包含子视图。
  • @extends('layouts.app'): 继承主布局。
  • @section('content') ... @endsection: 定义内容区域。
  • @yield('title'): 显示子视图中某个区域的内容。
resources/views/layouts/app.blade.php
<html>
<head><title>@yield('title', 'My App')</title></head>
<body>
@include('partials.nav')
<div class="container">
@yield('content')
</div>
</body>
</html>
// resources/views/home.blade.php
@extends('layouts.app')
@section('title', 'Homepage')
@section('content')
<p>This is the home page content.</p>
@endsection

重定向响应是 Illuminate\Http\RedirectResponse 的实例,并包含将用户重定向到另一个 URL 所需的正确头信息。

return redirect('/home/dashboard');
return redirect()->route('profile.show', ['id' => 1]);
return redirect()->action([UserController::class, 'profile'], ['id' => 1]);
return back()->withInput(); // 重定向回上一页,并将旧输入闪存到 Session
return redirect()->route('dashboard')->with('status', 'Profile updated!');
// 在 dashboard.blade.php 中:
// @if (session('status')) <div class="alert alert-success">{{ session('status') }}</div> @endif

Laravel 支持 MySQL、PostgreSQL、SQLite 和 SQL Server。配置位于 .env 和 config/database.php 中。

使用数据库迁移进行模式版本控制:php artisan make:migration create_users_table。使用 php artisan migrate 运行。

用于数据库查询的流畅接口:DB::table('users')->where('active', 1)->get();

ActiveRecord 实现:User::where('active', 1)->orderBy('name')->get();

有关详细示例和原始 SQL,请参阅Laravel 数据库操作章节。

错误和异常处理在 App\Exceptions\Handler 中配置。.env 中的 APP_DEBUG=true 在开发中显示详细错误。

Laravel 使用 Monolog 库。在 config/logging.php 中配置日志通道。默认日志文件是 storage/logs/laravel.log。使用 Log facade:

use Illuminate\Support\Facades\Log;
Log::emergency($message);
Log::alert($message);
Log::critical($message);
Log::error($message);
Log::warning($message);
Log::notice($message);
Log::info($message);
Log::debug($message);

Laravel 不包含像旧版本中 laravelcollective/html 那样的内置 HTML 表单构建器。相反,你在 Blade 模板中使用标准 HTML 表单。

<form method="POST" action="{{ route('routeName') }}">
@csrf {{-- CSRF 保护 --}}
<div>
<label for="email">Email Address</label>
<input type="email" id="email" name="email" value="{{ old('email') }}" required>
@error('email')
<div class="alert alert-danger">{{ $message }}</div>
@enderror
</div>
<div>
<label for="password">Password</label>
<input type="password" id="password" name="password" required>
@error('password')
<div class="alert alert-danger">{{ $message }}</div>
@enderror
</div>
@if (false) {{-- PUT/PATCH/DELETE 请求示例 --}}
@method('PUT') {{-- 或 PATCH, DELETE --}}
@endif
<div>
<button type="submit">Submit</button>
</div>
</form>
  • @csrf: 生成一个包含 CSRF 令牌的隐藏输入字段。
  • method="POST": 用于修改数据的表单提交的标准方法。
  • action="{{ route('routeName') }}": 使用命名路由作为表单行为。
  • {{ old('input_name') }}: 如果验证失败,使用旧输入重新填充表单。
  • @error('input_name') ... @enderror: 显示特定字段的验证错误。
  • @method('VERB'): 用于 PUT、PATCH 或 DELETE 请求,因为 HTML 表单仅支持 GET 和 POST。

对于文件上传,向 <form> 标签添加 enctype="multipart/form-data"。参见文件上传章节。

Laravel 的本地化特性提供了一种方便的方式来获取不同语言的字符串,从而让你轻松地在应用中支持多种语言。

语言字符串存储在 lang 目录下的文件中(例如 lang/en/messages.php、lang/es/messages.php)。或者,对于基于 JSON 的文件:lang/en.json、lang/es.json。

PHP 文件示例(lang/en/messages.php):

<?php
return [
'welcome' => 'Welcome to our application!',
'greeting' => 'Hello, :name!',
];

使用 __ 助手函数或 @lang Blade 指令。

echo __('messages.welcome');
// 在 Blade 中: {{ __('messages.welcome') }} 或 @lang('messages.welcome')
echo __('messages.greeting', ['name' => 'Taylor']);

应用的默认语言环境在 config/app.php (locale) 中设置。你可以在运行时更改当前活跃语言环境:

use Illuminate\Support\Facades\App;
App::setLocale('es'); // 将当前语言环境设置为西班牙语

常见的做法是通过中间件根据 URL 段或用户偏好来设置语言环境。

HTTP 应用是无状态的。会话(Session)提供了一种跨多个请求存储用户信息的方式。Laravel 附带了各种 Session 后端(文件、cookie、数据库、Memcached/Redis 等),可在 config/session.php 和 .env (SESSION_DRIVER) 中配置。

访问 Session 数据(Illuminate\Http\Request):

Section titled “访问 Session 数据(Illuminate\Http\Request):”
// 存储数据
$request->session()->put('key', 'value');
// 获取数据
$value = $request->session()->get('key', 'default');
// 检查数据是否存在
if ($request->session()->has('users')) { /* ... */ }
// 获取所有数据
$allData = $request->session()->all();
// 移除一个项目
$request->session()->forget('key');
// 移除所有项目
$request->session()->flush();
session(['key' => 'value']); // 存储
$value = session('key', 'default'); // 获取

闪存数据仅在 Session 中存储到下一个请求。

$request->session()->flash('status', 'Task was successful!');
// 重定向后,在下一个请求的视图中:
// @if (session('status')) {{ session('status') }} @endif

Laravel 提供了几种不同的方法来验证应用的传入数据。最常见的是使用所有传入 HTTP 请求上可用的 validate 方法,或创建表单请求类 (Form Request classes)。

public function store(Request $request)
{
$validated = $request->validate([
'title' => 'required|unique:posts|max:255',
'body' => 'required',
'publish_at' => 'nullable|date',
]);
// 已验证的数据在 $validated 数组中可用
// 如果验证失败,会自动生成一个 RedirectResponse
// 或为 AJAX 请求生成一个带错误的 JsonResponse。
}

$errors 变量会自动在所有视图中可用。它是 Illuminate\Support\MessageBag 的一个实例。

@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<!-- 针对特定字段 -->
@error('title')
<div class="alert alert-danger">{{ $message }}</div>
@enderror

Laravel 提供了大量验证规则,包括 required、email、unique、min、max、date、confirmed、image、in、alpha 等。请参阅官方验证文档以获取完整列表。

对于更复杂的验证,使用 php artisan make:request StorePostRequest 创建表单请求类。这些类包含自己的授权和验证逻辑。

HTML 表单必须设置 enctype="multipart/form-data"。

$request->validate(['avatar' => 'required|image|mimes:jpeg,png|max:2048']);
if ($request->hasFile('avatar')) {
$path = $request->file('avatar')->store('avatars', 'public');
// 运行 `php artisan storage:link` 使 public disk 可访问
}

有关详细示例,请参阅Laravel 文件上传章节。

Laravel 使用 Symfony Mailer。通过 .env 和 config/mail.php 进行配置。

创建可邮寄类:php artisan make:mail OrderShipped。在可邮寄类中配置发件人、收件人、主题和视图。

use Illuminate\Support\Facades\Mail;
use App\Mail\OrderShipped;
Mail::to($recipient)->send(new OrderShipped($order));

有关详细示例,请参阅Laravel 发送邮件章节。

处理客户端异步请求。记住 CSRF 保护。

在 Blade 中添加 <meta name="csrf-token" content="{{ csrf_token() }}">。配置 JS 库(例如 jQuery $.ajaxSetup 或 Axios)以发送 X-CSRF-TOKEN 头。

从控制器返回 response()->json(['data' => $data]);。

有关详细示例,请参阅Laravel Ajax 章节。

所有异常都由 App\Exceptions\Handler 类处理。它包含 report()(用于日志记录)和 render()(用于 HTTP 响应)方法。

使用 abort(404); 或 abort(500, 'Something went wrong.'); 生成 HTTP 错误响应。

在 resources/views/errors/ 中创建 Blade 视图(例如 404.blade.php、503.blade.php)以自定义错误显示。

Laravel 的事件提供了一个简单的观察者实现,允许你订阅和监听应用中发生的各种事件。

`php artisan make:event PodcastProcessed`
`php artisan make:listener SendPodcastNotification --event=PodcastProcessed`

通常,如果监听器位于 App\Listeners 目录中并在其 handle 方法中正确地对事件进行类型提示,它们将自动被发现。手动注册在 App\Providers\EventServiceProvider 的 $listen 数组中完成:

protected $listen = [
\App\Events\PodcastProcessed::class => [
\App\Listeners\SendPodcastNotification::class,
],
];
use App\Events\PodcastProcessed;
PodcastProcessed::dispatch($podcast); // 或 event(new PodcastProcessed($podcast));

监听器 handle 方法:

public function handle(PodcastProcessed $event): void
{
// 访问 $event->podcast 并执行操作
}

Facades 提供了一个“静态”接口,用于访问应用服务容器中可用的类。它们提供了简洁、富有表现力的语法,同时保持了可测试性。

use Illuminate\Support\Facades\Cache;
Cache::put('key', 'value', $minutes);
$value = Cache::get('key');
  1. 创建一个包含功能的类。
  2. 创建一个继承 Illuminate\Support\Facades\Facade 的 Facade 类,实现 getFacadeAccessor() 方法以返回服务容器绑定键。
  3. 在服务提供者中绑定你的类(例如 App::bind('my-service', function() { return new MyService(); });)。
  4. (可选)在 config/app.php 的 aliases 数组中为 Facade 添加别名。

Laravel 开箱即用地提供了强大的安全特性。

  • 密码哈希 (Password Hashing): 使用 Hash facade(默认是 Bcrypt):Hash::make('password'),Hash::check('plain-text', $hashedPassword)。
  • 认证 (Authentication): 内置的用户登录、注册、密码重置服务。参见 Auth facade。
  • 授权 (Gates & Policies): 对用户权限进行细粒度控制。
  • CSRF 保护: 在 web 中间件组中对 POST、PUT、PATCH、DELETE 路由提供自动保护。在表单中使用 @csrf。
  • XSS 保护: Blade 的 {{ }} 语法会自动转义输出。极度谨慎地使用 {!! !!}。
  • SQL 注入保护: Eloquent ORM 和查询构建器使用 PDO 参数绑定,默认情况下可防止 SQL 注入。
  • Cookie 加密与签名: Cookies 会自动加密并签名。
  • HTTPS: 使用中间件或在服务提供者中使用 URL::forceScheme('https') 强制使用 HTTPS 来处理敏感数据。