Laravel-启动指南-八-

163 阅读26分钟

Laravel 启动指南(八)

原文:zh.annas-archive.org/md5/d0c72cd35a2ef551cf4f36bed0d4e4e2

译者:飞龙

协议:CC BY-NC-SA 4.0

第十七章:辅助函数与集合

我们已经在整本书中涵盖了许多全局函数:这些是一些小辅助函数,使执行常见任务变得更加容易,例如用于作业的dispatch(),用于事件的event(),以及用于依赖解析的app()。我们还在第五章中讨论了 Laravel 的集合,或称为增强数组的数组。

本章将涵盖一些常见且强大的辅助函数,以及使用集合进行编程的基础知识。本节中的许多“辅助函数”曾经是全局函数,现在是门面的调用;array_first(),全局函数,已被Arr::first(),授权调用所取代。因此,虽然这些在技术上并非全部是全局函数,因为它们不再是全局函数,但它们在我们的工具箱中仍然占据同样的位置。

辅助函数

您可以在辅助文档中找到 Laravel 提供的所有辅助函数的完整列表,但我们将在此处介绍一些最有用的函数。

数组

PHP 的本地数组操作函数为我们提供了很多能力,但有时我们希望进行的标准操作需要笨拙的循环和逻辑检查。Laravel 的数组辅助函数使一些常见的数组操作变得更加简单:

Arr::first(*$array, $callback, $default = null*)

返回通过回调闭包定义的测试的第一个数组值。您可以选择将默认值设置为第三个参数。以下是一个例子:

$people = [
    [
        'email' => 'm@me.com',
        'name' => 'Malcolm Me'
    ],
    [
        'email' => 'j@jo.com',
        'name' => 'James Jo'
    ],
];

 $value = Arr::first($people, function ($person, $key) {
     return $person['email'] == 'j@jo.com';
 });

Arr::get(*$array, $key, $default = null*)

使从数组中获取值变得简单,具有两个附加好处:如果请求不存在的键,它不会抛出错误(并且您可以使用第三个参数提供默认值),并且您可以使用点表示法遍历嵌套数组。例如:

$array = ['owner' => ['address' => ['line1' => '123 Main St.']]];

$line1 = Arr::get($array, 'owner.address.line1', 'No address');
$line2 = Arr::get($array, 'owner.address.line2');

Arr::has(*$array, $keys*)

使用点表示法来遍历嵌套数组,轻松检查数组是否具有特定值设置。$keys参数可以是单个条目或条目数组,将检查数组中的每个条目是否存在:

$array = ['owner' => ['address' => ['line1' => '123 Main St.']]];

if (Arr::has($array, 'owner.address.line2')) {
    // Do stuff
}

Arr::hasAny(*$array, $keys*)

使用点表示法轻松检查数组是否具有指定键之一。$keys参数可以是单个键或键数组,将检查数组中是否存在任何键:

$array = ['owner' => ['address' => ['line1' => '123 Main St.']]];

if (Arr::hasAny($array, ['owner.address', 'default.address'])) {
    // Do stuff
}

Arr::pluck(*$array, $value, $key = null*)

返回与提供的键对应的值数组:

$array = [
    ['owner' => ['id' => 4, 'name' => 'Tricia']],
    ['owner' => ['id' => 7, 'name' => 'Kimberly']],
];

$array = Arr::pluck($array, 'owner.name');

// Returns ['Tricia', 'Kimberly'];

如果您希望返回的数组由源数组的另一个值键入,则可以将该值的点表示法引用作为第三个参数:

$array = Arr::pluck($array, 'owner.name', 'owner.id');

// Returns [4 => 'Tricia', 7 => 'Kimberly'];

Arr::random(*$array, $num = null*)

从提供的数组中返回一个随机项。如果提供了$num参数,则会随机选择那么多个结果的数组:

$array = [
    ['owner' => ['id' => 4, 'name' => 'Tricia']],
    ['owner' => ['id' => 7, 'name' => 'Kimberly']],
];

$randomOwner = Arr::random($array);

Arr::join(*$array, $glue, $finalGlue = ''*)

$array中的项目连接成一个字符串,在它们之间添加$glue。如果提供了$finalGlue,它将添加到数组的最后一个元素之前,而不是$glue

$array = ['Malcolm', 'James', 'Tricia', 'Kimberly'];

Arr::join($array, ', ');
// Malcolm, James, Tricia, Kimberly

Arr::join($array, ', ', ', and');
// Malcolm, James, Tricia, and Kimberly

字符串

就像使用数组一样,使用原生 PHP 函数可以进行一些字符串操作和检查,但这可能很麻烦。Laravel 的帮助函数使一些常见的字符串操作变得更快更简单:

e(*$string*)

htmlentities()的别名;准备(通常是用户提供的)字符串,以便在 HTML 页面上安全地回显。例如:

e('<script>do something nefarious</script>');

// Returns &lt;script&gt;do something nefarious&lt;/script&gt;

str(*$string*)

用于转换可字符串化对象;是Str::of(*$string*)的别名:

str('http') === Str::of('http');
// true

Str::startsWith(*$haystack, $needle*)Str::endsWith(*$haystack, $needle*)Str::contains(*$haystack, $needle, $ignoreCase*)

返回一个布尔值,指示提供的$haystack字符串是否以提供的$needle字符串开头、结尾或包含:

if (Str::startsWith($url, 'https')) {
    // Do something
}

if (Str::endsWith($abstract, '...')) {
    // Do something
}

if (Str::contains($description, '1337 h4x0r')) {
    // Run away
}

Str::limit(*$value, $limit = 100, $end = '...'*)

将字符串限制为提供的字符数。如果字符串的长度小于限制,则只返回字符串;如果大于,则修剪为提供的字符数,然后附加...或提供的$end字符串。例如:

$abstract = Str::limit($loremIpsum, 30);
// Returns "Lorem ipsum dolor sit amet, co..."

$abstract = Str::limit($loremIpsum, 30, "&hellip;");
// Returns "Lorem ipsum dolor sit amet, co&hellip;"

Str::words(*$value, $words = 100, $end = '...'*)

将字符串限制为提供的单词数。如果字符串的长度小于单词数,只返回字符串;如果大于,修剪为提供的单词数,然后附加...或提供的$end字符串。例如:

$abstract = Str::words($loremIpsum, 3);
// Returns "Lorem ipsum dolor..."

$abstract = Str::words($loremIpsum, 5, " &hellip;");
// Returns "Lorem ipsum dolor sit amet, &hellip;"

Str::before(*$subject, $search*)Str::after(*$subject, $search*)Str::beforeLast(*$subject, $search*)Str::afterLast(*$subject, $search*)

返回一个字符串的子字符串,在另一个字符串之前或之后,或最后一个实例之后。例如:

Str::before('Nice to meet you!', 'meet you');
// Returns "Nice to "

Str::after('Nice to meet you!', 'Nice');
// Returns " to meet you!"

Str::beforeLast('App\Notifications\WelcomeNotification', '\\');
// Returns "App\Notifications"

Str::afterLast('App\Notifications\WelcomeNotification', '\\');
// Returns "WelcomeNotification"

Str::is(*$pattern, $value*)

返回一个布尔值,指示给定字符串是否与给定模式匹配。该模式可以是正则表达式模式,或者你可以使用星号表示通配符位置:

Str::is('*.dev', 'myapp.dev');       // true
Str::is('*.dev', 'myapp.dev.co.uk'); // false
Str::is('*dev*', 'myapp.dev');       // true
Str::is('*myapp*', 'www.myapp.dev'); // true
Str::is('my*app', 'myfantasticapp'); // true
Str::is('my*app', 'myapp');          // true

如何将正则表达式传递给Str::is()

如果你想知道可以传递给Str::is()的正则表达式模式是什么,请查看这里的方法定义(空间有限,已简化)来了解它的工作原理:

public function is($pattern, $value)
{
    if ($pattern == $value) return true;

    $pattern = preg_quote($pattern, '#');
    $pattern = Str::replace('\*', '.*', $pattern);
    if (preg_match('#^'.$pattern.'\z#u', $value) === 1) {
        return true;
    }

    return false;
}

Str::isUuid(*$value*)

确定该值是否为有效的 UUID:

Str::isUuid('33f6115c-1c98-49f3-9158-a4a4376dfbe1'); // Returns true
Str::isUuid('laravel-up-and-running'); // Returns false

Str::random(*$length = n*)

返回指定长度的大小写混合字母数字随机字符串:

$hash = Str::random(64);
// Sample: J40uNWAvY60wE4BPEWxu7BZFQEmxEHmGiLmQncj0ThMGJK7O5Kfgptyb9ul wspmh

Str::slug(*$title, $separator = '-', $language = 'en'*)

从字符串中创建一个 URL 友好的 slug,通常用于为名称或标题创建 URL 段:

Str::slug('How to Win Friends and Influence People');
// Returns 'how-to-win-friends-and-influence-people'

Str::plural(*$value, $count = n*)

将字符串转换为其复数形式。该函数目前仅支持英语语言:

Str::plural('book');
// Returns books

Str::plural('person');
// Returns people

Str::plural('person', 1);
// Returns person

__(*$key, $replace = [], $locale = null*)

使用你的本地化文件翻译给定的翻译字符串或翻译键:

echo __('Welcome to your dashboard');

echo __('messages.welcome');

应用程序路径

当处理文件系统时,通常很繁琐为获取和保存文件创建链接到某些目录。这些助手函数让你快速访问到你的应用程序中一些最重要目录的完全限定路径。

请注意,这些函数可以不带参数调用,但如果传递参数,它将附加到正常目录字符串的末尾并作为整体返回:

app_path(*$append = ''*)

返回你的应用程序中app目录的路径:

app_path();
// Returns /home/forge/myapp.com/app

base_path(*$path = ''*)

返回你的应用程序根目录的路径:

base_path();
// Returns /home/forge/myapp.com

config_path(*$path = ''*)

返回你的应用程序中配置文件的路径:

config_path();
// Returns /home/forge/myapp.com/config

database_path(*$path = ''*)

返回你的应用程序中数据库文件的路径:

database_path();
// Returns /home/forge/myapp.com/database

storage_path(*$path = ''*)

返回你的应用程序中storage目录的路径:

storage_path();
// Returns /home/forge/myapp.com/storage

lang_path(*$path = ''*)

返回你的应用程序中lang目录的路径:

lang_path();
// Returns /home/forge/myapp.com/resources/lang

URLs

一些前端文件路径是一致的,但有时输入起来很烦人—例如,资源文件的路径—有方便的快捷方式对它们很有帮助,我们将在这里介绍。但是,一些路径实际上可能会变化,因此确保所有链接和资源正常工作的一些助手函数至关重要:

action(*$action*, *$parameters = []*, *$absolute = true*)

假设控制器方法只映射到一个 URL,根据控制器和方法名对(用@分隔)或使用元组表示法,返回正确的 URL:

<a href="{{ action('PersonController@index') }}">See all People</a>
// Or, using tuple notation:
<a href="{{ action(
 [App\Http\Controllers\PersonController::class, 'index']
 ) }}">
    See all People
</a>

// Returns <a href="http://myapp.com/people">See all People</a>

如果控制器方法需要参数,你可以将它们作为第二个参数传递(如果需要多个参数,则作为数组传递)。如果你想要清晰地标记它们,你可以给它们加上键,但重要的是它们按正确的顺序排列:

<a href="{{ action(
 'PersonController@show',
 ['id => 3]
 ) }}">See Person #3</a>
// or
<a href="{{ action(
 'PersonController@show',
 [3]
 ) }}">See Person #3</a

// Returns <a href="http://myapp.com/people/3">See Person #3</a>

如果将第三个参数传递为false,你的链接将生成为相对路径(/people/3)而不是绝对路径(*myapp.com/people/3*)。

route(*$name*, *$parameters = []*, *$absolute = true*)

如果路由有名称,返回该路由的 URL:

// routes/web.php
Route::get('people', [PersonController::class, 'index'])
    ->name('people.index');

// A view somewhere
<a href="{{ route('people.index') }}">See all People</a>

// Returns <a href="http://myapp.com/people">See all People</a>

如果路由定义需要参数,你可以将它们作为第二个参数传递(如果需要多个参数,则作为数组传递)。同样,如果你想要清晰地标记它们,你可以给它们加上键,但重要的是它们按正确的顺序排列:

<a href="{{ route('people.show', ['id' => 3]) }}">See Person #3</a>
// or
<a href="{{ route('people.show', [3]) }}">See Person #3</a>

// Returns <a href="http://myapp.com/people/3">See Person #3</a>

如果将第三个参数传递为false,你的链接将生成为相对路径而不是绝对路径。

url(*$string*)secure_url(*$string*)

给定任何路径字符串,转换为完全限定的 URL。(secure_url()url()相同,但强制使用 HTTPS):

url('people/3');

// Returns http://myapp.com/people/3

如果没有传递参数,这将返回一个Illuminate``\Routing``\UrlGenerator的实例,这样就可以进行方法链式调用:

url()->current();
// Returns http://myapp.com/abc

url()->full();
// Returns http://myapp.com/abc?order=reverse

url()->previous();
// Returns http://myapp.com/login

// And many more methods available on the UrlGenerator...

杂项

有一些其他全局助手我建议你熟悉一下。当然,你应该查看完整列表,但这里提到的几个绝对值得一看:

abort(*$code, $message, $headers*), abort_unless(*$boolean, $code, $message, $headers*), abort_if(*$boolean, $code, $message, $headers*)

抛出 HTTP 异常。abort()抛出定义的异常,abort_unless()在第一个参数为false时抛出异常,abort_if()在第一个参数为true时抛出异常:

public function controllerMethod(Request $request)
{
    abort(403, 'You shall not pass');
    abort_unless(request()->filled('magicToken'), 403);
    abort_if(request()->user()->isBanned, 403);
}

auth()

返回 Laravel 认证器的实例。像Auth门面一样,您可以使用它来获取当前用户,检查登录状态等:

$user = auth()->user();
$userId = auth()->id();

if (auth()->check()) {
   // Do something
}

back()

生成一个“重定向回上一页”的响应,将用户发送到先前的位置:

Route::get('post', function () {
    // ...

    if ($condition) {
        return back();
    }
});

collect(*$array*)

接受一个数组并返回相同数据,转换为集合:

$collection = collect(['Rachel', 'Hototo']);

我们稍后会讨论集合。

config(*$key*)

返回任何点表示的配置项的值:

$defaultDbConnection = config('database.default');

csrf_field(), csrf_token()

返回一个完整的 HTML 隐藏输入字段(csrf_field())或仅适当的令牌值(csrf_token()),用于向您的表单提交添加 CSRF 验证:

<form>
    {{ csrf_field() }}
</form>

// or

<form>
    <input type="hidden" name="_token" value="{{ csrf_token() }}">
</form>

dump(*$variable*), dd(*$variable*...)

对所有提供的参数运行类似于var_dump()的输出;dd()还会运行exit()来退出应用程序(这用于调试):

// ...
dump($var1, $var2); // Check the output...
// ...
dd($var1, $var2, $state); // Why is this not working???

env(*$key*, *$default = null*)

返回给定键的环境变量:

$key = env('API_KEY', '');

请记住,在配置文件之外绝不要使用env()

dispatch(*$job*)

分派一个作业:

dispatch(new EmailAdminAboutNewUser($user));

event(*$event*)

触发一个事件:

event(new ContactAdded($contact));

old(*$key = null*, *$default = null*)

返回此表单键的上次用户表单提交的旧值(如果存在):

<input name="name" value="{{ old('value', 'Your name here') }}"

redirect(*$path*)

返回到给定路径的重定向响应:

Route::get('post', function () {
    // ...

    return redirect('home');
});

没有参数时,生成Illuminate\Routing\Redirector类的实例。

response(*$content*, *$status = 200*, *$headers*)

如果传入参数,则返回预先构建的Response实例。如果没有参数,则返回Response工厂的实例:

return response('OK', 200, ['X-Header-Greatness' => 'Super great']);

return response()->json(['status' => 'success']);

tap(*$value*, *$callback = null*)

调用闭包(第二个参数),传递第一个参数给闭包,然后返回第一个参数(而不是闭包的输出):

return tap(Contact::first(), function ($contact) {
    $contact->name = 'Aheahe';
    $contact->save();
});

view(*$viewPath*)

返回视图实例:

Route::get('home', function () {
    return view('home'); // Gets /resources/views/home.blade.php
});

fake()

返回一个 Faker 的实例:

@for($i = 0; $i <= 4; $i++)
    <td>Purchased by {{ fake()->unique()->name() }}</td>
@endfor

集合

集合是 Laravel 提供的最强大但最不被赞赏的工具之一。我们在“Eloquent Collections”中稍作介绍,但这里快速回顾一下。

集合本质上是具有超能力的数组。您通常需要将数组传递给的数组遍历方法(array_walk()array_map()array_reduce()等)都可以作为每个集合上一致、清晰、可链式调用的方法使用。您可以尝试使用函数式编程,通过 map、reduce 和 filter 实现更清晰的代码。

我们将在这里讨论 Laravel 集合和集合管道编程的基础知识,但要深入了解,请查看 Adam Wathan 的书《Refactoring to Collections》(Gumroad)。

基础知识

Laravel 中的集合并不是一个新概念。许多语言默认支持数组的集合式编程,但在 PHP 中我们就没那么幸运了。

使用 PHP 的 array*() 函数,我们可以将 示例 17-1 中显示的混乱怪物转换为稍微不那么混乱的怪物,如 示例 17-2 所示。

示例 17-1. 一个常见但丑陋的 foreach 循环
$users = [...];

$admins = [];

foreach ($users as $user) {
    if ($user['status'] == 'admin') {
        $user['name'] = $user['first'] . ' ' . $user['last'];
        $admins[] = $user;
    }
}

return $admins;
示例 17-2. 使用原生 PHP 函数重构 foreach 循环
$users = [...];

return array_map(function ($user) {
    $user['name'] = $user['first'] . ' ' . $user['last'];
    return $user;
}, array_filter($users, function ($user) {
    return $user['status'] == 'admin';
}));

在这里,我们去掉了一个临时变量($admins),并将一个令人困惑的 foreach 循环转换为两个明确的操作:map 和 filter。

问题在于,PHP 的数组操作函数令人困惑且糟糕。只需看看这个例子;array_map() 先接受闭包,再接受数组,但 array_filter() 先接受数组,再接受闭包。此外,如果我们增加了任何复杂性,就会有函数嵌套函数嵌套函数的情况。真是一团糟。

Laravel 的集合将 PHP 的数组操作方法的强大之处与简洁流畅的语法结合起来,并添加了许多甚至在 PHP 的数组操作工具箱中不存在的方法。使用 collect() 辅助方法将数组转换为 Laravel 集合后,我们可以像 示例 17-3 中展示的那样操作。

示例 17-3. 使用 Laravel 集合重构 foreach 循环
$users = collect([...]);

return $users->filter(function ($user) {
    return $user['status'] == 'admin';
})->map(function ($user) {
    $user['name'] = $user['first'] . ' ' . $user['last'];
    return $user;
});

这并不是最极端的例子。还有很多其他例子,减少代码行数和增加简单性会更加强有力。但这种情况非常常见

看看原始示例及其混乱的情况。除非你完全理解整个代码样本,否则不会完全清楚任何给定部分的用途。

集合提供的最大好处是,相比其他任何方法,它将操作数组的行为分解为简单、明确和可理解的任务。现在你可以像这样做:

$users = [...]
$countAdmins = collect($users)->filter(function ($user) {
    return $user['status'] == 'admin';
})->count();

或者像这样:

$users = [...];
$greenTeamPoints = collect($users)->filter(function ($user) {
    return $user['team'] == 'green';
})->sum('points');

在本章的其余部分中,我们将看到许多例子都是基于我们在这里开始想象的虚构的 $users 集合。$users 数组中的每个条目都代表一个单独的人类;它们可能都可以通过数组访问。每个用户具体的属性可能会根据示例有所不同。但是无论何时看到这个 $users 变量,都知道这是我们正在处理的内容。

几个集合操作

比我们迄今为止涵盖的还要多得多。我建议您查看Laravel 集合文档以了解更多可用的方法,但为了帮助您入门,这里只列出了一些核心方法:

all(), toArray()

如果你想将集合转换为数组,可以使用all()toArray()toArray()不仅将集合转换为数组,还会将其下面的任何 Eloquent 对象扁平化为数组。all()仅将集合转换为数组;集合中包含的任何 Eloquent 对象将保持为 Eloquent 对象。以下是一些示例:

$users = User::all();

$users->toArray();

/* Returns
 [
 ['id' => '1', 'name' => 'Agouhanna'],
 ...
 ]
*/

$users->all();

/* Returns
 [
 Eloquent object { id : 1, name: 'Agouhanna' },
 ...
 ]
*/

filter(), reject()

当你想通过检查每个项目是否符合闭包来获取原始集合的一个子集时,你将使用filter()(如果闭包返回true则保留项目)或reject()(如果闭包返回false则保留项目):

$users = collect([...]);
$admins = $users->filter(function ($user) {
    return $user->isAdmin;
});

$paidUsers = $user->reject(function ($user) {
    return $user->isTrial;
});

where()

where()使得提供原始集合的一个子集变得容易,其中给定键等于给定值。你可以用where()做的任何事情也可以用filter(),但它是一个常见情景的快捷方式:

$users = collect([...]);
$admins = $users->where('role', 'admin');

whereNull(), whereNotNull()

whereNull()使得提供原始集合的一个子集变得容易,其中给定键等于nullwhereNotNull()则是其反义:

$users = collect([...]);
$active = $users->whereNull('deleted_at');
$deleted = $users->whereNotNull('deleted_at');

first(), last()

如果你只想从集合中获取单个项目,可以使用first()来获取列表的开头或last()来获取列表的末尾。

如果你调用first()last()而没有参数,它们只会分别给出集合中的第一个或最后一个项目。但如果你传递一个闭包,它们将会给出集合中首个或最后一个在该闭包中返回true的项目。

有时你会这样做是因为你想要实际的第一个或最后一个项目。但有时这是获取一个项目的最简单方法,即使你只期望有一个项目:

$users = collect([...]);
$owner = $users->first(function ($user) {
    return $user->isOwner;
});

$firstUser = $users->first();
$lastUser = $users->last();

你还可以向每种方法传递第二个参数,即默认值,如果闭包没有提供任何结果,将作为后备提供。

each()

如果你想对集合的每个项目执行某些操作,但不包括修改项目或集合本身,则可以使用each()

$users = collect([...]);
$users->each(function ($user) {
    EmailUserAThing::dispatch($user);
});

map()

如果你想遍历集合中的所有项目,对它们进行更改,并返回带有所有更改的新集合,你应该使用map()

$users = collect([...]);
$users = $users->map(function ($user) {
    return [
        'name' => $user['first'] . ' ' . $user['last'],
        'email' => $user['email'],
    ];
});

reduce()

如果你想从集合中获取单个结果,如计数或字符串,你可能想使用reduce()。该方法通过采用初始值(称为carry)并允许集合中的每个项目以某种方式改变该值来工作。你可以为carry定义一个初始值,并接受当前carry状态和每个项目作为参数的闭包:

$users = collect([...]);

$points = $users->reduce(function ($carry, $user) {
    return $carry + $user['points'];
}, 0); // Start with a carry of 0

pluck()

如果你想要仅获取集合中每个项目下给定键的值,可以使用pluck()

$users = collect([...]);

$emails = $users->pluck('email')->toArray();

chunk(), take()

chunk()使得将集合分割成预定义大小的组变得容易,take()则仅获取指定数量的项目:

$users = collect([...]);

$rowsOfUsers = $users->chunk(3); // Separates into groups of 3

$topThree = $users->take(3); // Pulls the first 3

takeUntil(), takeWhile()

takeUntil() 返回集合中直到回调函数返回 true 的所有项目。takeWhile() 返回集合中直到回调函数返回 false 的所有项目。如果传递给 takeUntil() 的回调函数从未返回 true,或者传递给 takeWhile() 的回调函数从未返回 false,则返回整个集合:

$items = collect([1, 2, 3, 4, 5, 6, 7, 8, 9]);

$subset = $items->takeUntil(function ($item) {
    return $item >= 5;
})->toArray();
// [1, 2, 3, 4]

$subset = $items->takeWhile(function ($item) {
    return $item < 4;
})->toArray();
// [1, 2, 3]

groupBy()

如果你想要根据它们的某个属性值将所有项目分组到你的集合中,你可以使用 groupBy()

$users = collect([...]);

$usersByRole = $users->groupBy('role');

/* Returns:
 [
 'member' => [...],
 'admin' => [...],
 ]
*/

你也可以传递一个闭包,闭包返回的内容将用于分组记录:

$heroes = collect([...]);

$heroesByAbilityType = $heroes->groupBy(function ($hero) {
    if ($hero->canFly() && $hero->isInvulnerable()) {
        return 'Kryptonian';
    }

    if ($hero->bitByARadioactiveSpider()) {
        return 'Spidermanesque';
    }

    if ($hero->color === 'green' && $hero->likesSmashing()) {
        return 'Hulk-like';
    }

    return 'Generic';
});

reverse()shuffle()

reverse() 将你的集合中项目的顺序反转,而 shuffle() 将它们随机化:

$numbers = collect([1, 2, 3]);

$numbers->reverse()->toArray(); // [3, 2, 1]
$numbers->shuffle()->toArray(); // [2, 3, 1]

skip()

skip() 返回一个新的集合,其中不包括指定数量的项目:

$numbers = collect([1, 2, 3, 4, 5]);

$numbers->skip(3)->values(); // [4, 5]

skipUntil()

skipUntil() 跳过项目直到回调函数返回 true。你也可以传递一个值给 skipUntil,它将跳过所有值,直到找到给定的值。如果值从未找到或回调从未返回 true,则返回一个空集合:

$numbers = collect([1, 2, 3, 4, 5]);

$numbers->skipUntil(function ($item) {
    return $item > 3;
})->values();
// [4, 5]

$numbers->skipUntil(3)->values();
// [3, 4, 5]

skipWhile()

skipWhile() 跳过项目直到回调函数返回 true。如果回调从未返回 false,则返回一个空集合:

$numbers = collect([1, 2, 3, 4, 5]);

$numbers->skipWhile(function ($item) {
    return $item <= 3;
})->toArray();
// [4, 5]

sort()sortBy()sortByDesc()

如果你的项目是简单的字符串或整数,你可以使用 sort() 来对它们进行排序:

$sortedNumbers = collect([1, 7, 6])->sort()->toArray(); // [1, 6, 7]

如果它们更复杂,你可以将一个字符串(表示属性)或闭包传递给 sortBy()sortByDesc() 来定义你的排序行为:

$users = collect([...]);

// Sort an array of users by their 'email' property
$users->sort('email');

// Sort an array of users by their 'email' property
$users->sortBy(function ($user, $key) {
    return $user['email'];
});

countBy()

countBy 计算集合中每个值的每次出现:

$collection = collect([10, 10, 20, 20, 20, 30]);

$collection->countBy()->all();

// [10 => 2, 20 => 3, 30 => 1]

结果集合中的每个键都是原始值之一;它的配对值是该值在原始集合中出现的次数。

countBy 方法还接受一个回调函数,用于自定义用于计算集合中每个项目的值:

$collection = collect(['laravel.com', 'tighten.co']);

$collection->countBy(function ($address) {
    return Str::after($address, '.');
})->all();

// all: ["com" => 1, "co" => 1]

count()isEmpty()isNotEmpty()

你可以使用 count()isEmpty()isNotEmpty() 来查看集合中有多少项目:

$numbers = collect([1, 2, 3]);

$numbers->count();   // 3
$numbers->isEmpty(); // false
$numbers->isNotEmpty() // true

avg()sum()

如果你正在处理一组数字的集合,avg()sum() 就像它们的方法名所说的那样工作,不需要任何参数:

collect([1, 2, 3])->sum(); // 6
collect([1, 2, 3])->avg(); // 2

但如果你正在处理数组,你可以将每个数组中要提取的属性的键传递给操作:

$users = collect([...]);

$sumPoints = $users->sum('points');
$avgPoints = $users->avg('points');

join

join() 将集合值连接为单个输出字符串,使用提供的字符串连接每个值,类似于 PHP 的 join() 方法。你也可以(可选地)自定义最终的连接操作符:

$collection = collect(['a', 'b', 'c', 'd', 'e']);
$collection->join(', ', ', and ');

// 'a, b, c, d, and e'

在 Laravel 之外使用集合

你是否已经爱上了集合,并想在你的非 Laravel 项目中使用它们?

只需使用 composer require illuminate/collections 命令,你就可以在你的代码中准备好 Illuminate\S⁠u⁠p⁠p⁠o⁠r⁠t⁠\​C⁠o⁠l⁠l⁠e⁠c⁠t⁠i⁠o⁠n 类,以及 collect() 辅助函数。

简而言之

Laravel 提供了一套全局助手函数,简化各种任务。它们使得操作和检查数组和字符串变得更加容易,方便生成路径和 URL,并提供简单访问一些持久和关键功能。

Laravel 的集合(collections)是强大的工具,为 PHP 带来了集合管道的可能性。

第十八章:Laravel 生态系统

随着 Laravel 的发展,Laravel 团队构建了一套工具来支持和简化 Laravel 开发人员的生活和工作流程。许多新工作已直接进入核心,但还有很多包和 SaaS 提供并不是核心的一部分,但仍然是 Laravel 经验的重要组成部分。

我们已经涵盖了其中相当多的内容,对于那些内容,我将提供指向书中更多信息的指针。对于我们尚未涵盖的工具,我将简要描述每个工具,并提供相关网站的链接。

本书中涵盖的工具

我们已经浏览过这些内容,但这里是它们的简要提醒以及您可以找到相关资源的链接。

Valet

Valet 是一个本地开发服务器(适用于 Mac,并有适用于 Windows 和 Linux 的分支),使得将所有项目快速轻松地提供给浏览器变得非常简单。您将通过 Composer 在本地开发机器上全局安装 Valet。

只需几个命令,您就可以在 *.test* 域上为您机器上的每个 Laravel 应用程序提供 Nginx、MySQL、Redis 等服务。

Valet 是在 “Laravel Valet” 中介绍的。

Homestead

Homestead 是在一个简单的 Vagrant 设置之上的配置层,使得从一个 Laravel 友好的 Vagrant 设置中服务多个 Laravel 应用程序变得简单。

Homestead 是在 “Laravel Homestead” 中简要介绍的。

Herd

Herd 是一个原生的 macOS 应用程序,将 Valet 及其依赖项打包成一个单独的应用程序,您可以在其中安装,无需处理 Docker、Homebrew 或任何其他依赖管理器。

Herd 是在 “Laravel Herd” 中介绍的。

Laravel 安装程序

Laravel 安装程序是一个全局安装在您的本地开发机器上(通过 Composer 安装),它可以轻松快速地设置一个新的 Laravel 项目。

安装程序是在 “使用 Laravel 安装程序工具安装 Laravel” 中介绍的。

Dusk

Dusk 是一个用于测试整个应用程序(包括 JavaScript 等)的前端测试框架。它是一个强大的包,您可以通过 Composer 将其引入您的应用程序,并通过 ChromeDriver 驱动实际的浏览器。

Dusk 是在 “使用 Dusk 进行测试” 中介绍的。

Passport

Passport 是一个强大而简单易用的 OAuth 2.0 服务器,用于为客户端身份验证您的 API。您将在每个应用程序中安装它作为一个 Composer 包,并且只需很少的工作,就可以为您的用户提供完整的 OAuth 2.0 流程。

Passport 是在 “使用 Laravel Passport 进行 API 认证” 中介绍的。

Sail

Sail 是由 Docker 驱动的 Laravel 默认的本地开发环境。

Sail 是在 “Laravel Sail” 中介绍的。

Sanctum

Sanctum 是一个用于支持移动应用程序、SPA 和简单基于令牌的 API 的身份验证系统。它是复杂的 OAuth 的一个简化但仍然功能强大的替代方案。

Sanctum 被介绍在“API Authentication with Sanctum”中。

Fortify

Fortify 是一个无头身份验证系统。它为 Laravel 需要的所有身份验证功能提供了路由和控制器,从登录和注册到密码重置等等,可供任何你选择的前端消费。

Fortify 被介绍在“Fortify”中。

Breeze

Breeze 是所有 Laravel 必需身份验证功能的最小路由和控制器集合,并与每个功能配套的前端模板。Breeze 可以通过 Blade、Vue、React 或 Inertia 提供。

Breeze 被介绍在“Laravel Breeze”中。

Jetstream

Jetstream 是一个强大的应用程序启动套件,提供了 Breeze 提供的所有身份验证功能,以及电子邮件验证、双因素身份验证、会话管理、API 身份验证和团队管理功能。与 Breeze 不同,Jetstream 仅提供两种前端工具选择:Livewire 和 Inertia/Vue。

Jetstream 被介绍在“Laravel Jetstream”中。

Horizon

Horizon 是一个可以通过 Composer 安装到每个应用程序中的队列监控包。它为监控 Redis 队列作业的健康状况、性能、失败和历史提供了完整的用户界面。

Horizon 简要介绍了“Laravel Horizon”。

Echo

Echo 是一个 JavaScript 库(随着 Laravel 通知系统的一系列改进而引入),使得通过 WebSockets 订阅来自你的 Laravel 应用的事件和频道变得简单。

Echo 被介绍在“Laravel Echo (the JavaScript Side)”中。

本书未涉及的工具

本书未涉及的一些工具,因为它们超出了本书的范围。其中一些只用于特殊情况(例如用于支付的 Cashier,用于社交登录的 Socialite 等),但有些我每天都在使用(尤其是 Forge)。

下面是一个简要介绍,从你在工作中最可能遇到的工具开始。请注意,这个列表并不详尽!

Forge

Forge 是一款付费的 SaaS 工具,用于在 DigitalOcean、Linode、AWS 等主机上创建和管理虚拟服务器。它为你提供了一切运行所需的工具,从队列和队列工作者到 Let’s Encrypt SSL 证书。此外,它还可以设置简单的 Shell 脚本,以在你将新代码推送到 GitHub 或 Bitbucket 时自动部署你的站点。

Forge 在快速轻松地启动站点方面非常有用,但它并不是如此简单,你无法在长期或更大规模上也运行你的应用程序。你可以扩展你的服务器大小,添加负载均衡器,并在 Forge 内管理服务器之间的私有网络。

Vapor

Vapor 是一个付费的 SaaS 工具,用于将 Laravel 应用程序部署到 AWS Lambda,使用“无服务器”托管模式。它管理缓存、队列、数据库、资源构建、域指向、自动缩放、内容传递网络、环境管理以及大多数您将需要为 Laravel 应用程序进行无服务器部署的任何其他事项。

Envoyer

Envoyer 是一个付费的 SaaS 工具,被称为“零停机 PHP 部署”。与 Forge 不同,Envoyer 不会启动或管理您的服务器。它的主要任务是监听触发器,通常是在推送新代码时,但您也可以手动触发部署或通过 Webhook 触发。

Envoyer 在以下三个方面远远优于 Forge 的推送部署工具和大多数其他推送部署解决方案:

  • 它具有强大的工具集,可以构建简单但强大的多阶段部署流程。

  • 它使用类似 Capistrano 的零停机部署方式部署您的应用程序;每个新部署都构建到自己的文件夹中,只有在构建过程成功完成后,才将该部署文件夹的符号链接到您的实际 Web 根目录。因此,在 Composer 安装或 NPM 构建时,服务器不会出现中断。

  • 由于这种基于文件夹的系统,可以轻松快速地回滚到以前的版本;Envoyer 只需将符号链接更新回以前的部署文件夹,即可立即提供旧版本的服务。

您还可以设置定期健康检查(对您的服务器进行 ping 测试,如果 ping 测试未返回 200 HTTP 响应,则向您报告错误),期望您的 cron 作业将定期向 Envoyer 发送 ping,并基于聊天的方式通知任何重要事件。

Envoyer 比 Forge 更像一个专业工具。我不认识很多 Laravel 开发者不使用 Forge,但那些愿意支付使用 Envoyer 的人更可能拥有如果不能立即回滚问题提交或者网站流量(或者重要的流量)足够大而会有很多问题的网站。如果您的网站属于这一类别,Envoyer 会让您感到像魔法一样。

Cashier

Cashier 是一个免费的包,提供了一个简单的界面,用来管理 Stripe 的订阅计费服务。Cashier 处理订阅用户的大部分基本功能,包括更改他们的计划、提供访问发票、处理来自计费服务的 Webhook 回调、管理取消宽限期等等。

如果你想让用户使用 Stripe 进行订阅注册,Cashier 会让你的生活变得轻松得多。

Socialite

Socialite 是一个免费的包,使得向您的应用程序添加社交登录变得非常简单(例如通过 GitHub 或 Facebook)。

Nova

Nova是一个付费包,用于构建管理面板。如果想象一下您平均复杂的 Laravel 应用程序,可能会有几个部分:公共面向客户的网站或视图、用于对核心数据或客户列表进行更改的管理部分,甚至可能还有一个 API。

Nova 极大地简化了使用 Vue 和 Laravel API 构建站点管理面板部分的过程。它可以轻松生成所有资源的 CRUD(创建、读取、更新、删除)页面,以及针对数据的更复杂的自定义视图、每个资源上的自定义操作和关系,甚至用于向相同的一般管理空间添加非 CRUD 工具的自定义工具。

Spark

Spark是一个付费包,用于生成接受付款的 SaaS,并且简化用户、团队和订阅的管理。它提供了 Stripe 和 Paddle 集成、发票、基于座位或团队的计费以及完整的独立计费门户,使您不必受限于 Spark 的默认技术栈。

Envoy

Envoy是一个本地任务运行程序,可以轻松定义将在远程服务器上运行的常见任务,将这些任务的定义提交到版本控制,并简单而可预测地运行它们。

查看示例 18-1 以了解常见 Envoy 任务的样子。

示例 18-1. 一个常见的 Envoy 任务
@servers(['web-1' => '192.168.1.1', 'web-2' => '192.168.1.2'])

@task('deploy', ['on' => ['web-1', 'web-2']])
    cd mysite.com
    git pull origin {{ $branch }}
    php artisan migrate
    php artisan route:cache
@endtask

要运行示例 18-1,请在本地终端中运行以下命令:

envoy run deploy --branch=master

望远镜

望远镜是一个免费的调试工具,可以作为 Laravel 应用程序的包安装。它生成一个仪表板,您可以深入了解作业的当前状态、队列工作者、HTTP 请求、数据库查询等等。

Octane

Octane是一个免费工具,使您能够使用异步、并发的 PHP Web 服务器为您的 Laravel 应用程序提供服务,旨在提供速度和性能。在撰写本书时,有三种这样的工具:Swoole、Open Swoole 和 RoadRunner。使用 Octane,这些工具将一次性加载您的应用程序到内存中,然后以最高效的方式为每个请求提供服务,利用语言和系统级工具来实现并发。

Pennant

Pennant是 Laravel 本地实现的“特性标志”模式,允许您轻松定义每个请求是否应在您的应用程序中看到某个特性—通常是因为请求的用户及其访问权限。Pennant 允许您一次性定义应用哪些指标用于确定是否应该为给定特性服务请求,提供了与 Laravel 访问控制列表层非常相似的语法。

Folio

Folio 是一个 Laravel 包,允许您基于文件夹中模板文件的排列来构建应用程序的路由。类似于 Next 和 Nuxt,Folio 允许您创建单独的模板(例如 /index.blade.php 显示在 mysite.com//about.blade.php 显示在 mysite.com/about/users/index.blade.php 显示在 mysite.com/users),或者定义应与 URL 中占位符匹配的模板(例如 /users/[id].blade.php 显示在 mysite.com/users/14)。

Volt

Volt 使用单文件功能组件扩展 Livewire 的功能。Volt 还提供了一个指令 @volt,允许您将模板的一部分分配给 Livewire 组件定义管理,同时模板的其余部分仍然是普通的 Blade。

Pint

Pint 是一个代码风格工具,旨在在你的应用程序中强制执行 Laravel 的默认代码风格。它基于 PHP-CS-Fixer 构建,并提供了一些工具改进,同时还提供了预配置的 Laravel 特定代码规则集。

其他资源

我已经提到了很多资源,但这里是一些人们经常转向学习 Laravel 的资源的非详尽列表:

有许多博客(我在 mattstauffer.com 有一个,Tighten 在 tighten.com 也有一个,还有许多其他非常有用的),许多优秀的 Twitter 用户,许多出色的包作者,以及太多我尊重但无法在这里列出的 Laravel 开发者。这是一个富有多样性和慷慨的社区,充满了乐于分享一切他们学到的开发者;难的不是找到好内容,而是找到时间去消化这一切。

作为 Laravel 开发者的旅程中可能遇到的每一个人或资源我无法一一列举,但如果你从这里列出的资源和人士开始,你将在使用 Laravel 方面迈出良好的第一步。

第十九章:术语表

访问器

在 Eloquent 模型上定义的一种方法,用于自定义如何返回给定属性。访问器使得可以定义从模型获取给定属性将返回与数据库中存储的值不同(或者更可能是格式不同)的值。

ActiveRecord

一种常见的数据库 ORM 模式,也是 Laravel 的 Eloquent 使用的模式。在 ActiveRecord 中,同一个模型类定义了如何检索和持久化数据库记录以及如何表示它们。此外,每个数据库记录由应用程序中的单个实体表示,而每个应用程序中的实体都映射到单个数据库记录。

API

技术上称为应用程序编程接口,但最常用来指一系列端点(及其使用方法说明),可以用于通过 HTTP 调用来读取和修改系统外部数据。有时,API 这个术语也用来描述任何给定包、库或类公开给其消费者的接口或便利。

应用程序测试

应用测试通常被称为验收或功能测试,它们测试应用程序的整体行为,通常在外部边界,通过使用诸如 DOM 爬虫之类的工具,这正是 Laravel 应用测试套件提供的功能。

参数(Artisan)

参数是可以传递给 Artisan 控制台命令的参数。参数不以--开头,也不跟着=, 而是只接受一个单一值。

Artisan

这个工具使得可以从命令行与 Laravel 应用程序进行交互。

断言

在测试中,断言是测试的核心:你断言某些东西应该等于(或小于或大于)其他某些东西,或者应该具有给定的数量,或者任何其他你喜欢的条件。断言是可以通过或失败的事物。

认证

正确地确认自己作为应用程序的成员/用户的身份是认证的行为。认证并不定义你可以做什么,而只是你是谁(或者不是谁)。

授权

假设你已经通过身份验证(或者未通过),授权定义了根据你的特定身份标识,你能够允许做什么。授权涉及访问和控制。

自动装配

当一个依赖注入容器将一个可解析类的实例注入而开发人员并没有显式地告诉它如何解析该类时,这被称为自动装配。对于没有自动装配的容器,你甚至不能注入一个没有依赖关系的纯 PHP 对象,直到你明确地将它绑定到容器中。通过自动装配,你只需要在容器中明确绑定某些东西,如果它的依赖关系对容器来说太复杂或者太模糊,容器无法自行解决。

beanstalkd

Beanstalk 是一个工作队列。它简单且擅长运行多个异步任务—这使得它成为 Laravel 队列的常用驱动程序。beanstalkd 是它的守护进程。

Blade

Laravel 的模板引擎。

Carbon

一个使得与日期工作更加轻松和表达力更强的 PHP 包。

Cashier

Laravel 的一个包,使得与 Stripe 或 Braintree 的计费特别在订阅上下文中更加简单、一致、强大。

闭包

闭包是 PHP 版本的匿名函数。闭包是一个可以像对象一样传递、分配给变量、作为参数传递给其他函数和方法,甚至可以序列化的函数。

CodeIgniter

一个旧的 PHP 框架,Laravel 的灵感来源。

集合

一个开发模式的名称,也是 Laravel 实现它的工具。像增强版数组一样,集合提供了 map、reduce、filter 等许多强大的操作,PHP 的原生数组没有这些功能。

命令

自定义 Artisan 控制台任务的名称。

Composer

PHP 的依赖管理器。类似于 RubyGems 或 NPM。

容器

在 Laravel 中,“容器”是指负责依赖注入的应用程序容器。通过app()访问,也负责解析对控制器、事件、作业和命令的调用,容器是将每个 Laravel 应用粘合在一起的关键。

契约

接口的另一个名称。

控制器

一个负责将用户请求路由到应用程序服务和数据,并向用户返回有用响应形式的类。

CSRF(跨站请求伪造)

一种恶意攻击,外部站点通过劫持用户的浏览器(通常使用 JavaScript)在用户仍然登录到您的站点时对您的应用程序发出请求。通过在站点上的每个表单中添加令牌(以及在POST端检查该令牌),可以防止这种攻击。

依赖注入

一种开发模式,依赖项从外部注入—通常通过构造函数—而不是在类中实例化。

指令

Blade 语法选项,如@if@unless等。

点符号表示法

使用.向下导航继承树,引用跳转到新层级。如果你有一个数组['owner' => ['address' => ['line1' => '123 Main St.']]],你有三层嵌套。使用点表示法,你可以将“123 Main St.”表示为"owner.address.line1"

Dusk

Laravel 的前端测试包,可以通过启动 ChromeDriver 运行测试,测试 JavaScript(主要是 Vue)和 DOM 交互。

预加载

通过在第一个查询中添加第二个智能查询来避免 N+1 问题,以获取一组相关项目。通常,您有一个第一个查询来获取一组 A 的集合。但是每个 A 都有许多 B,因此每次从 A 获取 B 时,您需要一个新的查询。急切加载意味着执行两个查询:首先获取所有 A,然后获取所有这些 A 相关的 所有 B,在单个查询中完成。两个查询,搞定。

Echo

Laravel 产品,使 WebSocket 身份验证和数据同步变得简单。

Eloquent

Laravel 的 ActiveRecord ORM。您将用这个工具定义和查询诸如 User 模型之类的内容。

环境变量

.env 文件中定义的变量,预期不包含在版本控制中。这意味着它们在环境之间不同步,同时也保持安全。

Envoy

Laravel 包,用于编写在远程服务器上运行常见任务的脚本。Envoy 提供了定义任务和服务器的语法,以及用于运行任务的命令行实用程序。

Envoyer

Laravel 的 SaaS 产品,用于零停机时间部署、多服务器部署以及服务器和 cron 健康检查。

事件

Laravel 的工具,用于实现发布/订阅或观察者模式。每个事件表示发生了某个事件:事件的名称描述了发生了什么(例如,UserSubscribed),载荷允许附加相关信息。设计为“触发”然后“监听”(或者按照发布/订阅的概念发布和订阅,如果你更喜欢这种方式)。

外观

Laravel 中用于简化访问复杂工具的工具。外观为 Laravel 核心服务提供静态访问。由于每个外观都由容器中的类支持,因此您可以将对 Cache::put(); 的调用替换为对 $cache = app('cache'); $cache->put(); 的两行调用。

Faker

一个 PHP 包,使生成随机数据变得简单。您可以请求不同类别的数据,如名称、地址和时间戳。

标志

一个参数,可以是开或关(布尔值)。

流畅

可以一个接一个地链接的方法称为流畅方法。为了提供流畅的语法,每个方法必须返回实例,准备好再次链接。这允许类似于 People::where('age', '>' , 14)->orderBy('name')->get() 这样的操作。

Flysystem

Laravel 用于促进其本地和云文件访问的包。

Forge

Laravel 产品,可以轻松在 DigitalOcean 和 AWS 等主要云提供商上快速创建和管理虚拟服务器。

Fortify

无头后端身份验证系统,提供 Laravel 所有重要身份验证系统的路由和控制器。

FQCN(完全限定类名)

任何给定类、特征或接口的完全命名空间名称。Controller 是类名;Illuminate\Routing\Controller 是完全限定类名。

辅助函数

全局可访问的 PHP 函数(或在 Laravel 中有时是全局可访问的外观调用),可以使其他功能更加简单。

Homestead

Laravel 的工具,封装了 Vagrant,并简化了在本地 Laravel 开发中启动 Forge-并行虚拟服务器的过程。

Horizon

Laravel 包,提供更细致管理队列的工具,比 Laravel 默认的更加深入,并提供队列工作者及其作业的当前和历史操作状态的洞察。

HTTP 客户端

Laravel 内置的 HTTP 客户端,提供向其他 Web 应用程序发出出站请求的能力。

Illuminate

Laravel 组件的所有顶级命名空间。

集成测试

集成测试测试单个单元如何协同工作并传递消息。

IoC(控制反转)

将如何创建接口的具体实例的“控制”权交给包的高级代码而不是低级代码的概念。没有 IoC,每个控制器和类可能都会决定要创建哪个 Mailer 的实例。IoC 使得低级代码——这些控制器和类——只需请求一个 Mailer,一些高级配置代码就会定义每个应用程序一次提供哪个实例来满足请求。

job

意图封装单一任务的类。作业旨在能够推送到队列并异步运行。

JSON(JavaScript 对象表示法)

数据表示的语法。

JWT(JSON Web Token)

包含确定用户身份验证状态和访问权限所需所有信息的 JSON 对象。此 JSON 对象经过数字签名,这就是其可信的原因,使用 HMAC 或 RSA。通常在标头中传递。

mailable

一种旨在将发送邮件的功能封装到一个“可发送”类中的架构模式。

Markdown

一种设计用于格式化纯文本并输出到多种格式的格式化语言。通常用于格式化可能由脚本处理或以其原始形式被人类阅读的文本,例如 Git 的 README。

大量赋值

一次性传递多个参数来创建或更新 Eloquent 模型,使用一个键控数组。

Memcached

旨在提供简单但快速数据存储的内存中数据存储。Memcached 仅支持基本的键/值存储。

中间件

围绕应用程序的一系列包装器,过滤和装饰其输入和输出。

迁移

存储在代码中并从中运行的对数据库状态的操作。

Mockery

Laravel 自带的一个库,可以在测试中轻松模拟 PHP 类。

模型

用于表示系统中给定数据库表的类。在像 Laravel 的 Eloquent 这样的 ActiveRecord ORM 中,此类用于表示系统中的单个记录,并与数据库表交互。

模型工厂

用于定义应用程序如何在需要时生成模型实例的工具。通常与像 Faker 这样的假数据生成器配对使用。

多租户

一个应用程序为多个客户提供服务,每个客户都有自己的客户。多租户通常意味着应用程序的每个客户都可以获得自己的主题和域名,以便通过您的其他客户的潜在服务来区分其向客户提供的服务。

修改器

Eloquent 中的工具,允许您在保存到数据库之前操纵要保存到模型属性的数据。

Nginx

一种类似 Apache 的 Web 服务器。

通知

Laravel 框架工具,允许通过多种通知渠道(例如电子邮件、Slack、短信)向一个或多个接收者发送单条消息。

Nova

一个用于为您的 Laravel 应用程序构建管理面板的付费 Laravel 包。

NPM(Node 包管理器)

一个用于 Node 包的中央基于 Web 的存储库,在npmjs.org;还是一种工具,用于根据package.json的规范将项目的前端依赖项安装到node_modules目录中的本地计算机上。

OAuth

API 的最常见认证框架。OAuth 具有多个授权类型,每种类型描述了消费者如何在初始认证握手后检索、使用和刷新标识其身份的“令牌”的不同流程。

选项(Artisan)

类似于参数,选项是可以传递给 Artisan 命令的参数。它们以--开头,可以用作标志(--force)或提供数据(--userId=5)。

ORM(对象关系映射器)

一个设计模式,其核心是使用编程语言中的对象来表示关系数据库中的数据及其关系。

护照

一个可以轻松将 OAuth 身份验证服务器添加到您的 Laravel 应用程序中的 Laravel 包。

PHPSpec

一个 PHP 测试框架。

PHPUnit

一个 PHP 测试框架。最常见的,与大多数 Laravel 的自定义测试代码连接在一起。

多态的

在数据库术语中,能够与具有类似特征的多个数据库表进行交互。多态关系允许将多个模型的实体以相同的方式附加。

预处理器

一个构建工具,接收语言的特殊形式(对于 CSS,一种特殊形式是 LESS)并生成具有正常语言(CSS)的代码。预处理器内置工具和特性,这些特性不在核心语言中。

主键

大多数数据库表都有一个旨在代表每行的单个列。这称为主键,通常命名为id

队列

一个可以添加作业的堆栈。通常与队列工作者相关联,队列工作者逐个从队列中拉取作业,处理它们,然后丢弃它们。

React

一个 JavaScript 框架。由 Facebook 创建和维护。

实时门面

与门面类似,但不需要单独的类。实时门面可用于通过在其命名空间前加上Facades\来使任何类的方法可调用为静态方法。

Redis

像 Memcached 一样,比大多数关系数据库更简单但功能强大和快速的数据存储。Redis 支持非常有限的数据结构和数据类型,但在速度和可伸缩性方面弥补了这一不足。

REST(表述性状态转移)

当今 API 的最常见格式。通常建议与 API 的每个交互都单独进行身份验证,并且应该是“无状态”的;通常还建议使用 HTTP 动词来基本区分请求。

路由

用户可能访问 Web 应用程序的方式或方式的定义。路由是一种模式定义;它可以是像 /users/5,或者 /users,或者 /users/*id* 这样的东西。

S3(简单存储服务)

Amazon 的“对象存储”服务,它使得使用 AWS 强大的计算能力来存储和提供文件变得容易。

SaaS(软件即服务)

通过支付费用使用的基于 Web 的应用程序。

Sanctum

针对单页面应用程序、移动应用程序和简单基于令牌的 API 的 API 令牌认证系统。

作用域

在 Eloquent 中,用于定义如何一致而简单地缩小查询的工具。

Scout

用于在 Eloquent 模型上进行全文搜索的 Laravel 包。

序列化

将更复杂的数据(通常是 Eloquent 模型)转换为更简单的形式(在 Laravel 中通常是数组或 JSON)的过程。

服务提供商

Laravel 中注册和启动类和容器绑定的结构。

Socialite

一个使得在 Laravel 应用程序中添加社交认证(例如通过 Facebook 登录)变得简单的 Laravel 包。

软删除

将数据库行标记为“已删除”,而不实际删除它;通常与默认隐藏所有“已删除”行的 ORM 配对使用。

Spark

一个使得轻松创建新的基于订阅的 SaaS 应用程序变得容易的 Laravel 工具。

Symfony

一个专注于构建优秀组件并使其对他人可访问的 PHP 框架。Symfony 的 HTTPFoundation 是 Laravel 和其他现代 PHP 框架的核心。

Telescope

一个为 Laravel 应用程序添加调试助手的 Laravel 包。

Tinker

Laravel 的 REPL 或读-评估-打印循环。这是一个工具,允许您在命令行中以应用程序的完整上下文中执行复杂的 PHP 操作。

TL;DR

太长了;没读。 “摘要。”

类型提示

在方法签名中以类或接口名作为变量名的前缀。告诉 PHP(以及 Laravel 和其他开发者),该参数中允许传递的唯一允许的是具有给定类或接口的对象。

单元测试

单元测试针对较小的、相对孤立的单元——通常是一个类或方法。

Vagrant

一个命令行工具,可以使用预定义的镜像在本地计算机上轻松构建虚拟机。

Valet

一个 Laravel 包(适用于 macOS 用户,但也有 Linux 和 Windows 的分支),可以轻松地从您选择的开发文件夹中为您的应用程序提供服务,而无需担心 Vagrant 或虚拟机。

验证

确保用户输入与预期模式匹配。

视图

一个单独的文件,从后端系统或框架获取数据并将其转换为 HTML。

视图组合器

每当加载给定视图时,它会提供一组特定的数据。

Vue

一个 JavaScript 框架。Laravel 首选。由尤雨溪编写。