Laravel 框架

精选 Laravel 框架 常用指令与核心速查备忘单,涵盖高频用法、配置参数与实用技巧。 精选 Laravel 常用指令与核心速查备忘单,涵盖高频用法、配置参数与实用技巧。 Laravel 是富有表现力的渐进式 PHP Web 应用框架。本速查表面向 Laravel 8 常用命令与功能。

#快速入门

#系统要求 (Requirements)

  • PHP 版本 >= 7.3
  • BCMath PHP 扩展
  • Ctype PHP 扩展
  • Fileinfo PHP 扩展
  • JSON PHP 扩展
  • Mbstring PHP 扩展
  • OpenSSL PHP 扩展
  • PDO PHP 扩展
  • Tokenizer PHP 扩展
  • XML PHP 扩展

确保 Web 服务器将所有请求指向应用的 public/index.php 文件,参见: 部署

#🪟 窗口管理 安装 (Windows)

  • #安装 Docker Desktop

  • #安装并启用 WSL2

  • #确保 Docker Desktop 已配置为使用 WSL2

  • #在 WSL2 终端中:

    ```shell
    $ curl -s https://laravel.build/example-app | bash
    $ cd example-app
    $ ./vendor/bin/sail up
    ```
    

通过 http://localhost 访问应用

#Mac 安装 (Mac)

  • #安装 Docker Desktop

  • #在终端中:

    ```shell
    $ curl -s https://laravel.build/example-app | bash
    $ cd example-app
    $ ./vendor/bin/sail up
    ```
    

通过 http://localhost 访问应用

#Linux 安装 (Linux)

$ curl -s https://laravel.build/example-app | bash
$ cd example-app
$ ./vendor/bin/sail up

通过 Composer 安装

$ composer create-project laravel/laravel example-app
$ cd example-app
$ php artisan serve

通过 http://localhost 访问应用

#配置 (Configuration)

#环境变量 (.env)

.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']);

#调试模式 (Debug Mode)

开启(本地开发):

// .env file
APP_ENV=local
APP_DEBUG=true
// ...

关闭(生产环境):

// .env file
APP_ENV=production
APP_DEBUG=false
// ...

#维护模式 (Maintenance Mode)

临时停用应用(返回 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 并绕过 维护页面

#路由 (Routing)

#路由 HTTP 方法 (Router HTTP Methods)

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 () {
    //
});

#基本定义 (Basic Definition)

use Illuminate\Support\Facades\Route;

// closure
Route::get('/greeting', function () {
    return 'Hello World';
});

// controller action
Route::get(
    '/user/profile',
    [UserProfileController::class, 'show']
);

#依赖注入 (Dependency Injection)

use Illuminate\Http\Request;

Route::get('/users', function (Request $request) {
    // ...
});

对具体依赖做类型提示即可自动注入

#视图路由 (View Routes)

// Argument 1: URI, Argument 2: view name
Route::view('/welcome', 'welcome');

// with data
Route::view('/welcome', 'welcome', ['name' => 'Taylor']);

路由只需返回一个视图即可。

#路由模型绑定 (Route Model Binding)

隐式绑定 (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;
});

便捷方式:将模型实例自动注入到路由中

#路由参数 (Route Parameters)

在路由中捕获 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;
});

#重定向路由 (Redirect Routes)

HTTP 302 状态

Route::redirect('/here', '/there');

设置状态码

Route::redirect('/here', '/there', 301);

永久 301 重定向

Route::permanentRedirect('/here', '/there');

#正则表达式约束 (Regular Expression Constraints)

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]+']);

另见:正则速查表

#命名路由 (Named Routes)

路由名称必须始终唯一

Route::get('/user/profile', function () {
    //
})->name('profile');

参见:辅助函数

#回退路由 (Fallback Routes)

Route::fallback(function () {
    //
});

当没有任何其他路由匹配时执行

#路由组 (Route Groups)

中间件 (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');
});

在多条路由间共享属性

#访问当前路由 (Accessing current route)

use Illuminate\Support\Facades\Route;

// Illuminate\Routing\Route
$route = Route::current();

// string
$name = Route::currentRouteName();

// string
$action = Route::currentRouteAction();

#辅助函数 (Helpers)

#路由辅助 (routes)

命名路由 (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 生成 (URL Generation)

为应用生成任意 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();

#命名路由 URL (Named Route URL)

$url = route('profile');

参见 命名路由

#错误处理 (Error Handling)

public function isValid($value)
{
    try {
        // Validate the value...
    } catch (Throwable $e) {
        report($e);

        return false;
    }
}

报告异常但仍继续处理当前请求

#HTTP 异常 (HTTP Exceptions)

// page not found
abort(404);

// Unauthorized
abort(401);

// Forbidden
abort(403);

// Server Error
abort(500);

使用状态码生成 HTTP 异常响应

#控制器 (Controllers)

#基本用法

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']);

#请求 (Requests)

#CSRF 防护 (CSRF Protection)

Laravel 会为每个活动用户会话自动生成 CSRF「令牌」。 该令牌用于验证已认证用户确实是发起请求的人。

获取当前会话令牌:

Route::get('/token', function (Request $request) {
    $token = $request->session()->token();

    $token = csrf_token();

    // ...
});

POSTPUTPATCHDELETE 表单应包含隐藏的 CSRF _token 字段以校验 请求。

<form method="POST" action="/profile">
  @csrf

  <!-- Equivalent to... -->
  <input type="hidden" name="_token" value="{{ csrf_token() }}" />
</form>

参见 表单

#访问请求 (Accessing Request)

通过对控制器动作或路由闭包做类型提示获取当前请求实例

// controller action
class UserController extends Controller
{
    public function store(Request $request)
    {
        $name = $request->input('name');
    }
}

// closure
Route::get('/', function (Request $request) {
    //
});

参见路由

#路径 (Path)

请求的路径信息

$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)

传入请求的完整 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']);

#请求方法 (Request Method)

$method = $request->method();

// verify that the HTTP verb matches a given string
if ($request->isMethod('post')) {
    //
}

#客户端 IP (Client IP)

$ipAddress = $request->ip();

#请求头 (Headers)

$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();

#内容类型 (Content Type)

返回请求可接受的全部内容类型数组

$contentTypes = $request->getAcceptableContentTypes();

布尔检查:请求是否接受指定内容类型

if ($request->accepts(['text/html', 'application/json'])) {
    // ...
}

#输入数据 (Input)

将全部传入输入数据作为数组取出

$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');

#动态属性 (Dynamic Properties)

通过属性访问输入。 若输入中找不到,会继续检查路由参数。

$name = $request->name;

#获取部分输入 (Retrieve Partial Input)

$input = $request->only(['username', 'password']);

$input = $request->only('username', 'password');

$input = $request->except(['credit_card']);

$input = $request->except('credit_card');

#检查是否存在 (Check Existence)

判断某个/某些值是否存在

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')) {
    //
}

#旧输入 (Old Input)

获取上一次请求的输入

$username = $request->old('username');

或使用 old() 辅助函数

<input type="text" name="username" value="{{ old('username') }}">

参见:辅助函数 参见:表单

#上传文件 (Uploaded Files)

从请求中获取上传文件

$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 文件存储

#视图 (Views)

#简介 (Intro)

<!-- View stored in resources/views/greeting.blade.php -->

<html>
  <body>
    <h1>Hello, <?php echo $name; ?></h1>
  </body>
</html>

resources/views 目录放置 .blade.php 文件即可创建视图。

#向视图传递数据 (Pass Data to Views)

以数组传递 (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>

#view 辅助函数 (view helper)

在路由中用 view() 辅助函数返回视图

Route::get('/', function () {
    return view('greeting', ['name' => 'James']);
});

参见:视图路由辅助函数

#子目录 (Subdirectories)

// resources/views/admin.profile.blade.php
return view('admin.profile');

#Blade 模板 (Blade Templates)

#简介 (Intro)

Blade 是 Laravel 内置模板引擎,同时也允许使用原生 PHP。

#视图 (Views)

Blade 视图通过 view() 辅助函数返回

Route::get('/', function () {
    return view('welcome', ['name' => 'Samantha']);
});

参见:视图

#代码注释

{{-- This comment will not be present in the rendered HTML --}}

#指令 (Directives)

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 循环变量

#显示数据 (Displaying Data)

Blade 的回显语句 {{ }} 会自动经过 PHP 的 htmlspecialchars,以防 XSS 攻击。

显示 name 变量的内容:

Hello, {{ $name }}.

显示 PHP 函数的返回结果:

The current UNIX timestamp is {{ time() }}.

不经过 htmlspecialchars 转义直接输出数据

Hello, {!! $name !!}.

#包含子视图 (Including Subviews)

在一个视图中包含另一个 Blade 视图。 父视图可用的全部变量,对包含的子视图同样可用

<div>
  <!-- resources/views/shared/errors/blade.php -->
  @include('shared.errors')

  <form>
    <!-- Form Contents -->
  </form>
</div>

#原生 PHP (Raw PHP)

执行一段原生 PHP 代码块

@php
    $counter = 1;
@endphp

#堆栈 (Stacks)

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

#表单 (Forms)

#简介 (Intro)

#CSRF 字段 (CSRF Field)

加入隐藏 CSRF 令牌字段以校验请求

<form method="POST" action="/profile">
  @csrf

  ...
</form>

参见:CSRF 防护

#方法字段 (Method Field)

由于 HTML 表单无法直接发起 PUTPATCHDELETE 请求,需要添加隐藏 _method 字段来伪装 这些 HTTP 动词:

<form action="/post/my-post" method="POST">
  @method('PUT')

  ...
</form>

#验证错误 (Validation Errors)

<!-- /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

参见:验证

#回填表单 (Repopulating Forms)

因验证错误而重定向时,请求输入会被闪存到会话。 用 old 方法取回上一次请求的输入

$title = $request->old('title');

或使用 old() 辅助函数

<input type="text" name="title" value="{{ old('title') }}" />

#验证 (Validation)

#简介 (Intro)

若验证失败,将生成重定向到上一 URL 的响应。 若传入请求为 XHR,则返回包含验证错误信息的 JSON 响应。

#验证逻辑 (Logic)

// 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...
}

#验证规则 (Rules)

也可以数组形式传入规则

$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。 可接受输入为 truefalse10"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 类型。

MIME 类型与扩展名完整列表

可为空 (nullable)

字段可以为 null。

数值 (numeric)

字段必须为数值。

密码 (password)

字段必须与已认证用户的密码匹配。

禁止出现 (prohibited)

字段必须为空或不存在。

条件禁止 (prohibited_if:anotherfield,value,...)

anotherfield 等于任一给定值时,字段必须为空或不存在。

除非条件禁止 (prohibited_unless:anotherfield,value,...)

除非 anotherfield 等于任一给定值,否则字段必须为空或不存在。

必填 (必填)

字段必须存在于输入数据中且不为空。 满足以下任一条件即视为「空」:

  • 值为 null
  • 值为空字符串。
  • 值为空数组或空的 Countable 对象。
  • 值为没有路径的上传文件。

伴随必填 (必填_with:foo,bar,...)

仅当其他任一指定字段存在且非空时,本字段必须存在且非空

固定大小 (size:value)

字段大小必须匹配给定值。

  • 字符串:字符数量
  • 数值数据:整数值(还需配合 numericinteger 规则)。
  • 数组:元素个数
  • 文件:以千字节计的大小
// 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

查看全部可用规则

#验证密码 (Validate Passwords)

确保密码具备足够复杂度

$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()

#显示验证错误 (Display Validation Errors)

<!-- /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 -->

参见:验证错误

#可选字段 (可选 Fields)

若不想让验证器把可选字段的 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 Input)

获取已通过验证的请求数据

$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'];

#会话 (Session)

#简介 (Intro)

Laravel 内置多种会话后端,通过统一 API 访问。已包含 Memcached、Redis 与数据库 支持。

配置 (Configuration)

会话配置位于 config/session.php。 默认使用文件会话驱动

#检查是否设置/存在 (Check Isset / Exists)

当项存在且不为 null 时返回 true

if ($request->session()->has('users')) {
    //
}

只要存在即返回 true(即使值为 null):

if ($request->session()->exists('users')) {
    //
}

当项为 null 或不存在时返回 true

if ($request->session()->missing('users')) {
    //
}

#检索数据 (Retrieving Data)

通过 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');

#存储数据 (Store Data)

通过请求实例

$request->session()->put('key', 'value');

通过全局 session 辅助函数

session(['key' => 'value']);

向会话中已是数组的值追加新元素

// array of team names
$request->session()->push('user.teams', 'developers');

#日志 (Logging)

#配置 (Configuration)

日志行为配置位于 config/logging.php。 默认使用 stack 通道记录消息,它会把多个日志通道聚合为 单一通道。

#日志级别 (Levels)

RFC 5424 规范 中定义的全部日志级别均可用:

  • emergency(紧急)
  • alert(警报)
  • critical(严重)
  • error(错误)
  • warning(警告)
  • notice(通知)
  • info(信息)
  • debug(调试)

#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);

#上下文信息 (Contextual Info)

use Illuminate\Support\Facades\Log;

Log::info('User failed to login.', ['id' => $user->id]);

#部署 (Deployment)

#简介 (Intro)

确保 Web 服务器将所有请求指向应用的 public/index.php 文件

#优化 (Optimization)

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

#调试模式 (Debug Mode)

config/app.php 中的调试选项决定向用户展示多少错误信息 。 默认取自 .env 中的 APP_DEBUG 环境变量。在生产 环境中该值应始终为 false。 若生产环境将 APP_DEBUG 设为 true,可能把敏感配置暴露给最终 用户。