精选 Laravel 框架 常用指令与核心速查备忘单,涵盖高频用法、配置参数与实用技巧。 精选 Laravel 常用指令与核心速查备忘单,涵盖高频用法、配置参数与实用技巧。 Laravel 是富有表现力的渐进式 PHP Web 应用框架。本速查表面向 Laravel 8 常用命令与功能。
确保 Web 服务器将所有请求指向应用的 public/index.php 文件,参见:
部署
```shell
$ curl -s https://laravel.build/example-app | bash
$ cd example-app
$ ./vendor/bin/sail up
```
通过 http://localhost 访问应用
```shell
$ curl -s https://laravel.build/example-app | bash
$ cd example-app
$ ./vendor/bin/sail up
```
通过 http://localhost 访问应用
从 .env 文件读取配置值
env('APP_DEBUG');
// with 默认值
env('APP_DEBUG', false);
判断当前运行环境
use Illuminate\Support\Facades\App;
$environment = App::environment();
使用「点」语法访问配置值
// config/app.php --> ['timezone' => '']
$value = config('app.timezone');
// Retrieve a 默认值 if the configuration value does not exist...
$value = config('app.timezone', 'Asia/Seoul');
在运行时设置配置值:
config(['app.timezone' => 'America/Chicago']);
开启(本地开发):
// .env file
APP_ENV=local
APP_DEBUG=true
// ...
关闭(生产环境):
// .env file
APP_ENV=production
APP_DEBUG=false
// ...
临时停用应用(返回 503 状态码)
php artisan down
关闭维护模式 (Disable maintenance mode)
php artisan up
绕过维护模式 (Bypass Maintenance Mode)
php artisan down --secret="1630542a-246b-4b66-afa1-dd72a4c43515"
访问应用 URL https://example.com/1630542a-246b-4b66-afa1-dd72a4c43515 以写入 Cookie 并绕过
维护页面
Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);
匹配多种 HTTP 方法
Route::match(['get', 'post'], '/', function () {
//
});
Route::any('/', function () {
//
});
use Illuminate\Support\Facades\Route;
// closure
Route::get('/greeting', function () {
return 'Hello World';
});
// controller action
Route::get(
'/user/profile',
[UserProfileController::class, 'show']
);
use Illuminate\Http\Request;
Route::get('/users', function (Request $request) {
// ...
});
对具体依赖做类型提示即可自动注入
// Argument 1: URI, Argument 2: view name
Route::view('/welcome', 'welcome');
// with data
Route::view('/welcome', 'welcome', ['name' => 'Taylor']);
路由只需返回一个视图即可。
隐式绑定 (Implicit binding)
使用闭包
use App\Models\User;
Route::get('/users/{user}', function (User $user) {
return $user->email;
});
// /user/1 --> User::where('id', '=', 1);
使用控制器动作
use App\Http\Controllers\UserController;
use App\Models\User;
// Route definition...
Route::get('/users/{user}', [UserController::class, 'show']);
// Controller method definition...
public function show(User $user)
{
return view('user.profile', ['user' => $user]);
}
使用自定义解析列
use App\Models\Post;
Route::get('/posts/{post:slug}', function (Post $post) {
return $post;
});
// /posts/my-post --> Post::where('slug', '=', 'my-post');
始终使用其他列进行解析
// in App\Models\Post
public function getRouteKeyName()
{
return 'slug';
}
多个模型——第二个是第一个的子资源
use App\Models\Post;
use App\Models\User;
Route::get('/users/{user}/posts/{post:slug}', function (User $user, Post $post) {
return $post;
});
便捷方式:将模型实例自动注入到路由中
在路由中捕获 URI 路径片段
必需参数 (必填 parameters)
Route::get('/user/{id}', function ($id) {
return 'User '.$id;
});
结合依赖注入
use Illuminate\Http\Request;
Route::get('/user/{id}', function (Request $request, $id) {
return 'User '.$id;
});
可选参数 (可选 Parameters)
Route::get('/user/{name?}', function ($name = null) {
return $name;
});
Route::get('/user/{name?}', function ($name = 'John') {
return $name;
});
HTTP 302 状态
Route::redirect('/here', '/there');
设置状态码
Route::redirect('/here', '/there', 301);
永久 301 重定向
Route::permanentRedirect('/here', '/there');
Route::get('/user/{name}', function ($name) {
//
})->where('name', '[A-Za-z]+');
Route::get('/user/{id}', function ($id) {
//
})->where('id', '[0-9]+');
Route::get('/user/{id}/{name}', function ($id, $name) {
//
})->where(['id' => '[0-9]+', 'name' => '[a-z]+']);
另见:正则速查表
Route::fallback(function () {
//
});
当没有任何其他路由匹配时执行
中间件 (Middleware)
Route::middleware(['first', 'second'])->group(function () {
Route::get('/', function () {
// Uses first & second middleware...
});
Route::get('/user/profile', function () {
// Uses first & second middleware...
});
});
URI 前缀 (URI Prefixes)
Route::prefix('admin')->group(function () {
Route::get('/users', function () {
// Matches The "/admin/users" URL
});
});
名称前缀 (Name Prefix)
Route::name('admin.')->group(function () {
Route::get('/users', function () {
// Route assigned name "admin.users"...
})->name('users');
});
在多条路由间共享属性
use Illuminate\Support\Facades\Route;
// Illuminate\Routing\Route
$route = Route::current();
// string
$name = Route::currentRouteName();
// string
$action = Route::currentRouteAction();
命名路由 (Named route)
$url = route('profile');
带参数
// Route::get('/user/{id}/profile', /*...*/ )->name('profile);
$url = route('profile', ['id' => 1]);
// /user/1/profile/
带查询字符串
// Route::get('/user/{id}/profile', /*...*/ )->name('profile);
$url = route('profile', ['id' => 1, 'photos'=>'yes']);
// /user/1/profile?photos=yes
重定向 (Redirects)
// Generating Redirects...
return redirect()->route('profile');
Eloquent 模型 (Eloquent Models)
echo route('post.show', ['post' => $post]);
route 辅助函数会自动提取模型的路由键。参见 路由
为应用生成任意 URL,并自动使用当前请求的协议(HTTP 或 HTTPS)与主机 信息
$post = App\Models\Post::find(1);
echo url("/posts/{$post->id}");
// http://example.com/posts/1
当前 URL (Current URL)
// Get the current URL without the query string...
echo url()->current();
// Get the current URL including the query string...
echo url()->full();
// Get the full URL for the previous request...
echo url()->previous();
public function isValid($value)
{
try {
// Validate the value...
} catch (Throwable $e) {
report($e);
return false;
}
}
报告异常但仍继续处理当前请求
// page not found
abort(404);
// Unauthorized
abort(401);
// Forbidden
abort(403);
// Server Error
abort(500);
使用状态码生成 HTTP 异常响应
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Models\User;
class UserController extends Controller
{
public function show($id)
{
return view('user.profile', [
'user' => User::findOrFail($id)
]);
}
}
为该控制器方法定义路由:
use App\Http\Controllers\UserController;
Route::get('/user/{id}', [UserController::class, 'show']);
Laravel 会为每个活动用户会话自动生成 CSRF「令牌」。 该令牌用于验证已认证用户确实是发起请求的人。
获取当前会话令牌:
Route::get('/token', function (Request $request) {
$token = $request->session()->token();
$token = csrf_token();
// ...
});
POST、PUT、PATCH 或 DELETE 表单应包含隐藏的 CSRF _token 字段以校验
请求。
<form method="POST" action="/profile">
@csrf
<!-- Equivalent to... -->
<input type="hidden" name="_token" value="{{ csrf_token() }}" />
</form>
参见 表单
通过对控制器动作或路由闭包做类型提示获取当前请求实例
// controller action
class UserController extends Controller
{
public function store(Request $request)
{
$name = $request->input('name');
}
}
// closure
Route::get('/', function (Request $request) {
//
});
请求的路径信息
$uri = $request->path();
// https://example.com/foo/bar --> foo/bar
路径模式匹配 (Match path to pattern)
验证传入请求路径是否匹配给定模式
// * is wildcard
if ($request->is('admin/*')) {
//
}
判断传入请求是否匹配某个命名路由
if ($request->routeIs('admin.*')) {
//
}
传入请求的完整 URL
// URL without the query string
$url = $request->url();
// URL including query string
$urlWithQueryString = $request->fullUrl();
// append data to query string
$request->fullUrlWithQuery(['type' => 'phone']);
$method = $request->method();
// verify that the HTTP verb matches a given string
if ($request->isMethod('post')) {
//
}
$ipAddress = $request->ip();
$value = $request->header('X-Header-Name');
$value = $request->header('X-Header-Name', '默认值');
// determine if the request contains a given header
if ($request->hasHeader('X-Header-Name')) {
//
}
// retrieve a bearer token from the Authorization header
$token = $request->bearerToken();
返回请求可接受的全部内容类型数组
$contentTypes = $request->getAcceptableContentTypes();
布尔检查:请求是否接受指定内容类型
if ($request->accepts(['text/html', 'application/json'])) {
// ...
}
将全部传入输入数据作为数组取出
$input = $request->all();
将全部传入输入数据作为集合取出
$input = $request->collect();
// retrieve subset as collection
$request->collect('users')->each(function ($user) {
// ...
});
参见 辅助函数
获取用户输入(也会读取查询字符串)
$name = $request->input('name');
// with 默认值 if none present
$name = $request->input('name', 'Sally');
访问数组形式的输入
$name = $request->input('products.0.name');
$names = $request->input('products.*.name');
将全部输入值作为关联数组取出:
$input = $request->input();
仅从查询字符串中取值:
$name = $request->query('name');
// with 默认值
$name = $request->query('name', 'Helen');
将全部查询字符串值作为关联数组取出:
$query = $request->query();
布尔输入值 (Boolean Input Values)
适用于复选框或其他布尔输入。对 1、"1"、true、"true"、"on" 与 "yes" 返回 true。
其他所有值返回 false
$archived = $request->boolean('archived');
通过属性访问输入。 若输入中找不到,会继续检查路由参数。
$name = $request->name;
$input = $request->only(['username', 'password']);
$input = $request->only('username', 'password');
$input = $request->except(['credit_card']);
$input = $request->except('credit_card');
判断某个/某些值是否存在
if ($request->has('name')) {
//
}
// check if ALL values are present
if ($request->has(['name', 'email'])) {
//
}
// if any values are present
if ($request->hasAny(['name', 'email'])) {
//
}
// if a file is present on request
if ($request->hasFile('image')) {
//
}
从请求中获取上传文件
$file = $request->file('photo');
$file = $request->photo;
获取文件路径或扩展名
$path = $request->photo->path();
$extension = $request->photo->extension();
以随机生成的文件名存储上传文件
// path where the file should be stored relative to
// the filesystem's configured root directory
$path = $request->photo->store('images');
// 可选 2nd param to specify the filesystem disk
$path = $request->photo->store('images', 's3');
存储上传文件并指定文件名
$path = $request->photo->storeAs('images', 'filename.jpg');
$path = $request->photo->storeAs('images', 'filename.jpg', 's3');
更多参见:Laravel 文件存储
<!-- View stored in resources/views/greeting.blade.php -->
<html>
<body>
<h1>Hello, <?php echo $name; ?></h1>
</body>
</html>
在 resources/views 目录放置 .blade.php 文件即可创建视图。
以数组传递 (As an array)
return view('greetings', ['name' => 'Victoria']);
使用 with() (Using with())
return view('greeting')
->with('name', 'Victoria')
->with('occupation', 'Astronaut');
使用数据键名访问各个值
<html>
<body>
<h1>Hello, {{ $name }}</h1>
<!-- Or -->
<h1>Hello, <?php echo $name; ?></h1>
</body>
</html>
// resources/views/admin.profile.blade.php
return view('admin.profile');
Blade 是 Laravel 内置模板引擎,同时也允许使用原生 PHP。
Blade 视图通过 view() 辅助函数返回
Route::get('/', function () {
return view('welcome', ['name' => 'Samantha']);
});
参见:视图
{{-- This comment will not be present in the rendered HTML --}}
if 语句 (if Statements)
@if (count($records) === 1)
I have one record!
@elseif (count($records) > 1)
I have multiple records!
@else
I don't have any records!
@endif
isset 与 empty (isset & empty)
@isset($records)
// $records is defined and is not null...
@endisset
@empty($records)
// $records is "empty"...
@endempty
身份验证 (Authentication)
@auth
// The user is authenticated...
@endauth
@guest
// The user is not authenticated...
@endguest
循环 (Loops)
@for ($i = 0; $i < 10; $i++)
The current value is {{ $i }}
@endfor
@foreach ($users as $user)
<p>This is user {{ $user->id }}</p>
@endforeach
@forelse ($users as $user)
<li>{{ $user->name }}</li>
@empty
<p>No users</p>
@endforelse
@while (true)
<p>I'm looping forever.</p>
@endwhile
循环迭代信息:
@foreach ($users as $user)
@if ($loop->first)
This is the first iteration.
@endif
@if ($loop->last)
This is the last iteration.
@endif
<p>This is user <!--swig7--></p>
@endforeach
更多参见:Laravel 循环变量
Blade 的回显语句 {{ }} 会自动经过 PHP 的 htmlspecialchars,以防 XSS 攻击。
显示 name 变量的内容:
Hello, {{ $name }}.
显示 PHP 函数的返回结果:
The current UNIX timestamp is {{ time() }}.
不经过 htmlspecialchars 转义直接输出数据
Hello, {!! $name !!}.
在一个视图中包含另一个 Blade 视图。 父视图可用的全部变量,对包含的子视图同样可用
<div>
<!-- resources/views/shared/errors/blade.php -->
@include('shared.errors')
<form>
<!-- Form Contents -->
</form>
</div>
执行一段原生 PHP 代码块
@php
$counter = 1;
@endphp
Blade 允许向命名堆栈推送内容,并可在其他视图或布局中渲染。 适合子视图所需的 JavaScript 库
<!-- Add to the stack -->
@push('scripts')
<script src="/example.js"></script>
@endpush
渲染堆栈
<head>
<!-- Head Contents -->
@stack('scripts')
</head>
向前插入到堆栈开头
@push('scripts')
This will be second...
@endpush
// Later...
@prepend('scripts')
This will be first...
@endprepend
由于 HTML 表单无法直接发起 PUT、PATCH 或 DELETE 请求,需要添加隐藏 _method 字段来伪装
这些 HTTP 动词:
<form action="/post/my-post" method="POST">
@method('PUT')
...
</form>
<!-- /resources/views/post/create.blade.php -->
<label for="title">Post Title</label>
<input id="title" type="text" class="@error('title') is-invalid @enderror" />
@error('title')
<div class="alert alert-danger">{{ $message }}</div>
@enderror
参见:验证
因验证错误而重定向时,请求输入会被闪存到会话。
用 old 方法取回上一次请求的输入
$title = $request->old('title');
或使用 old() 辅助函数
<input type="text" name="title" value="{{ old('title') }}" />
若验证失败,将生成重定向到上一 URL 的响应。 若传入请求为 XHR,则返回包含验证错误信息的 JSON 响应。
// in routes/web.php
Route::get('/post/create', [App\Http\Controllers\PostController::class, 'create']);
Route::post('/post', [App\Http\Controllers\PostController::class, 'store']);
// in app/Http/Controllers/PostController...
public function store(Request $request)
{
$validated = $request->validate([
// input name => validation rules
'title' => '必填|unique:posts|max:255',
'body' => '必填',
]);
// The blog post is valid...
}
也可以数组形式传入规则
$validatedData = $request->validate([
'title' => ['必填', 'unique:posts', 'max:255'],
'body' => ['必填'],
]);
晚于日期 (after:date)
字段值必须晚于给定日期。
'start_date' => '必填|date|after:tomorrow'
除日期字符串外,也可指定另一字段与之比较日期
'finish_date' => '必填|date|after:start_date'
参见 早于日期
晚于或等于日期 (after_or_equal:date)
字段值必须晚于或等于给定日期。 参见 晚于日期
早于日期 (before:date)
字段值必须早于给定日期。
可将另一字段名作为 date 的值传入。
参见 晚于日期
字母数字 (alpha_num)
字段必须全部由字母与数字组成
布尔值 (boolean)
字段必须可被转换为 boolean。
可接受输入为 true、false、1、0、"1" 与 "0"
确认字段 (confirmed)
字段必须存在对应的 {field}_confirmation 确认字段。
例如字段为 password 时,必须同时存在 password_confirmation 字段
当前密码 (current_password)
字段必须与已认证用户的密码匹配。
日期 (date)
字段必须是 strtotime 可解析的有效、非相对日期。
电子邮箱 (email)
字段必须格式化为电子邮箱地址。
文件 (file)
字段必须是成功上传的文件。 参见:上传文件
最大值 (max:value)
字段必须小于或等于最大值。 字符串、数值、数组与文件的计算方式同 size 规则。
最小值 (min:value)
字段必须达到最小值。 字符串、数值、数组与文件的计算方式同 size 规则。
MIME 类型 (mimetypes:text/plain,...)
文件必须匹配给定 MIME 类型之一:
'video' => 'mimetypes:video/avi,video/mpeg,video/quicktime'
框架会读取文件内容并尝试猜测 MIME 类型,而不依赖客户端提供的 MIME 类型。
扩展名 MIME (mimes:foo,bar,...)
字段的 MIME 类型必须对应所列扩展名之一。
'photo' => 'mimes:jpg,bmp,png'
框架会读取文件内容并尝试猜测 MIME 类型,而不依赖客户端提供的 MIME 类型。
可为空 (nullable)
字段可以为 null。
数值 (numeric)
字段必须为数值。
密码 (password)
字段必须与已认证用户的密码匹配。
禁止出现 (prohibited)
字段必须为空或不存在。
条件禁止 (prohibited_if:anotherfield,value,...)
当 anotherfield 等于任一给定值时,字段必须为空或不存在。
除非条件禁止 (prohibited_unless:anotherfield,value,...)
除非 anotherfield 等于任一给定值,否则字段必须为空或不存在。
必填 (必填)
字段必须存在于输入数据中且不为空。 满足以下任一条件即视为「空」:
null。Countable 对象。伴随必填 (必填_with:foo,bar,...)
仅当其他任一指定字段存在且非空时,本字段必须存在且非空
固定大小 (size:value)
字段大小必须匹配给定值。
numeric 或 integer 规则)。// Validate that a string is exactly 12 characters long...
'title' => 'size:12';
// Validate that a provided integer equals 10...
'seats' => 'integer|size:10';
// Validate that an array has exactly 5 elements...
'tags' => 'array|size:5';
// Validate that an uploaded file is exactly 512 kilobytes...
'image' => 'file|size:512';
唯一约束 (unique:table,column)
字段值不得已存在于给定数据库表中
URL 格式 (url)
字段必须是有效 URL
确保密码具备足够复杂度
$validatedData = $request->validate([
'password' => ['必填', 'confirmed', Password::min(8)],
]);
Password 规则对象可方便地自定义密码复杂度要求
// Require at least 8 characters...
Password::min(8)
// Require at least one letter...
Password::min(8)->letters()
// Require at least one uppercase and one lowercase letter...
Password::min(8)->mixedCase()
// Require at least one number...
Password::min(8)->numbers()
// Require at least one symbol...
Password::min(8)->symbols()
确保密码未出现在公开密码泄露库中
Password::min(8)->uncompromised()
通过 k-匿名 模型,借助 haveibeenpwned.com 服务完成检查,且不牺牲用户隐私与安全
方法可以链式调用
Password::min(8)
->letters()
->mixedCase()
->numbers()
->symbols()
->uncompromised()
<!-- /resources/views/post/create.blade.php -->
<h1>Create Post</h1>
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li><!--swig13--></li>
@endforeach
</ul>
</div>
@endif
<!-- Create Post Form -->
参见:验证错误
若不想让验证器把可选字段的 null 当成无效,通常需将其标为 nullable
否则验证器会把 null 值判定为无效
// publish_at field may be either null or a valid date representation
$request->validate([
'title' => '必填|unique:posts|max:255',
'body' => '必填',
'publish_at' => 'nullable|date',
]);
获取已通过验证的请求数据
$validated = $request->validated();
或使用 safe(),它返回 Illuminate\Support\ValidatedInput 实例
$validated = $request->safe()->only(['name', 'email']);
$validated = $request->safe()->except(['name', 'email']);
$validated = $request->safe()->all();
遍历 (Iterate)
foreach ($request->safe() as $key => $value) {
//
}
按数组访问 (Access as an array)
$validated = $request->safe();
$email = $validated['email'];
Laravel 内置多种会话后端,通过统一 API 访问。已包含 Memcached、Redis 与数据库 支持。
配置 (Configuration)
会话配置位于 config/session.php。
默认使用文件会话驱动
当项存在且不为 null 时返回 true:
if ($request->session()->has('users')) {
//
}
只要存在即返回 true(即使值为 null):
if ($request->session()->exists('users')) {
//
}
当项为 null 或不存在时返回 true:
if ($request->session()->missing('users')) {
//
}
通过 Request (Via Request)
// ...
class UserController extends Controller
{
public function show(Request $request, $id)
{
$value = $request->session()->get('key');
//
}
}
可将默认值作为第二参数传入,在键不存在时使用
$value = $request->session()->get('key', 'default');
// closure can be passed and executed as a default
$value = $request->session()->get('key', function () {
return 'default';
});
通过 session 辅助函数 (Via session helper)
Route::get('/home', function () {
// Retrieve a piece of data from the session...
$value = session('key');
// Specifying a 默认值...
$value = session('key', 'default');
// Store a piece of data in the session...
session(['key' => 'value']);
});
参见:Session 辅助函数
全部会话数据 (All Session Data)
$data = $request->session()->all();
取出并删除 (Retrieve and Delete)
从会话中取出并删除某一项
$value = $request->session()->pull('key', 'default');
通过请求实例
$request->session()->put('key', 'value');
通过全局 session 辅助函数
session(['key' => 'value']);
向会话中已是数组的值追加新元素
// array of team names
$request->session()->push('user.teams', 'developers');
日志行为配置位于 config/logging.php。
默认使用 stack 通道记录消息,它会把多个日志通道聚合为
单一通道。
RFC 5424 规范 中定义的全部日志级别均可用:
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);
use Illuminate\Support\Facades\Log;
Log::info('User failed to login.', ['id' => $user->id]);
确保 Web 服务器将所有请求指向应用的 public/index.php 文件
Composer 自动加载映射 (Composer's autoloader map)
composer install --optimize-autoloader --no-dev
配置加载 (Configuration Loading)
请确保仅在配置文件中调用 env 函数。
配置缓存后将不再加载 .env,此后对 .env 变量调用 env 函数都会
返回 null
php artisan config:cache
路由加载 (Route Loading)
php artisan route:cache
视图加载 (View Loading)
php artisan view:cache
config/app.php 中的调试选项决定向用户展示多少错误信息
。
默认取自 .env 中的 APP_DEBUG 环境变量。在生产
环境中该值应始终为 false。
若生产环境将 APP_DEBUG 设为 true,可能把敏感配置暴露给最终
用户。