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');
// 带默认值
env('APP_DEBUG', false);
确定当前环境
use Illuminate\Support\Facades\App;
$environment = App::environment();
使用“点”语法访问配置值
// config/app.php --> ['timezone' => '']
$value = config('app.timezone');
// 如果配置值不存在,则检索默认值...
$value = config('app.timezone', 'Asia/Seoul');
在运行时设置配置值:
config(['app.timezone' => 'America/Chicago']);
开启(本地开发):
// .env 文件
APP_ENV=local
APP_DEBUG=true
// ...
关闭(生产环境):
// .env 文件
APP_ENV=production
APP_DEBUG=false
// ...
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;
// 闭包
Route::get('/greeting', function () {
return 'Hello World';
});
// 控制器操作
Route::get(
'/user/profile',
[UserProfileController::class, 'show']
);
use Illuminate\Http\Request;
Route::get('/users', function (Request $request) {
// ...
});
类型提示具体依赖项以实现自动注入
// 参数 1: URI, 参数 2: 视图名称
Route::view('/welcome', 'welcome');
// 带数据
Route::view('/welcome', 'welcome', ['name' => 'Taylor']);
路由只需要返回一个视图。
使用闭包
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::get('/users/{user}', [UserController::class, 'show']);
// 控制器方法定义...
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');
始终使用不同的列进行解析
// 在 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 的段
Route::get('/user/{id}', function ($id) {
return 'User '.$id;
});
使用依赖注入
use Illuminate\Http\Request;
Route::get('/user/{id}', function (Request $request, $id) {
return 'User '.$id;
});
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 () {
//
});
当没有其他路由匹配时执行
Route::middleware(['first', 'second'])->group(function () {
Route::get('/', function () {
// 使用 first 和 second 中间件...
});
Route::get('/user/profile', function () {
// 使用 first 和 second 中间件...
});
});
Route::prefix('admin')->group(function () {
Route::get('/users', function () {
// 匹配 "/admin/users" URL
});
});
Route::name('admin.')->group(function () {
Route::get('/users', function () {
// 路由分配的名称为 "admin.users"...
})->name('users');
});
跨路由共享属性
use Illuminate\Support\Facades\Route;
// Illuminate\Routing\Route
$route = Route::current();
// 字符串
$name = Route::currentRouteName();
// 字符串
$action = Route::currentRouteAction();
$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
// 生成重定向...
return redirect()->route('profile');
echo route('post.show', ['post' => $post]);
路由辅助函数将自动提取模型的路由键。请参阅 路由
为您的应用程序生成任意 URL,这些 URL 将自动使用当前请求的方案(HTTP 或 HTTPS)和主机
$post = App\Models\Post::find(1);
echo url("/posts/{$post->id}");
// http://example.com/posts/1
// 获取不带查询字符串的当前 URL...
echo url()->current();
// 获取包含查询字符串的当前 URL...
echo url()->full();
// 获取先前请求的完整 URL...
echo url()->previous();
public function isValid($value)
{
try {
// 验证值...
} catch (Throwable $e) {
report($e);
return false;
}
}
报告异常但继续处理当前请求
// 页面未找到
abort(404);
// 未授权
abort(401);
// 禁止访问
abort(403);
// 服务器错误
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
<!-- 等同于... -->
<input type="hidden" name="_token" value="{{ csrf_token() }}" />
</form>
请参阅 表单
通过类型提示控制器操作或路由闭包来获取当前请求的实例
// 控制器操作
class UserController extends Controller
{
public function store(Request $request)
{
$name = $request->input('name');
}
}
// 闭包
Route::get('/', function (Request $request) {
//
});
请求的路径信息
$uri = $request->path();
// https://example.com/foo/bar --> foo/bar
验证传入的请求路径是否与给定模式匹配
// * 是通配符
if ($request->is('admin/*')) {
//
}
确定传入的请求是否与命名路由匹配
if ($request->routeIs('admin.*')) {
//
}
传入请求的完整 URL
// 不带查询字符串的 URL
$url = $request->url();
// 包含查询字符串的 URL
$urlWithQueryString = $request->fullUrl();
// 将数据附加到查询字符串
$request->fullUrlWithQuery(['type' => 'phone']);
$method = $request->method();
// 验证 HTTP 动词是否与给定字符串匹配
if ($request->isMethod('post')) {
//
}
$ipAddress = $request->ip();
$value = $request->header('X-Header-Name');
$value = $request->header('X-Header-Name', 'default value');
// 确定请求是否包含给定标头
if ($request->hasHeader('X-Header-Name')) {
//
}
// 从 Authorization 标头中检索持有者令牌
$token = $request->bearerToken();
返回一个包含请求接受的所有内容类型的数组
$contentTypes = $request->getAcceptableContentTypes();
布尔值检查请求是否接受内容类型
if ($request->accepts(['text/html', 'application/json'])) {
// ...
}
以数组形式检索所有传入请求的输入数据
$input = $request->all();
以集合形式检索所有传入请求的输入数据
$input = $request->collect();
// 以集合形式检索子集
$request->collect('users')->each(function ($user) {
// ...
});
请参阅 辅助函数
检索用户输入(也从查询字符串中获取值)
$name = $request->input('name');
// 如果不存在则使用默认值
$name = $request->input('name', 'Sally');
访问数组输入
$name = $request->input('products.0.name');
$names = $request->input('products.*.name');
以关联数组形式检索所有输入值:
$input = $request->input();
仅从查询字符串中检索值:
$name = $request->query('name');
// 带默认值
$name = $request->query('name', 'Helen');
以关联数组形式检索所有查询字符串值:
$query = $request->query();
有助于复选框输入或其他布尔值。对于 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')) {
//
}
// 检查是否所有值都存在
if ($request->has(['name', 'email'])) {
//
}
// 如果任何值存在
if ($request->hasAny(['name', 'email'])) {
//
}
// 如果请求中存在文件
if ($request->hasFile('image')) {
//
}
从请求中检索上传的文件
$file = $request->file('photo');
$file = $request->photo;
获取文件路径或扩展名
$path = $request->photo->path();
$extension = $request->photo->extension();
使用随机生成的文件名存储上传的文件
// 文件应存储的路径,相对于
// 文件系统配置的根目录
$path = $request->photo->store('images');
// 可选的第二个参数,用于指定文件系统磁盘
$path = $request->photo->store('images', 's3');
存储上传的文件并指定名称
$path = $request->photo->storeAs('images', 'filename.jpg');
$path = $request->photo->storeAs('images', 'filename.jpg', 's3');
更多信息:Laravel 文件存储
Blade 是 Laravel 中包含的模板引擎,它也允许您使用纯 PHP。
Blade 视图使用 view()
辅助函数返回
Route::get('/', function () {
return view('welcome', ['name' => 'Samantha']);
});
请参阅:视图
{{-- 此注释不会出现在渲染的 HTML 中 --}}
@if (count($records) === 1)
我有一条记录!
@elseif (count($records) > 1)
我有多个记录!
@else
我没有任何记录!
@endif
@isset($records)
// $records 已定义且不为 null...
@endisset
@empty($records)
// $records 为 "empty"...
@endempty
@auth
// 用户已通过身份验证...
@endauth
@guest
// 用户未通过身份验证...
@endguest
@for ($i = 0; $i < 10; $i++)
当前值为 {{ $i }}
@endfor
@foreach ($users as $user)
<p>这是用户 {{ $user->id }}</p>
@endforeach
@forelse ($users as $user)
<li>{{ $user->name }}</li>
@empty
<p>没有用户</p>
@endforelse
@while (true)
<p>我正在永远循环。</p>
@endwhile
循环迭代:
@foreach ($users as $user)
@if ($loop->first)
这是第一次迭代。
@endif
@if ($loop->last)
这是最后一次迭代。
@endif
<p>这是用户 <!--swig7--></p>
@endforeach
更多信息:Laravel 循环变量
Blade 的 echo 语句 {{ }}
会自动通过 PHP 的 htmlspecialchars
函数处理,以防止 XSS 攻击。
显示 name 变量的内容:
你好, {{ $name }}.
显示 PHP 函数的结果:
当前 UNIX 时间戳是 {{ time() }}.
显示数据而不使用 htmlspecialchars
转义
你好, {!! $name !!}.
从另一个视图中包含 Blade 视图。 父视图可用的所有变量也对包含的视图可用
<div>
<!-- resources/views/shared/errors/blade.php -->
@include('shared.errors')
<form>
<!-- 表单内容 -->
</form>
</div>
执行纯 PHP 代码块
@php
$counter = 1;
@endphp
Blade 允许您推送到命名堆栈,这些堆栈可以在另一个视图或布局中渲染。 对于子视图所需的 javascript 库很有用
<!-- 添加到堆栈 -->
@push('scripts')
<script src="/example.js"></script>
@endpush
渲染堆栈
<head>
<!-- 头部内容 -->
@stack('scripts')
</head>
前置到堆栈的开头
@push('scripts')
这将是第二个...
@endpush
// 稍后...
@prepend('scripts')
这将是第一个...
@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">文章标题</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 响应。
// 在 routes/web.php 中
Route::get('/post/create', [App\Http\Controllers\PostController::class, 'create']);
Route::post('/post', [App\Http\Controllers\PostController::class, 'store']);
// 在 app/Http/Controllers/PostController 中...
public function store(Request $request)
{
$validated = $request->validate([
// 输入名称 => 验证规则
'title' => 'required|unique:posts|max:255',
'body' => 'required',
]);
// 博客文章有效...
}
也可以作为数组传递
$validatedData = $request->validate([
'title' => ['required', 'unique:posts', 'max:255'],
'body' => ['required'],
]);
字段必须是给定日期之后的值。
'start_date' => 'required|date|after:tomorrow'
您可以指定另一个字段与日期进行比较,而不是日期字符串
'finish_date' => 'required|date|after:start_date'
请参阅 before:date
字段必须是给定日期之后或等于给定日期的值。 请参阅 after:date
字段必须是给定日期之前的值。
可以将另一个字段的名称作为 date
的值提供。
请参阅 after:date
字段必须完全是字母数字字符
字段必须能够转换为 boolean
。
接受的输入是 true
、false
、1
、0
、"1"
和 "0"
字段必须有一个匹配的 {field}_confirmation
字段。
例如,如果字段是 password,则必须存在一个匹配的 password_confirmation
字段
字段必须与经过身份验证的用户的密码匹配。
根据 strtotime
PHP 函数,字段必须是有效的、非相对的日期。
字段必须格式化为电子邮件地址。
字段必须是成功上传的文件。 请参阅:上传的文件
字段必须小于或等于最大值。 字符串、数字、数组和文件的计算方式与 size 规则类似。
字段必须具有最小值。 字符串、数字、数组和文件的计算方式与 size 规则类似。
文件必须匹配给定的 MIME 类型之一:
'video' => 'mimetypes:video/avi,video/mpeg,video/quicktime'
将读取文件内容,框架将尝试猜测 MIME 类型,而不管客户端提供的 MIME 类型如何。
字段的 MIME 类型必须对应于列出的扩展名之一。
'photo' => 'mimes:jpg,bmp,png'
将读取文件内容,框架将尝试猜测 MIME 类型,而不管客户端提供的 MIME 类型如何。
字段可以为 null。
字段必须是数字。
字段必须与经过身份验证的用户的密码匹配。
字段必须为空或不存在。
如果 anotherfield 字段等于任何值,则该字段必须为空或不存在。
除非 anotherfield 字段等于任何值,否则该字段必须为空或不存在。
字段必须存在于输入数据中且不能为空。 如果满足以下条件之一,则字段被视为“空”:
null
。Countable
对象。仅当任何其他指定字段存在且不为空时,该字段才必须存在且不为空
字段的大小必须与给定值匹配。
numeric
或 integer
规则)。// 验证字符串长度是否正好为 12 个字符...
'title' => 'size:12';
// 验证提供的整数是否等于 10...
'seats' => 'integer|size:10';
// 验证数组是否正好有 5 个元素...
'tags' => 'array|size:5';
// 验证上传的文件大小是否正好为 512 千字节...
'image' => 'file|size:512';
字段在给定的数据库表中不得存在
字段必须是有效的 URL
确保密码具有足够的复杂度
$validatedData = $request->validate([
'password' => ['required', 'confirmed', Password::min(8)],
]);
Password
规则对象允许您轻松自定义密码复杂度要求
// 要求至少 8 个字符...
Password::min(8)
// 要求至少一个字母...
Password::min(8)->letters()
// 要求至少一个大写字母和一个小写字母...
Password::min(8)->mixedCase()
// 要求至少一个数字...
Password::min(8)->numbers()
// 要求至少一个符号...
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>创建文章</h1>
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li><!--swig13--></li>
@endforeach
</ul>
</div>
@endif
<!-- 创建文章表单 -->
请参阅:验证错误
如果您不希望验证器将 null
值视为无效,则通常需要将“可选”请求字段标记为 nullable
// publish_at 字段可以为 null 或有效的日期表示形式
$request->validate([
'title' => 'required|unique:posts|max:255',
'body' => 'required',
'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();
foreach ($request->safe() as $key => $value) {
//
}
$validated = $request->safe();
$email = $validated['email'];
Laravel 附带了各种会话后端,可通过统一的 API 进行访问。包括 Memcached、Redis 和数据库支持。
会话配置在 config/session.php
中。
默认情况下,Laravel 配置为使用文件会话驱动程序
如果项目存在且不为 null
,则返回 true
:
if ($request->session()->has('users')) {
//
}
如果存在,即使为 null
,也返回 true
:
if ($request->session()->exists('users')) {
//
}
如果项目为 null
或不存在,则返回 true
:
if ($request->session()->missing('users')) {
//
}
// ...
class UserController extends Controller
{
public function show(Request $request, $id)
{
$value = $request->session()->get('key');
//
}
}
将默认值作为第二个参数传递,以便在键不存在时使用
$value = $request->session()->get('key', 'default');
// 可以传递闭包并作为默认值执行
$value = $request->session()->get('key', function () {
return 'default';
});
Route::get('/home', function () {
// 从会话中检索一条数据...
$value = session('key');
// 指定默认值...
$value = session('key', 'default');
// 在会话中存储一条数据...
session(['key' => 'value']);
});
请参阅:会话辅助函数
$data = $request->session()->all();
从会话中检索并删除一个项目
$value = $request->session()->pull('key', 'default');
通过请求实例
$request->session()->put('key', 'value');
通过全局“session”辅助函数
session(['key' => 'value']);
将新值推送到作为数组的会话值上
// 团队名称数组
$request->session()->push('user.teams', 'developers');
日志记录行为的配置选项在 config/logging.php
中。
默认情况下,Laravel 在记录消息时将使用堆栈通道,该通道将多个日志通道聚合到单个通道中。
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('用户登录失败。', ['id' => $user->id]);