輔助函式

簡介

Laravel 提供了多種全域 PHP「輔助函式」。這些函式中,大部分都是 Laravel 本身有在使用的。不過,若你覺得這些方法很方便的話,也可以在你自己的專案內使用。

可用的方法

陣列與物件

路徑

URL

其他

陣列與物件

Arr::accessible()

Arr::accessible 方法判斷給定的值是否能以陣列方式存取:

1use Illuminate\Support\Arr;
2use Illuminate\Support\Collection;
3 
4$isAccessible = Arr::accessible(['a' => 1, 'b' => 2]);
5 
6// true
7 
8$isAccessible = Arr::accessible(new Collection);
9 
10// true
11 
12$isAccessible = Arr::accessible('abc');
13 
14// false
15 
16$isAccessible = Arr::accessible(new stdClass);
17 
18// false
1use Illuminate\Support\Arr;
2use Illuminate\Support\Collection;
3 
4$isAccessible = Arr::accessible(['a' => 1, 'b' => 2]);
5 
6// true
7 
8$isAccessible = Arr::accessible(new Collection);
9 
10// true
11 
12$isAccessible = Arr::accessible('abc');
13 
14// false
15 
16$isAccessible = Arr::accessible(new stdClass);
17 
18// false

Arr::add()

Arr::add 方法會在給定的索引鍵 / 值配對不存在於給定陣列、或是該索引鍵的值 null 時將該配對新增到陣列上:

1use Illuminate\Support\Arr;
2 
3$array = Arr::add(['name' => 'Desk'], 'price', 100);
4 
5// ['name' => 'Desk', 'price' => 100]
6 
7$array = Arr::add(['name' => 'Desk', 'price' => null], 'price', 100);
8 
9// ['name' => 'Desk', 'price' => 100]
1use Illuminate\Support\Arr;
2 
3$array = Arr::add(['name' => 'Desk'], 'price', 100);
4 
5// ['name' => 'Desk', 'price' => 100]
6 
7$array = Arr::add(['name' => 'Desk', 'price' => null], 'price', 100);
8 
9// ['name' => 'Desk', 'price' => 100]

Arr::collapse()

Arr::collapse 方法將一組陣列的陣列坍縮(Collapse)成單一陣列:

1use Illuminate\Support\Arr;
2 
3$array = Arr::collapse([[1, 2, 3], [4, 5, 6], [7, 8, 9]]);
4 
5// [1, 2, 3, 4, 5, 6, 7, 8, 9]
1use Illuminate\Support\Arr;
2 
3$array = Arr::collapse([[1, 2, 3], [4, 5, 6], [7, 8, 9]]);
4 
5// [1, 2, 3, 4, 5, 6, 7, 8, 9]

Arr::crossJoin()

Arr::crossJoin 方法交叉合併(Cross Join)給定的陣列,產生一個包含所有可能排列(Permutation)笛卡兒積(Cartesian Product)

1use Illuminate\Support\Arr;
2 
3$matrix = Arr::crossJoin([1, 2], ['a', 'b']);
4 
5/*
6 [
7 [1, 'a'],
8 [1, 'b'],
9 [2, 'a'],
10 [2, 'b'],
11 ]
12*/
13 
14$matrix = Arr::crossJoin([1, 2], ['a', 'b'], ['I', 'II']);
15 
16/*
17 [
18 [1, 'a', 'I'],
19 [1, 'a', 'II'],
20 [1, 'b', 'I'],
21 [1, 'b', 'II'],
22 [2, 'a', 'I'],
23 [2, 'a', 'II'],
24 [2, 'b', 'I'],
25 [2, 'b', 'II'],
26 ]
27*/
1use Illuminate\Support\Arr;
2 
3$matrix = Arr::crossJoin([1, 2], ['a', 'b']);
4 
5/*
6 [
7 [1, 'a'],
8 [1, 'b'],
9 [2, 'a'],
10 [2, 'b'],
11 ]
12*/
13 
14$matrix = Arr::crossJoin([1, 2], ['a', 'b'], ['I', 'II']);
15 
16/*
17 [
18 [1, 'a', 'I'],
19 [1, 'a', 'II'],
20 [1, 'b', 'I'],
21 [1, 'b', 'II'],
22 [2, 'a', 'I'],
23 [2, 'a', 'II'],
24 [2, 'b', 'I'],
25 [2, 'b', 'II'],
26 ]
27*/

Arr::divide()

Arr::divide 方法回傳兩個陣列:一個陣列包含給定陣列的索引鍵,而另一個陣列則包含給定陣列的值:

1use Illuminate\Support\Arr;
2 
3[$keys, $values] = Arr::divide(['name' => 'Desk']);
4 
5// $keys: ['name']
6 
7// $values: ['Desk']
1use Illuminate\Support\Arr;
2 
3[$keys, $values] = Arr::divide(['name' => 'Desk']);
4 
5// $keys: ['name']
6 
7// $values: ['Desk']

Arr::dot()

Arr::dot 方法將多為陣列扁平化(Flatten)為一個使用「點 (.)」標記法來表示深度的一維陣列:

1use Illuminate\Support\Arr;
2 
3$array = ['products' => ['desk' => ['price' => 100]]];
4 
5$flattened = Arr::dot($array);
6 
7// ['products.desk.price' => 100]
1use Illuminate\Support\Arr;
2 
3$array = ['products' => ['desk' => ['price' => 100]]];
4 
5$flattened = Arr::dot($array);
6 
7// ['products.desk.price' => 100]

Arr::except()

Arr::except 方法從陣列中移除給定的索引鍵 / 值配對:

1use Illuminate\Support\Arr;
2 
3$array = ['name' => 'Desk', 'price' => 100];
4 
5$filtered = Arr::except($array, ['price']);
6 
7// ['name' => 'Desk']
1use Illuminate\Support\Arr;
2 
3$array = ['name' => 'Desk', 'price' => 100];
4 
5$filtered = Arr::except($array, ['price']);
6 
7// ['name' => 'Desk']

Arr::exists()

Arr::exists 方法會檢查給定的索引鍵是否存在於提供的陣列中:

1use Illuminate\Support\Arr;
2 
3$array = ['name' => 'John Doe', 'age' => 17];
4 
5$exists = Arr::exists($array, 'name');
6 
7// true
8 
9$exists = Arr::exists($array, 'salary');
10 
11// false
1use Illuminate\Support\Arr;
2 
3$array = ['name' => 'John Doe', 'age' => 17];
4 
5$exists = Arr::exists($array, 'name');
6 
7// true
8 
9$exists = Arr::exists($array, 'salary');
10 
11// false

Arr::first()

Arr::first 方法會回傳該陣列中通過給定布林測試的第一個元素:

1use Illuminate\Support\Arr;
2 
3$array = [100, 200, 300];
4 
5$first = Arr::first($array, function (int $value, int $key) {
6 return $value >= 150;
7});
8 
9// 200
1use Illuminate\Support\Arr;
2 
3$array = [100, 200, 300];
4 
5$first = Arr::first($array, function (int $value, int $key) {
6 return $value >= 150;
7});
8 
9// 200

也可以在第三個引數上提供一個預設值給該方法。若沒有任何值通過條件測試,就會回傳這個預設值:

1use Illuminate\Support\Arr;
2 
3$first = Arr::first($array, $callback, $default);
1use Illuminate\Support\Arr;
2 
3$first = Arr::first($array, $callback, $default);

Arr::flatten()

Arr::flatten 方法會將一個多維陣列扁平化(Flatten)為單一維度:

1use Illuminate\Support\Arr;
2 
3$array = ['name' => 'Joe', 'languages' => ['PHP', 'Ruby']];
4 
5$flattened = Arr::flatten($array);
6 
7// ['Joe', 'PHP', 'Ruby']
1use Illuminate\Support\Arr;
2 
3$array = ['name' => 'Joe', 'languages' => ['PHP', 'Ruby']];
4 
5$flattened = Arr::flatten($array);
6 
7// ['Joe', 'PHP', 'Ruby']

Arr::forget()

Arr::forget 方法使用「點 (.)」標記法來在多層巢狀陣列中移除給定的索引鍵 / 值配對:

1use Illuminate\Support\Arr;
2 
3$array = ['products' => ['desk' => ['price' => 100]]];
4 
5Arr::forget($array, 'products.desk');
6 
7// ['products' => []]
1use Illuminate\Support\Arr;
2 
3$array = ['products' => ['desk' => ['price' => 100]]];
4 
5Arr::forget($array, 'products.desk');
6 
7// ['products' => []]

Arr::get()

Arr::get 方法使用「點 (.)」標記法來在多層巢狀陣列中取值:

1use Illuminate\Support\Arr;
2 
3$array = ['products' => ['desk' => ['price' => 100]]];
4 
5$price = Arr::get($array, 'products.desk.price');
6 
7// 100
1use Illuminate\Support\Arr;
2 
3$array = ['products' => ['desk' => ['price' => 100]]];
4 
5$price = Arr::get($array, 'products.desk.price');
6 
7// 100

Arr::get 還接受一個預設值。若指定的索引鍵不存在時會回傳該預設值:

1use Illuminate\Support\Arr;
2 
3$discount = Arr::get($array, 'products.desk.discount', 0);
4 
5// 0
1use Illuminate\Support\Arr;
2 
3$discount = Arr::get($array, 'products.desk.discount', 0);
4 
5// 0

Arr::has()

Arr::has 方法使用「點 (.)」標記法來檢查給定的一個或多個項目是否存在:

1use Illuminate\Support\Arr;
2 
3$array = ['product' => ['name' => 'Desk', 'price' => 100]];
4 
5$contains = Arr::has($array, 'product.name');
6 
7// true
8 
9$contains = Arr::has($array, ['product.price', 'product.discount']);
10 
11// false
1use Illuminate\Support\Arr;
2 
3$array = ['product' => ['name' => 'Desk', 'price' => 100]];
4 
5$contains = Arr::has($array, 'product.name');
6 
7// true
8 
9$contains = Arr::has($array, ['product.price', 'product.discount']);
10 
11// false

Arr::hasAny()

Arr::hasAny 方法使用「點 (.)」標記法來檢查給定的多個項目中是否只少有一個存在:

1use Illuminate\Support\Arr;
2 
3$array = ['product' => ['name' => 'Desk', 'price' => 100]];
4 
5$contains = Arr::hasAny($array, 'product.name');
6 
7// true
8 
9$contains = Arr::hasAny($array, ['product.name', 'product.discount']);
10 
11// true
12 
13$contains = Arr::hasAny($array, ['category', 'product.discount']);
14 
15// false
1use Illuminate\Support\Arr;
2 
3$array = ['product' => ['name' => 'Desk', 'price' => 100]];
4 
5$contains = Arr::hasAny($array, 'product.name');
6 
7// true
8 
9$contains = Arr::hasAny($array, ['product.name', 'product.discount']);
10 
11// true
12 
13$contains = Arr::hasAny($array, ['category', 'product.discount']);
14 
15// false

Arr::isAssoc()

若給定的陣列為關聯式陣列(Associative Array)Arr::isAssoc 方法會回傳 true。當某個陣列的索引鍵不是以 0 開始依序排列的數字時,就是「關聯式」的陣列:

1use Illuminate\Support\Arr;
2 
3$isAssoc = Arr::isAssoc(['product' => ['name' => 'Desk', 'price' => 100]]);
4 
5// true
6 
7$isAssoc = Arr::isAssoc([1, 2, 3]);
8 
9// false
1use Illuminate\Support\Arr;
2 
3$isAssoc = Arr::isAssoc(['product' => ['name' => 'Desk', 'price' => 100]]);
4 
5// true
6 
7$isAssoc = Arr::isAssoc([1, 2, 3]);
8 
9// false

Arr::isList()

若給定陣列的索引鍵是從 0 開始的有序整數的話,Arr::isList 方法會回傳 true

1use Illuminate\Support\Arr;
2 
3$isList = Arr::isList(['foo', 'bar', 'baz']);
4 
5// true
6 
7$isList = Arr::isList(['product' => ['name' => 'Desk', 'price' => 100]]);
8 
9// false
1use Illuminate\Support\Arr;
2 
3$isList = Arr::isList(['foo', 'bar', 'baz']);
4 
5// true
6 
7$isList = Arr::isList(['product' => ['name' => 'Desk', 'price' => 100]]);
8 
9// false

Arr::join()

Arr::join 方法可使用字串來將各個陣列元素串接在一起。也可以用該方法的第二個引數來指定用於串接陣列中最後一個元素的字串:

1use Illuminate\Support\Arr;
2 
3$array = ['Tailwind', 'Alpine', 'Laravel', 'Livewire'];
4 
5$joined = Arr::join($array, ', ');
6 
7// Tailwind, Alpine, Laravel, Livewire
8 
9$joined = Arr::join($array, ', ', ' and ');
10 
11// Tailwind, Alpine, Laravel and Livewire
1use Illuminate\Support\Arr;
2 
3$array = ['Tailwind', 'Alpine', 'Laravel', 'Livewire'];
4 
5$joined = Arr::join($array, ', ');
6 
7// Tailwind, Alpine, Laravel, Livewire
8 
9$joined = Arr::join($array, ', ', ' and ');
10 
11// Tailwind, Alpine, Laravel and Livewire

Arr::keyBy()

Arr::keyBy 方法依照給定的索引鍵來為該陣列加上索引鍵。若多個項目有相同的索引鍵,則新的陣列中只會包含最後一個項目:

1use Illuminate\Support\Arr;
2 
3$array = [
4 ['product_id' => 'prod-100', 'name' => 'Desk'],
5 ['product_id' => 'prod-200', 'name' => 'Chair'],
6];
7 
8$keyed = Arr::keyBy($array, 'product_id');
9 
10/*
11 [
12 'prod-100' => ['product_id' => 'prod-100', 'name' => 'Desk'],
13 'prod-200' => ['product_id' => 'prod-200', 'name' => 'Chair'],
14 ]
15*/
1use Illuminate\Support\Arr;
2 
3$array = [
4 ['product_id' => 'prod-100', 'name' => 'Desk'],
5 ['product_id' => 'prod-200', 'name' => 'Chair'],
6];
7 
8$keyed = Arr::keyBy($array, 'product_id');
9 
10/*
11 [
12 'prod-100' => ['product_id' => 'prod-100', 'name' => 'Desk'],
13 'prod-200' => ['product_id' => 'prod-200', 'name' => 'Chair'],
14 ]
15*/

Arr::last()

Arr::last 方法會回傳該陣列中通過給定布林測試的最後一個元素:

1use Illuminate\Support\Arr;
2 
3$array = [100, 200, 300, 110];
4 
5$last = Arr::last($array, function (int $value, int $key) {
6 return $value >= 150;
7});
8 
9// 300
1use Illuminate\Support\Arr;
2 
3$array = [100, 200, 300, 110];
4 
5$last = Arr::last($array, function (int $value, int $key) {
6 return $value >= 150;
7});
8 
9// 300

可以在第三個引數上提供一個預設值給該方法。若沒有任何值通過條件測試,就會回傳這個預設值:

1use Illuminate\Support\Arr;
2 
3$last = Arr::last($array, $callback, $default);
1use Illuminate\Support\Arr;
2 
3$last = Arr::last($array, $callback, $default);

Arr::map()

Arr::map 可用於迭代整個陣列,並將各個陣列值與索引鍵傳入給定的回呼中。陣列值會被回呼中回傳的值給取代:

1use Illuminate\Support\Arr;
2 
3$array = ['first' => 'james', 'last' => 'kirk'];
4 
5$mapped = Arr::map($array, function (string $value, string $key) {
6 return ucfirst($value);
7});
8 
9// ['first' => 'James', 'last' => 'Kirk']
1use Illuminate\Support\Arr;
2 
3$array = ['first' => 'james', 'last' => 'kirk'];
4 
5$mapped = Arr::map($array, function (string $value, string $key) {
6 return ucfirst($value);
7});
8 
9// ['first' => 'James', 'last' => 'Kirk']

Arr::mapWithKeys()

Arr::mapWithKeys 方法會迭代該陣列,並將各個值傳入給定的回呼。該回呼應回傳一個包含單一索引鍵/值配對的關聯性陣列:

1use Illuminate\Support\Arr;
2 
3$array = [
4 [
5 'name' => 'John',
6 'department' => 'Sales',
7 'email' => '[email protected]',
8 ],
9 [
10 'name' => 'Jane',
11 'department' => 'Marketing',
12 'email' => '[email protected]',
13 ]
14];
15 
16$mapped = Arr::mapWithKeys($array, function (array $item, int $key) {
17 return [$item['email'] => $item['name']];
18});
19 
20/*
21 [
22 '[email protected]' => 'John',
23 '[email protected]' => 'Jane',
24 ]
25*/
1use Illuminate\Support\Arr;
2 
3$array = [
4 [
5 'name' => 'John',
6 'department' => 'Sales',
7 'email' => '[email protected]',
8 ],
9 [
10 'name' => 'Jane',
11 'department' => 'Marketing',
12 'email' => '[email protected]',
13 ]
14];
15 
16$mapped = Arr::mapWithKeys($array, function (array $item, int $key) {
17 return [$item['email'] => $item['name']];
18});
19 
20/*
21 [
22 '[email protected]' => 'John',
23 '[email protected]' => 'Jane',
24 ]
25*/

Arr::only()

Arr::only 方法回傳給定陣列中特定的索引鍵 / 值配對:

1use Illuminate\Support\Arr;
2 
3$array = ['name' => 'Desk', 'price' => 100, 'orders' => 10];
4 
5$slice = Arr::only($array, ['name', 'price']);
6 
7// ['name' => 'Desk', 'price' => 100]
1use Illuminate\Support\Arr;
2 
3$array = ['name' => 'Desk', 'price' => 100, 'orders' => 10];
4 
5$slice = Arr::only($array, ['name', 'price']);
6 
7// ['name' => 'Desk', 'price' => 100]

Arr::pluck()

Arr::pluck 方法可從給定陣列中取得給定索引鍵內的所有值:

1use Illuminate\Support\Arr;
2 
3$array = [
4 ['developer' => ['id' => 1, 'name' => 'Taylor']],
5 ['developer' => ['id' => 2, 'name' => 'Abigail']],
6];
7 
8$names = Arr::pluck($array, 'developer.name');
9 
10// ['Taylor', 'Abigail']
1use Illuminate\Support\Arr;
2 
3$array = [
4 ['developer' => ['id' => 1, 'name' => 'Taylor']],
5 ['developer' => ['id' => 2, 'name' => 'Abigail']],
6];
7 
8$names = Arr::pluck($array, 'developer.name');
9 
10// ['Taylor', 'Abigail']

也可以指定產生的清單要如何設定索引鍵:

1use Illuminate\Support\Arr;
2 
3$names = Arr::pluck($array, 'developer.name', 'developer.id');
4 
5// [1 => 'Taylor', 2 => 'Abigail']
1use Illuminate\Support\Arr;
2 
3$names = Arr::pluck($array, 'developer.name', 'developer.id');
4 
5// [1 => 'Taylor', 2 => 'Abigail']

Arr::prepend()

Arr::prepend 方法會將某個項目放到該陣列的最前面:

1use Illuminate\Support\Arr;
2 
3$array = ['one', 'two', 'three', 'four'];
4 
5$array = Arr::prepend($array, 'zero');
6 
7// ['zero', 'one', 'two', 'three', 'four']
1use Illuminate\Support\Arr;
2 
3$array = ['one', 'two', 'three', 'four'];
4 
5$array = Arr::prepend($array, 'zero');
6 
7// ['zero', 'one', 'two', 'three', 'four']

若有需要,也可以指定該值要使用的索引鍵:

1use Illuminate\Support\Arr;
2 
3$array = ['price' => 100];
4 
5$array = Arr::prepend($array, 'Desk', 'name');
6 
7// ['name' => 'Desk', 'price' => 100]
1use Illuminate\Support\Arr;
2 
3$array = ['price' => 100];
4 
5$array = Arr::prepend($array, 'Desk', 'name');
6 
7// ['name' => 'Desk', 'price' => 100]

Arr::prependKeysWith()

Arr::prependKeysWith 會將關聯式陣列中,將所有的索引鍵名稱加上給定的前置詞:

1use Illuminate\Support\Arr;
2 
3$array = [
4 'name' => 'Desk',
5 'price' => 100,
6];
7 
8$keyed = Arr::prependKeysWith($array, 'product.');
9 
10/*
11 [
12 'product.name' => 'Desk',
13 'product.price' => 100,
14 ]
15*/
1use Illuminate\Support\Arr;
2 
3$array = [
4 'name' => 'Desk',
5 'price' => 100,
6];
7 
8$keyed = Arr::prependKeysWith($array, 'product.');
9 
10/*
11 [
12 'product.name' => 'Desk',
13 'product.price' => 100,
14 ]
15*/

Arr::pull()

Arr::pull 方法從陣列中移除一組索引鍵 / 值配對:

1use Illuminate\Support\Arr;
2 
3$array = ['name' => 'Desk', 'price' => 100];
4 
5$name = Arr::pull($array, 'name');
6 
7// $name: Desk
8 
9// $array: ['price' => 100]
1use Illuminate\Support\Arr;
2 
3$array = ['name' => 'Desk', 'price' => 100];
4 
5$name = Arr::pull($array, 'name');
6 
7// $name: Desk
8 
9// $array: ['price' => 100]

可以在第三個引數上提供一個預設值給該方法。若指定的索引鍵不存在,就會回傳這個預設值:

1use Illuminate\Support\Arr;
2 
3$value = Arr::pull($array, $key, $default);
1use Illuminate\Support\Arr;
2 
3$value = Arr::pull($array, $key, $default);

Arr::query()

Arr::query 方法將該陣列轉換為查詢字串(Query String)

1use Illuminate\Support\Arr;
2 
3$array = [
4 'name' => 'Taylor',
5 'order' => [
6 'column' => 'created_at',
7 'direction' => 'desc'
8 ]
9];
10 
11Arr::query($array);
12 
13// name=Taylor&order[column]=created_at&order[direction]=desc
1use Illuminate\Support\Arr;
2 
3$array = [
4 'name' => 'Taylor',
5 'order' => [
6 'column' => 'created_at',
7 'direction' => 'desc'
8 ]
9];
10 
11Arr::query($array);
12 
13// name=Taylor&order[column]=created_at&order[direction]=desc

Arr::random()

Arr::random 方法從陣列中隨機回傳一個值:

1use Illuminate\Support\Arr;
2 
3$array = [1, 2, 3, 4, 5];
4 
5$random = Arr::random($array);
6 
7// 4 - (隨機取得)
1use Illuminate\Support\Arr;
2 
3$array = [1, 2, 3, 4, 5];
4 
5$random = Arr::random($array);
6 
7// 4 - (隨機取得)

也可以在第二個引數上指定要回傳項目的數量。請注意,若有提供第二個引數,就算只要求一個項目,還是會回傳一組陣列:

1use Illuminate\Support\Arr;
2 
3$items = Arr::random($array, 2);
4 
5// [2, 5] - (隨機取得)
1use Illuminate\Support\Arr;
2 
3$items = Arr::random($array, 2);
4 
5// [2, 5] - (隨機取得)

Arr::set()

Arr::set 方法可使用「點 (.)」標記法來在多層巢狀陣列中賦值:

1use Illuminate\Support\Arr;
2 
3$array = ['products' => ['desk' => ['price' => 100]]];
4 
5Arr::set($array, 'products.desk.price', 200);
6 
7// ['products' => ['desk' => ['price' => 200]]]
1use Illuminate\Support\Arr;
2 
3$array = ['products' => ['desk' => ['price' => 100]]];
4 
5Arr::set($array, 'products.desk.price', 200);
6 
7// ['products' => ['desk' => ['price' => 200]]]

Arr::shuffle()

Arr::shuffle 方法會隨機排序該陣列內的項目:

1use Illuminate\Support\Arr;
2 
3$array = Arr::shuffle([1, 2, 3, 4, 5]);
4 
5// [3, 2, 5, 1, 4] - (隨機產生)
1use Illuminate\Support\Arr;
2 
3$array = Arr::shuffle([1, 2, 3, 4, 5]);
4 
5// [3, 2, 5, 1, 4] - (隨機產生)

Arr::sort()

Arr::sort 方法以陣列內的值來排列陣列:

1use Illuminate\Support\Arr;
2 
3$array = ['Desk', 'Table', 'Chair'];
4 
5$sorted = Arr::sort($array);
6 
7// ['Chair', 'Desk', 'Table']
1use Illuminate\Support\Arr;
2 
3$array = ['Desk', 'Table', 'Chair'];
4 
5$sorted = Arr::sort($array);
6 
7// ['Chair', 'Desk', 'Table']

也可以使用給定閉包的執行結果來排序陣列:

1use Illuminate\Support\Arr;
2 
3$array = [
4 ['name' => 'Desk'],
5 ['name' => 'Table'],
6 ['name' => 'Chair'],
7];
8 
9$sorted = array_values(Arr::sort($array, function (array $value) {
10 return $value['name'];
11}));
12 
13/*
14 [
15 ['name' => 'Chair'],
16 ['name' => 'Desk'],
17 ['name' => 'Table'],
18 ]
19*/
1use Illuminate\Support\Arr;
2 
3$array = [
4 ['name' => 'Desk'],
5 ['name' => 'Table'],
6 ['name' => 'Chair'],
7];
8 
9$sorted = array_values(Arr::sort($array, function (array $value) {
10 return $value['name'];
11}));
12 
13/*
14 [
15 ['name' => 'Chair'],
16 ['name' => 'Desk'],
17 ['name' => 'Table'],
18 ]
19*/

Arr::sortDesc()

Arr::sortDesc 方法將陣列以其值來降冪排序:

1use Illuminate\Support\Arr;
2 
3$array = ['Desk', 'Table', 'Chair'];
4 
5$sorted = Arr::sortDesc($array);
6 
7// ['Table', 'Desk', 'Chair']
1use Illuminate\Support\Arr;
2 
3$array = ['Desk', 'Table', 'Chair'];
4 
5$sorted = Arr::sortDesc($array);
6 
7// ['Table', 'Desk', 'Chair']

也可以使用給定閉包的執行結果來排序陣列:

1use Illuminate\Support\Arr;
2 
3$array = [
4 ['name' => 'Desk'],
5 ['name' => 'Table'],
6 ['name' => 'Chair'],
7];
8 
9$sorted = array_values(Arr::sortDesc($array, function (array $value) {
10 return $value['name'];
11}));
12 
13/*
14 [
15 ['name' => 'Table'],
16 ['name' => 'Desk'],
17 ['name' => 'Chair'],
18 ]
19*/
1use Illuminate\Support\Arr;
2 
3$array = [
4 ['name' => 'Desk'],
5 ['name' => 'Table'],
6 ['name' => 'Chair'],
7];
8 
9$sorted = array_values(Arr::sortDesc($array, function (array $value) {
10 return $value['name'];
11}));
12 
13/*
14 [
15 ['name' => 'Table'],
16 ['name' => 'Desk'],
17 ['name' => 'Chair'],
18 ]
19*/

Arr::sortRecursive()

Arr::sortRecursive 方法會遞迴排序陣列。當遇到數字索引鍵的子陣列時,會使用 sort 函式;若子陣列為關聯式陣列,則使用 ksort 函式:

1use Illuminate\Support\Arr;
2 
3$array = [
4 ['Roman', 'Taylor', 'Li'],
5 ['PHP', 'Ruby', 'JavaScript'],
6 ['one' => 1, 'two' => 2, 'three' => 3],
7];
8 
9$sorted = Arr::sortRecursive($array);
10 
11/*
12 [
13 ['JavaScript', 'PHP', 'Ruby'],
14 ['one' => 1, 'three' => 3, 'two' => 2],
15 ['Li', 'Roman', 'Taylor'],
16 ]
17*/
1use Illuminate\Support\Arr;
2 
3$array = [
4 ['Roman', 'Taylor', 'Li'],
5 ['PHP', 'Ruby', 'JavaScript'],
6 ['one' => 1, 'two' => 2, 'three' => 3],
7];
8 
9$sorted = Arr::sortRecursive($array);
10 
11/*
12 [
13 ['JavaScript', 'PHP', 'Ruby'],
14 ['one' => 1, 'three' => 3, 'two' => 2],
15 ['Li', 'Roman', 'Taylor'],
16 ]
17*/

若想讓結果以降冪排序,可使用 Arr::sortRecursiveDesc 方法。

1$sorted = Arr::sortRecursiveDesc($array);
1$sorted = Arr::sortRecursiveDesc($array);

Arr::toCssClasses()

Arr::toCssClasses 可以有條件地編譯 CSS class 字串。該方法接受一組包含 class 的陣列,其中,陣列的索引鍵代表欲新增的 class,陣列值則是一個布林運算式。若陣列的元素有數字索引鍵,則該元素一定會被加到轉譯後的 Class 列表上:

1use Illuminate\Support\Arr;
2 
3$isActive = false;
4$hasError = true;
5 
6$array = ['p-4', 'font-bold' => $isActive, 'bg-red' => $hasError];
7 
8$classes = Arr::toCssClasses($array);
9 
10/*
11 'p-4 bg-red'
12*/
1use Illuminate\Support\Arr;
2 
3$isActive = false;
4$hasError = true;
5 
6$array = ['p-4', 'font-bold' => $isActive, 'bg-red' => $hasError];
7 
8$classes = Arr::toCssClasses($array);
9 
10/*
11 'p-4 bg-red'
12*/

Arr::toCssStyles()

Arr::toCssClasses 可以有條件地編譯 CSS Class 字串。該方法接受一組包含 Class 的陣列,其中,陣列的索引鍵代表欲新增的 Class,陣列值則是一個布林運算式。若陣列的元素有數字索引鍵,則該元素一定會被加到轉譯後的 Class 列表上:

1$hasColor = true;
2 
3$array = ['background-color: blue', 'color: blue' => $hasColor];
4 
5$classes = Arr::toCssStyles($array);
6 
7/*
8 'background-color: blue; color: blue;'
9*/
1$hasColor = true;
2 
3$array = ['background-color: blue', 'color: blue' => $hasColor];
4 
5$classes = Arr::toCssStyles($array);
6 
7/*
8 'background-color: blue; color: blue;'
9*/

該方法用於提供了 Laravel 的「將 Class 於 Blade 元件的 Attribute Bag 合併」功能,以及 @class Blade 指示詞

Arr::undot()

Arr::undot 方法將一組使用「點 (.)」標記法的一維陣列展開為多維陣列:

1use Illuminate\Support\Arr;
2 
3$array = [
4 'user.name' => 'Kevin Malone',
5 'user.occupation' => 'Accountant',
6];
7 
8$array = Arr::undot($array);
9 
10// ['user' => ['name' => 'Kevin Malone', 'occupation' => 'Accountant']]
1use Illuminate\Support\Arr;
2 
3$array = [
4 'user.name' => 'Kevin Malone',
5 'user.occupation' => 'Accountant',
6];
7 
8$array = Arr::undot($array);
9 
10// ['user' => ['name' => 'Kevin Malone', 'occupation' => 'Accountant']]

Arr::where()

Arr::where 方法使用給定的閉包來篩選陣列:

1use Illuminate\Support\Arr;
2 
3$array = [100, '200', 300, '400', 500];
4 
5$filtered = Arr::where($array, function (string|int $value, int $key) {
6 return is_string($value);
7});
8 
9// [1 => '200', 3 => '400']
1use Illuminate\Support\Arr;
2 
3$array = [100, '200', 300, '400', 500];
4 
5$filtered = Arr::where($array, function (string|int $value, int $key) {
6 return is_string($value);
7});
8 
9// [1 => '200', 3 => '400']

Arr::whereNotNull()

Arr::whereNotNull 方法從給定陣列中移除所有 null 的值:

1use Illuminate\Support\Arr;
2 
3$array = [0, null];
4 
5$filtered = Arr::whereNotNull($array);
6 
7// [0 => 0]
1use Illuminate\Support\Arr;
2 
3$array = [0, null];
4 
5$filtered = Arr::whereNotNull($array);
6 
7// [0 => 0]

Arr::wrap()

Arr::wrap 將給定值包裝(Wrap)為陣列。若給定的值已為陣列,則該方法會直接回傳該陣列,不做其他修改:

1use Illuminate\Support\Arr;
2 
3$string = 'Laravel';
4 
5$array = Arr::wrap($string);
6 
7// ['Laravel']
1use Illuminate\Support\Arr;
2 
3$string = 'Laravel';
4 
5$array = Arr::wrap($string);
6 
7// ['Laravel']

若給定值為 null,則會回傳空陣列:

1use Illuminate\Support\Arr;
2 
3$array = Arr::wrap(null);
4 
5// []
1use Illuminate\Support\Arr;
2 
3$array = Arr::wrap(null);
4 
5// []

data_fill()

data_fill 方法使用「點 (.)」標記法來在巢狀陣列或物件中填上原本不存在的值:

1$data = ['products' => ['desk' => ['price' => 100]]];
2 
3data_fill($data, 'products.desk.price', 200);
4 
5// ['products' => ['desk' => ['price' => 100]]]
6 
7data_fill($data, 'products.desk.discount', 10);
8 
9// ['products' => ['desk' => ['price' => 100, 'discount' => 10]]]
1$data = ['products' => ['desk' => ['price' => 100]]];
2 
3data_fill($data, 'products.desk.price', 200);
4 
5// ['products' => ['desk' => ['price' => 100]]]
6 
7data_fill($data, 'products.desk.discount', 10);
8 
9// ['products' => ['desk' => ['price' => 100, 'discount' => 10]]]

該方法也支援使用星號作為萬用字元,會填上對應的目標:

1$data = [
2 'products' => [
3 ['name' => 'Desk 1', 'price' => 100],
4 ['name' => 'Desk 2'],
5 ],
6];
7 
8data_fill($data, 'products.*.price', 200);
9 
10/*
11 [
12 'products' => [
13 ['name' => 'Desk 1', 'price' => 100],
14 ['name' => 'Desk 2', 'price' => 200],
15 ],
16 ]
17*/
1$data = [
2 'products' => [
3 ['name' => 'Desk 1', 'price' => 100],
4 ['name' => 'Desk 2'],
5 ],
6];
7 
8data_fill($data, 'products.*.price', 200);
9 
10/*
11 [
12 'products' => [
13 ['name' => 'Desk 1', 'price' => 100],
14 ['name' => 'Desk 2', 'price' => 200],
15 ],
16 ]
17*/

data_get()

data_get 方法使用「點 (.)」標記法來從巢狀陣列或物件中取值:

1$data = ['products' => ['desk' => ['price' => 100]]];
2 
3$price = data_get($data, 'products.desk.price');
4 
5// 100
1$data = ['products' => ['desk' => ['price' => 100]]];
2 
3$price = data_get($data, 'products.desk.price');
4 
5// 100

data_get 還接受一個預設值。若找不到指定的索引鍵時會回傳該預設值:

1$discount = data_get($data, 'products.desk.discount', 0);
2 
3// 0
1$discount = data_get($data, 'products.desk.discount', 0);
2 
3// 0

該方法也接受使用星號來作為萬用字元,可以套用到陣列或物件上的任何索引鍵:

1$data = [
2 'product-one' => ['name' => 'Desk 1', 'price' => 100],
3 'product-two' => ['name' => 'Desk 2', 'price' => 150],
4];
5 
6data_get($data, '*.name');
7 
8// ['Desk 1', 'Desk 2'];
1$data = [
2 'product-one' => ['name' => 'Desk 1', 'price' => 100],
3 'product-two' => ['name' => 'Desk 2', 'price' => 150],
4];
5 
6data_get($data, '*.name');
7 
8// ['Desk 1', 'Desk 2'];

data_set()

data_set 函式使用「點 (.)」標記法來在巢狀陣列或物件上賦值:

1$data = ['products' => ['desk' => ['price' => 100]]];
2 
3data_set($data, 'products.desk.price', 200);
4 
5// ['products' => ['desk' => ['price' => 200]]]
1$data = ['products' => ['desk' => ['price' => 100]]];
2 
3data_set($data, 'products.desk.price', 200);
4 
5// ['products' => ['desk' => ['price' => 200]]]

該函式也接受使用星號作為萬用字元,會為設定相應的目標賦值:

1$data = [
2 'products' => [
3 ['name' => 'Desk 1', 'price' => 100],
4 ['name' => 'Desk 2', 'price' => 150],
5 ],
6];
7 
8data_set($data, 'products.*.price', 200);
9 
10/*
11 [
12 'products' => [
13 ['name' => 'Desk 1', 'price' => 200],
14 ['name' => 'Desk 2', 'price' => 200],
15 ],
16 ]
17*/
1$data = [
2 'products' => [
3 ['name' => 'Desk 1', 'price' => 100],
4 ['name' => 'Desk 2', 'price' => 150],
5 ],
6];
7 
8data_set($data, 'products.*.price', 200);
9 
10/*
11 [
12 'products' => [
13 ['name' => 'Desk 1', 'price' => 200],
14 ['name' => 'Desk 2', 'price' => 200],
15 ],
16 ]
17*/

預設情況下,會複寫現有的值。若只想為不存在的項目賦值,可傳入 false 作為第四個引數給該函式:

1$data = ['products' => ['desk' => ['price' => 100]]];
2 
3data_set($data, 'products.desk.price', 200, overwrite: false);
4 
5// ['products' => ['desk' => ['price' => 100]]]
1$data = ['products' => ['desk' => ['price' => 100]]];
2 
3data_set($data, 'products.desk.price', 200, overwrite: false);
4 
5// ['products' => ['desk' => ['price' => 100]]]

data_forget()

data_forget 函式使用「點 (.)」標記法來在巢狀陣列或物件上移除一個值:

1$data = ['products' => ['desk' => ['price' => 100]]];
2 
3data_forget($data, 'products.desk.price');
4 
5// ['products' => ['desk' => []]]
1$data = ['products' => ['desk' => ['price' => 100]]];
2 
3data_forget($data, 'products.desk.price');
4 
5// ['products' => ['desk' => []]]

該函式也接受使用星號作為萬用字元,會移除相應的目標值:

1$data = [
2 'products' => [
3 ['name' => 'Desk 1', 'price' => 100],
4 ['name' => 'Desk 2', 'price' => 150],
5 ],
6];
7 
8data_forget($data, 'products.*.price');
9 
10/*
11 [
12 'products' => [
13 ['name' => 'Desk 1'],
14 ['name' => 'Desk 2'],
15 ],
16 ]
17*/
1$data = [
2 'products' => [
3 ['name' => 'Desk 1', 'price' => 100],
4 ['name' => 'Desk 2', 'price' => 150],
5 ],
6];
7 
8data_forget($data, 'products.*.price');
9 
10/*
11 [
12 'products' => [
13 ['name' => 'Desk 1'],
14 ['name' => 'Desk 2'],
15 ],
16 ]
17*/

head()

head 方法回傳給定陣列中的第一個元素:

1$array = [100, 200, 300];
2 
3$first = head($array);
4 
5// 100
1$array = [100, 200, 300];
2 
3$first = head($array);
4 
5// 100

last()

last 方法回傳給定陣列中的最後一個元素:

1$array = [100, 200, 300];
2 
3$last = last($array);
4 
5// 300
1$array = [100, 200, 300];
2 
3$last = last($array);
4 
5// 300

路徑

app_path()

app_path 回傳專案 app 目錄的完整名稱路徑。也可以使用 app_path 函式來為 app 目錄下相對路徑的完整名稱路徑:

1$path = app_path();
2 
3$path = app_path('Http/Controllers/Controller.php');
1$path = app_path();
2 
3$path = app_path('Http/Controllers/Controller.php');

base_path()

base_path 函式回傳專案根目錄的完整名稱路徑。也可以使用 base_path 來產生相對於根目錄下給定檔案的完整名稱路徑:

1$path = base_path();
2 
3$path = base_path('vendor/bin');
1$path = base_path();
2 
3$path = base_path('vendor/bin');

config_path()

config_path 函式回傳專案 config 目錄的完整名稱路徑。也可以使用 config_path 函式來產生專案 config 目錄內給定檔案的完整名稱路徑:

1$path = config_path();
2 
3$path = config_path('app.php');
1$path = config_path();
2 
3$path = config_path('app.php');

database_path()

database_path 函式回傳專案 database 目錄的完整名稱路徑。也可以使用 database_path 函式來產生 database 目錄下給定檔案的完整名稱路徑:

1$path = database_path();
2 
3$path = database_path('factories/UserFactory.php');
1$path = database_path();
2 
3$path = database_path('factories/UserFactory.php');

lang_path()

lang_path 函式回傳專案 lang 目錄的完整名稱路徑。也可以使用 lang_path 函式來產生 lang 目錄下給定檔案的完整名稱路徑:

1$path = lang_path();
2 
3$path = lang_path('en/messages.php');
1$path = lang_path();
2 
3$path = lang_path('en/messages.php');
lightbulb

預設情況下,Laravel 專案的 Skeleton 中未包含 lang 目錄。若想自定 Laravel 的語系檔,可以使用 lang:publish Artisan 指令來安裝語系檔:

mix()

mix 函式回傳版本化的 Mix 檔案路徑:

1$path = mix('css/app.css');
1$path = mix('css/app.css');

public_path()

public_path 函式回傳專案 public 目錄的完整名稱路徑。也可以使用 public_path 函式來產生 public 目錄下給定檔案的完整名稱路徑:

1$path = public_path();
2 
3$path = public_path('css/app.css');
1$path = public_path();
2 
3$path = public_path('css/app.css');

resource_path()

resource_path 函式回傳專案 resources 目錄的完整名稱路徑。也可以使用 resource_path 函式來產生 resources 目錄下給定檔案的完整名稱路徑:

1$path = resource_path();
2 
3$path = resource_path('sass/app.scss');
1$path = resource_path();
2 
3$path = resource_path('sass/app.scss');

storage_path()

storage_path 函式回傳專案 storage 目錄的完整名稱路徑。也可以使用 storage_path 函式來產生 storage 目錄下給定檔案的完整名稱路徑:

1$path = storage_path();
2 
3$path = storage_path('app/file.txt');
1$path = storage_path();
2 
3$path = storage_path('app/file.txt');

URL

action()

action 方法可為給定的 Controller 動作產生 URL:

1use App\Http\Controllers\HomeController;
2 
3$url = action([HomeController::class, 'index']);
1use App\Http\Controllers\HomeController;
2 
3$url = action([HomeController::class, 'index']);

若該方法接受 Route 參數,請將這些 Route 參數作為第二個引數傳給該方法:

1$url = action([UserController::class, 'profile'], ['id' => 1]);
1$url = action([UserController::class, 'profile'], ['id' => 1]);

asset()

asset 方法使用目前 Request 的 Scheme (HTTP 或 HTTPS) 來產生素材 URL:

1$url = asset('img/photo.jpg');
1$url = asset('img/photo.jpg');

可以在 .env 檔案中設定 ASSET_URL 變數來設定素材 URL 的主機名稱。若你將素材放在如 Amazon S3 或其他 CDN 之類的外部服務上,就很適合這樣設定:

1// ASSET_URL=http://example.com/assets
2 
3$url = asset('img/photo.jpg'); // http://example.com/assets/img/photo.jpg
1// ASSET_URL=http://example.com/assets
2 
3$url = asset('img/photo.jpg'); // http://example.com/assets/img/photo.jpg

route()

route 函式產生給定命名 Route 的 URL:

1$url = route('route.name');
1$url = route('route.name');

若該 Route 接受參數,請將這些參數作為第二個引數傳給該方法:

1$url = route('route.name', ['id' => 1]);
1$url = route('route.name', ['id' => 1]);

預設情況下,route 函式回傳絕對 URL。若想產生相對 URL,請傳入 false 作為第三個引數給該函式:

1$url = route('route.name', ['id' => 1], false);
1$url = route('route.name', ['id' => 1], false);

secure_asset()

secure_asset 函式使用 HTTPS 為素材產生 URL:

1$url = secure_asset('img/photo.jpg');
1$url = secure_asset('img/photo.jpg');

secure_url()

secure_url 函式產生給定路徑上的完整名稱 HTTPS URL。可以傳入額外的 URL 片段給該函式的第二個引數:

1$url = secure_url('user/profile');
2 
3$url = secure_url('user/profile', [1]);
1$url = secure_url('user/profile');
2 
3$url = secure_url('user/profile', [1]);

to_route()

to_route 函式為給定的命名 Route 產生一個重新導向的 HTTP Response

1return to_route('users.show', ['user' => 1]);
1return to_route('users.show', ['user' => 1]);

若有需要,也可以傳入一個用於跳轉的 HTTP 狀態碼以及一些額外的回應標頭作為 to_route 方法的第三與第四個引數:

1return to_route('users.show', ['user' => 1], 302, ['X-Framework' => 'Laravel']);
1return to_route('users.show', ['user' => 1], 302, ['X-Framework' => 'Laravel']);

url()

url 函式可以產生給定路徑上的完整名稱 URL:

1$url = url('user/profile');
2 
3$url = url('user/profile', [1]);
1$url = url('user/profile');
2 
3$url = url('user/profile', [1]);

若未提供路徑,則會回傳 Illuminate\Routing\UrlGenerator 實體:

1$current = url()->current();
2 
3$full = url()->full();
4 
5$previous = url()->previous();
1$current = url()->current();
2 
3$full = url()->full();
4 
5$previous = url()->previous();

其他

abort()

abort 函式會擲回 HTTP Exception。HTTP Exception 會被 Exception Handler(例外處理常式) 轉譯:

1abort(403);
1abort(403);

也可以提供 Exception 訊息與要傳送給瀏覽器的自訂 HTTP Response 標頭:

1abort(403, 'Unauthorized.', $headers);
1abort(403, 'Unauthorized.', $headers);

abort_if()

abort_if 函式會在給定布林運算式取值為 true 時擲回一個 HTTP Exception:

1abort_if(! Auth::user()->isAdmin(), 403);
1abort_if(! Auth::user()->isAdmin(), 403);

abort 方法類似,我們也可以在第三個引數上提供 Exception 的 Response 文字,並在第四個引數上提供一組自訂 Response 標頭陣列。

abort_unless()

abort_unless 函式會在給定布林運算式取值為 false 時擲回一個 HTTP Exception:

1abort_unless(Auth::user()->isAdmin(), 403);
1abort_unless(Auth::user()->isAdmin(), 403);

abort 方法類似,我們也可以在第三個引數上提供 Exception 的 Response 文字,並在第四個引數上提供一組自訂 Response 標頭陣列。

app()

app 函式回傳 Service Container 實體:

1$container = app();
1$container = app();

也可以傳入一個類別或介面名稱來用 Container 解析:

1$api = app('HelpSpot\API');
1$api = app('HelpSpot\API');

auth()

auth 函式回傳 Authenticator 的實體。可以使用 auth 函式來作為 Auth Facade 的替代:

1$user = auth()->user();
1$user = auth()->user();

若有需要,可以指定要存取的 Guard 實體:

1$user = auth('admin')->user();
1$user = auth('admin')->user();

back()

back 函式產生一個指向使用者上一個瀏覽位置的[重新導向 HTTP Response]:

1return back($status = 302, $headers = [], $fallback = '/');
2 
3return back();
1return back($status = 302, $headers = [], $fallback = '/');
2 
3return back();

bcrypt()

bcrypt 方法使用 Bcrypt 來雜湊給定的值。也可以使用這個函式來作為 Hash Facade 的替代:

1$password = bcrypt('my-secret-password');
1$password = bcrypt('my-secret-password');

blank()

blank 函式判斷給定值是否為「空白(Blank)」:

1blank('');
2blank(' ');
3blank(null);
4blank(collect());
5 
6// true
7 
8blank(0);
9blank(true);
10blank(false);
11 
12// false
1blank('');
2blank(' ');
3blank(null);
4blank(collect());
5 
6// true
7 
8blank(0);
9blank(true);
10blank(false);
11 
12// false

請參考 filled 方法以瞭解與 blank 相反的方法。

broadcast()

broadcast 函式會廣播給定的 Event 給其 Listener:

1broadcast(new UserRegistered($user));
2 
3broadcast(new UserRegistered($user))->toOthers();
1broadcast(new UserRegistered($user));
2 
3broadcast(new UserRegistered($user))->toOthers();

cache()

cache 函式可用來從快取中取值。若快取中沒有給定的索引鍵,則會回傳可選的預設值:

1$value = cache('key');
2 
3$value = cache('key', 'default');
1$value = cache('key');
2 
3$value = cache('key', 'default');

可以傳入一組索引鍵 / 值配對的陣列給該函式來將項目加入快取中。也請傳入單位為秒的快取值有效期間:

1cache(['key' => 'value'], 300);
2 
3cache(['key' => 'value'], now()->addSeconds(10));
1cache(['key' => 'value'], 300);
2 
3cache(['key' => 'value'], now()->addSeconds(10));

class_uses_recursive()

class_uses_recursive 函式回傳某個類別使用的所有 Trait,包含其所有上層(Parent)類別使用的 Trait:

1$traits = class_uses_recursive(App\Models\User::class);
1$traits = class_uses_recursive(App\Models\User::class);

collect()

collect 函式使用給定值來建立一個 Collection 實體:

1$collection = collect(['taylor', 'abigail']);
1$collection = collect(['taylor', 'abigail']);

config()

config 函式可取得設定變數中的值。設定值可以通過「點 (.)」語法來存取,即包含設定檔名稱與欲存取的選項名。也可以指定設定選項不存在時要回傳的預設值:

1$value = config('app.timezone');
2 
3$value = config('app.timezone', $default);
1$value = config('app.timezone');
2 
3$value = config('app.timezone', $default);

也可以在執行階段傳入一組索引鍵 / 值配對的陣列來設定設定值。不過,請注意,該函式只會影響目前 Request 的設定值,並不會實際更新設定:

1config(['app.debug' => true]);
1config(['app.debug' => true]);

cookie 函式建立一個新的 Cookie 實體:

1$cookie = cookie('name', 'value', $minutes);
1$cookie = cookie('name', 'value', $minutes);

csrf_field()

csrf_field 函式產生一個包含 CSRF Token 的 HTML hidden 輸入欄位。舉例來說,在 Blade 語法中可這樣使用:

1{{ csrf_field() }}
1{{ csrf_field() }}

csrf_token()

csrf_token 函式可取得目前 CSRF Token 的值:

1$token = csrf_token();
1$token = csrf_token();

decrypt()

decrypt 函式會解密給定的值。可使用這個方法作為 Crypt Facade 的替代。

1$password = decrypt($value);
1$password = decrypt($value);

dd()

dd 函式可傾印給定變數,並結束目前的指令碼執行:

1dd($value);
2 
3dd($value1, $value2, $value3, ...);
1dd($value);
2 
3dd($value1, $value2, $value3, ...);

若不想結束目前的指令碼執行,請改為使用 dump 方法。

dispatch()

dispatch 方法將給定 Job 推入 Laravel 的 Job 佇列 中:

1dispatch(new App\Jobs\SendEmails);
1dispatch(new App\Jobs\SendEmails);

dispatch_sync()

dispatch_sync 方法將給定的 Job 推入到同步的 (Sync) Queue 中以立即處理該 Job:

1dispatch_sync(new App\Jobs\SendEmails);
1dispatch_sync(new App\Jobs\SendEmails);

dump()

dump 函式傾印給定的變數:

1dump($value);
2 
3dump($value1, $value2, $value3, ...);
1dump($value);
2 
3dump($value1, $value2, $value3, ...);

若想在傾印變數後停止執行指令碼,請使用 dd 函式來代替。

encrypt()

encrypt 函式會加密給定的值。可使用這個方法作為 Crypt Facade 的替代:

1$secret = encrypt('my-secret-value');
1$secret = encrypt('my-secret-value');

env()

env 函式可取得環境變數的值,或是回傳預設值:

1$env = env('APP_ENV');
2 
3$env = env('APP_ENV', 'production');
1$env = env('APP_ENV');
2 
3$env = env('APP_ENV', 'production');
exclamation

若在部署流程中執行了 config:cache 指令,應確保只有在設定檔中呼叫 env 函式。設定檔被快取後,就不會再載入 .env 檔了。所有 env 函式查詢 .env 變數的呼叫都會回傳 null

event()

event 函式將給定 Event 分派(Dispatch)給其 Listener:

1event(new UserRegistered($user));
1event(new UserRegistered($user));

fake()

fake 方法會從 Container 中解析 Faker 單例 (Singleton),很適合在 Model Factory、資料庫 Seeder、測試、打樣 View 等地方建立假資料:

1@for($i = 0; $i < 10; $i++)
2 <dl>
3 <dt>Name</dt>
4 <dd>{{ fake()->name() }}</dd>
5 
6 <dt>Email</dt>
7 <dd>{{ fake()->unique()->safeEmail() }}</dd>
8 </dl>
9@endfor
1@for($i = 0; $i < 10; $i++)
2 <dl>
3 <dt>Name</dt>
4 <dd>{{ fake()->name() }}</dd>
5 
6 <dt>Email</dt>
7 <dd>{{ fake()->unique()->safeEmail() }}</dd>
8 </dl>
9@endfor

預設情況下,fake 函式會使用 config/app.php 設定檔中的 app.faker_locale 設定選項。不過,也可以將地區選項傳入 fake 函式來指定地區。每個地區選項都會被解析為個別的單例:

1fake('nl_NL')->name()
1fake('nl_NL')->name()

filled()

filled 函式判斷給定值是否不為「空白(Blank)」:

1filled(0);
2filled(true);
3filled(false);
4 
5// true
6 
7filled('');
8filled(' ');
9filled(null);
10filled(collect());
11 
12// false
1filled(0);
2filled(true);
3filled(false);
4 
5// true
6 
7filled('');
8filled(' ');
9filled(null);
10filled(collect());
11 
12// false

請參考 blank 方法以瞭解與 filled 相反的方法。

info()

info 函式寫入 info 等級的資訊至程式的 日誌 中:

1info('Some helpful information!');
1info('Some helpful information!');

也可以傳入一組包含上下文資料的陣列給該函式:

1info('User login attempt failed.', ['id' => $user->id]);
1info('User login attempt failed.', ['id' => $user->id]);

logger()

logger 函式可用來寫入 debug 等級的訊息至日誌中:

1logger('Debug message');
1logger('Debug message');

也可以傳入一組包含上下文資料的陣列給該函式:

1logger('User has logged in.', ['id' => $user->id]);
1logger('User has logged in.', ['id' => $user->id]);

若未傳入任何值給該方法,則會回傳 Logger 實體:

1logger()->error('You are not allowed here.');
1logger()->error('You are not allowed here.');

method_field()

method_field 函式產生一個用於模擬表單 HTTP 動詞的 HTML hidden 輸入欄位。舉例來說,在 Blade 語法中可這樣使用:

1<form method="POST">
2 {{ method_field('DELETE') }}
3</form>
1<form method="POST">
2 {{ method_field('DELETE') }}
3</form>

now()

now 函式建立一個目前時間的新 Illuminate\Support\Carbon 實體:

1$now = now();
1$now = now();

old()

old 函式取得快閃存入 Session 的舊輸入值:

1$value = old('value');
2 
3$value = old('value', 'default');
1$value = old('value');
2 
3$value = old('value', 'default');

由於提供給 old 方法第二個引數的「預設值」常常都是 Eloquent Model 的屬性,因此,在 Laravel 中,我們可以直接將整個 Eloquent Model 作為第二個引數傳給 old 方法即可。當我們傳入 Eloquent Model 給 old 方法時,Laravel 會假設傳給 old 方法的第一個引數即為要當作「預設值」的 Eloquent 屬性名稱:

1{{ old('name', $user->name) }}
2 
3// 等同於...
4 
5{{ old('name', $user) }}
1{{ old('name', $user->name) }}
2 
3// 等同於...
4 
5{{ old('name', $user) }}

optional()

optional 函式接受任何的引數,並可讓你存取該物件上的屬性或呼叫該物件上的方法。若給定的物件為 null,存取屬性和方法時會回傳 null 而不是發生錯誤:

1return optional($user->address)->street;
2 
3{!! old('name', optional($user)->name) !!}
1return optional($user->address)->street;
2 
3{!! old('name', optional($user)->name) !!}

optional 函式也接受閉包作為其第二個引數。若第一個引數傳入的值不是 null 時會叫用該閉包:

1return optional(User::find($id), function (User $user) {
2 return $user->name;
3});
1return optional(User::find($id), function (User $user) {
2 return $user->name;
3});

policy()

policy 方法取得給定類別的 Policy 實體:

1$policy = policy(App\Models\User::class);
1$policy = policy(App\Models\User::class);

redirect()

redirect 函式回傳一個重新導向的 HTTP Response。若呼叫時未提供任何引數,則回傳 Redirector 實體:

1return redirect($to = null, $status = 302, $headers = [], $https = null);
2 
3return redirect('/home');
4 
5return redirect()->route('route.name');
1return redirect($to = null, $status = 302, $headers = [], $https = null);
2 
3return redirect('/home');
4 
5return redirect()->route('route.name');

report()

report 函式會使用 Exception Handler 來回報 Exception:

1report($e);
1report($e);

report 函式也接受一個字串作為其引數。若傳入字串給該函式時,report 會使用給定的字串作為訊息來建立 Exception:

1report('Something went wrong.');
1report('Something went wrong.');

report_if()

report_if 函式會在給定條件為 true 時使用 Exception Handler 來回報 Exception:

1report_if($shouldReport, $e);
2 
3report_if($shouldReport, 'Something went wrong.');
1report_if($shouldReport, $e);
2 
3report_if($shouldReport, 'Something went wrong.');

report_unless()

report_unless 函式會在給定條件為 false 時使用 Exception Handler 來回報 Exception:

1report_unless($reportingDisabled, $e);
2 
3report_unless($reportingDisabled, 'Something went wrong.');
1report_unless($reportingDisabled, $e);
2 
3report_unless($reportingDisabled, 'Something went wrong.');

request()

request 函式回傳目前的 Request 實體,或是從目前 Request 中取得輸入欄位的值:

1$request = request();
2 
3$value = request('key', $default);
1$request = request();
2 
3$value = request('key', $default);

rescue()

rescue 函式會執行給定的閉包,並 Catch 在執行時發生的所有 Exception。被 Catch 到的 Exception 會被送到 Exception Handler,不過,Request 會繼續執行:

1return rescue(function () {
2 return $this->method();
3});
1return rescue(function () {
2 return $this->method();
3});

也可以傳入第二個引數給 rescue 函式。執行閉包時若有發生 Exception,就會使用這個引數來當作回傳的「預設」值:

1return rescue(function () {
2 return $this->method();
3}, false);
4 
5return rescue(function () {
6 return $this->method();
7}, function () {
8 return $this->failure();
9});
1return rescue(function () {
2 return $this->method();
3}, false);
4 
5return rescue(function () {
6 return $this->method();
7}, function () {
8 return $this->failure();
9});

可提供一個 report 引數給 rescue 函式來判斷 Exception 是否應以 report 函式回報:

1return rescue(function () {
2 return $this->method();
3}, report: function (Throwable $throwable) {
4 return $throwable instanceof InvalidArgumentException;
5});
1return rescue(function () {
2 return $this->method();
3}, report: function (Throwable $throwable) {
4 return $throwable instanceof InvalidArgumentException;
5});

resolve()

resolve 函式使用 Service Container 來將給定的類別或介面名稱解析為實體:

1$api = resolve('HelpSpot\API');
1$api = resolve('HelpSpot\API');

response()

response 函式建立一個 Response 實體,或是取得 Response Factory 的實體:

1return response('Hello World', 200, $headers);
2 
3return response()->json(['foo' => 'bar'], 200, $headers);
1return response('Hello World', 200, $headers);
2 
3return response()->json(['foo' => 'bar'], 200, $headers);

retry()

retry 函式會嘗試執行給定的閉包,直到達到最大嘗試次數限制。若該回呼未擲回(Throw) Exception,則會回傳該回呼的回傳值。若回呼擲回 Exception,就會自動嘗試重新執行回呼。達到最大嘗試次數後,就會擲回 Exception:

1return retry(5, function () {
2 // 嘗試 5 次,每次嘗試間暫停 100ms...
3}, 100);
1return retry(5, function () {
2 // 嘗試 5 次,每次嘗試間暫停 100ms...
3}, 100);

若想自動手動計算每次長時間要暫停的毫秒數,可傳入閉包作為第三個引數給 retry 函式:

1use Exception;
2 
3return retry(5, function () {
4 // ...
5}, function (int $attempt, Exception $exception) {
6 return $attempt * 100;
7});
1use Exception;
2 
3return retry(5, function () {
4 // ...
5}, function (int $attempt, Exception $exception) {
6 return $attempt * 100;
7});

為了方便起見,也可以提供陣列作為 retry 函式的第一個引數。會使用這個真累來判斷每次嘗試間要暫停多久:

1return retry([100, 200] function () {
2 // 第一次重試時休息 100ms,第二次重試時休息 200ms...
3});
1return retry([100, 200] function () {
2 // 第一次重試時休息 100ms,第二次重試時休息 200ms...
3});

若只想在特定條件下重試,可傳入一個閉包作為第四個引數給 retry 函式:

1use Exception;
2 
3return retry(5, function () {
4 // ...
5}, 100, function (Exception $exception) {
6 return $exception instanceof RetryException;
7});
1use Exception;
2 
3return retry(5, function () {
4 // ...
5}, 100, function (Exception $exception) {
6 return $exception instanceof RetryException;
7});

session()

session 函式可用來取得或設定 Session 值:

1$value = session('key');
1$value = session('key');

可以傳入一組索引鍵 / 值配對的陣列給該函式來賦值:

1session(['chairs' => 7, 'instruments' => 3]);
1session(['chairs' => 7, 'instruments' => 3]);

若未傳入任何值給該方法,則會回傳 Session Store 實體:

1$value = session()->get('key');
2 
3session()->put('key', $value);
1$value = session()->get('key');
2 
3session()->put('key', $value);

tap()

tap 方法接受兩個引數:任意值 $value、以及一個閉包。$value 會被傳入閉包中,然後 tap 方法會回傳 $value 的值。閉包的回傳值沒有任何影響:

1$user = tap(User::first(), function (User $user) {
2 $user->name = 'taylor';
3 
4 $user->save();
5});
1$user = tap(User::first(), function (User $user) {
2 $user->name = 'taylor';
3 
4 $user->save();
5});

若未傳入閉包給 tap 函式,則可呼叫任何給定 $value 上的方法。無論呼叫的方法回傳什麼值,在此處都會回傳 $value。舉例來說,Eloquent update 方法一般會回傳整數。不過,若我們可以將 update 方法的呼叫串在 tap 函式後方,來強制把該方法的回傳值改為 Model 實體:

1$user = tap($user)->update([
2 'name' => $name,
3 'email' => $email,
4]);
1$user = tap($user)->update([
2 'name' => $name,
3 'email' => $email,
4]);

若要將 tap 方法加到類別上,可以將 Illuminate\Support\Traits\Tappable Trait 加到類別中。該 Trait 的 tap 方法接受一個閉包作為其唯一的引數。物件實體本身會被傳入該閉包中,並由 tap 方法回傳:

1return $user->tap(function (User $user) {
2 // ...
3});
1return $user->tap(function (User $user) {
2 // ...
3});

throw_if()

throw_if 函式會在給定布林運算式取值為 true 時擲回一個 Exception:

1throw_if(! Auth::user()->isAdmin(), AuthorizationException::class);
2 
3throw_if(
4 ! Auth::user()->isAdmin(),
5 AuthorizationException::class,
6 'You are not allowed to access this page.'
7);
1throw_if(! Auth::user()->isAdmin(), AuthorizationException::class);
2 
3throw_if(
4 ! Auth::user()->isAdmin(),
5 AuthorizationException::class,
6 'You are not allowed to access this page.'
7);

throw_unless()

throw_unless 函式會在給定布林運算式取值為 false 時擲回一個 Exception:

1throw_unless(Auth::user()->isAdmin(), AuthorizationException::class);
2 
3throw_unless(
4 Auth::user()->isAdmin(),
5 AuthorizationException::class,
6 'You are not allowed to access this page.'
7);
1throw_unless(Auth::user()->isAdmin(), AuthorizationException::class);
2 
3throw_unless(
4 Auth::user()->isAdmin(),
5 AuthorizationException::class,
6 'You are not allowed to access this page.'
7);

today()

today 函式建立一個目前日期的新 Illuminate\Support\Carbon 實體:

1$today = today();
1$today = today();

trait_uses_recursive()

trait_uses_recursive 函式回傳該 Trait 使用的所有 Trait:

1$traits = trait_uses_recursive(\Illuminate\Notifications\Notifiable::class);
1$traits = trait_uses_recursive(\Illuminate\Notifications\Notifiable::class);

transform()

transform 函式會在給定值不為空白(Blank)時執行閉包,並回傳該閉包的回傳值:

1$callback = function (int $value) {
2 return $value * 2;
3};
4 
5$result = transform(5, $callback);
6 
7// 10
1$callback = function (int $value) {
2 return $value * 2;
3};
4 
5$result = transform(5, $callback);
6 
7// 10

可傳入預設值或閉包作為第三個引數給該函式。若給定值為空白時,會回傳這個值:

1$result = transform(null, $callback, 'The value is blank');
2 
3// The value is blank
1$result = transform(null, $callback, 'The value is blank');
2 
3// The value is blank

validator()

validator 函式使用給定的引數來建立一個新的 Validator 實體。可以用來當作是 Validator Facade 的替代:

1$validator = validator($data, $rules, $messages);
1$validator = validator($data, $rules, $messages);

value()

value 函式會回傳給定的值。不過,若傳入閉包給該函式,會執行該閉包並回傳該閉包的值:

1$result = value(true);
2 
3// true
4 
5$result = value(function () {
6 return false;
7});
8 
9// false
1$result = value(true);
2 
3// true
4 
5$result = value(function () {
6 return false;
7});
8 
9// false

也可以傳入更多引數給 value 函式。若第一個引數為閉包,則這些其他的引數會被作為引數來傳給該閉包。若不是閉包,則這些引數會被忽略:

1$result = value(function (string $name) {
2 return $name;
3}, 'Taylor');
4 
5// 'Taylor'
1$result = value(function (string $name) {
2 return $name;
3}, 'Taylor');
4 
5// 'Taylor'

view()

view 函式可取得一個 View 實體:

1return view('auth.login');
1return view('auth.login');

with()

with 函式會回傳給定的值。若有傳入閉包作為第二個引數該函式,會執行該閉包並回傳該閉包的回傳值:

1$callback = function (mixed $value) {
2 return is_numeric($value) ? $value * 2 : 0;
3};
4 
5$result = with(5, $callback);
6 
7// 10
8 
9$result = with(null, $callback);
10 
11// 0
12 
13$result = with(5, null);
14 
15// 5
1$callback = function (mixed $value) {
2 return is_numeric($value) ? $value * 2 : 0;
3};
4 
5$result = with(5, $callback);
6 
7// 10
8 
9$result = with(null, $callback);
10 
11// 0
12 
13$result = with(5, null);
14 
15// 5

其他公用程式

效能評定 (Benchmark)

有時候,我們會想快速地測試程式中某個部分的效能。這種時候,可以使用 Benchmark 輔助類別來測量完成給定回呼所需的毫秒數:

1<?php
2 
3use App\Models\User;
4use Illuminate\Support\Benchmark;
5 
6Benchmark::dd(fn () => User::find(1)); // 0.1 ms
7 
8Benchmark::dd([
9 'Scenario 1' => fn () => User::count(), // 0.5 ms
10 'Scenario 2' => fn () => User::all()->count(), // 20.0 ms
11]);
1<?php
2 
3use App\Models\User;
4use Illuminate\Support\Benchmark;
5 
6Benchmark::dd(fn () => User::find(1)); // 0.1 ms
7 
8Benchmark::dd([
9 'Scenario 1' => fn () => User::count(), // 0.5 ms
10 'Scenario 2' => fn () => User::all()->count(), // 20.0 ms
11]);

預設情況下,給定回呼擲回被執行一次 (即一次迭代),而執行所花費的時間會被顯示在瀏覽器或主控台上。

若想讓該回呼被執行多次,可使用該方法的第二個引數來指定該回呼要被呼叫的迭代數。執行該回呼超過一次時,Benchmark 類別會回傳在各個迭代間執行該回呼所花費的平均毫秒數:

1Benchmark::dd(fn () => User::count(), iterations: 10); // 0.5 ms
1Benchmark::dd(fn () => User::count(), iterations: 10); // 0.5 ms

有時候,我們可能會需要針對回呼進行基準測試 (Benchmark),並取得該回呼的回傳值。 value 方法將回傳一個元組 (Tuple),其中包含該回呼的回傳值,以及執行該回呼所花費的毫秒數:

1[$count, $duration] = Benchmark::value(fn () => User::count());
1[$count, $duration] = Benchmark::value(fn () => User::count());

Date - 日期

Laravel 包含了 Carbon 函式庫。Carbon 是一個強大的日期與時間操作函式庫。若要建立新的 Carbon 實體,可呼叫 now 函式。該函式在 Laravel 專案中是全域函式,隨處都可用:

1$now = now();
1$now = now();

或者,也可以使用 Illuminate\Support\Carbon 類別來建立新的 Carbon 實體:

1use Illuminate\Support\Carbon;
2 
3$now = Carbon::now();
1use Illuminate\Support\Carbon;
2 
3$now = Carbon::now();

請參考 Carbon 的官方說明文件以進一步瞭解 Carbon 與其功能。

Lottery

Laravel 的 Lottery 類別可用來依據給定的機率執行回呼。這個類別特別適用於想只在特定比例的連入 Request 內執行程式時:

1use Illuminate\Support\Lottery;
2 
3Lottery::odds(1, 20)
4 ->winner(fn () => $user->won())
5 ->loser(fn () => $user->lost())
6 ->choose();
1use Illuminate\Support\Lottery;
2 
3Lottery::odds(1, 20)
4 ->winner(fn () => $user->won())
5 ->loser(fn () => $user->lost())
6 ->choose();

也可以將 Laravel 的 Lottery 類別與其他 Laravel 功能組合使用。舉例來說,當資料庫查詢速度慢時,我們可以只將其中一部分的查詢回報給 Exception Handler。此外,由於 Lottery 類別是 callable,因此我們可以將 Lottery 實體傳給任何接受 callable 的方法:

1use Carbon\CarbonInterval;
2use Illuminate\Support\Facades\DB;
3use Illuminate\Support\Lottery;
4 
5DB::whenQueryingForLongerThan(
6 CarbonInterval::seconds(2),
7 Lottery::odds(1, 100)->winner(fn () => report('Querying > 2 seconds.')),
8);
1use Carbon\CarbonInterval;
2use Illuminate\Support\Facades\DB;
3use Illuminate\Support\Lottery;
4 
5DB::whenQueryingForLongerThan(
6 CarbonInterval::seconds(2),
7 Lottery::odds(1, 100)->winner(fn () => report('Querying > 2 seconds.')),
8);

測試 Lottery

Laravel 提供了一些簡單的方法,能讓你輕鬆測試專案的 Lottery 呼叫:

1// Lottery 結果永遠為「贏」...
2Lottery::alwaysWin();
3 
4// Lottery 結果永遠為「輸」...
5Lottery::alwaysLose();
6 
7// Lottery 的結果會先是「贏」,然後是「輸」,接著會回到其正常的行為...
8Lottery::fix([true, false]);
9 
10// Lottery 會回到正常行為...
11Lottery::determineResultsNormally();
1// Lottery 結果永遠為「贏」...
2Lottery::alwaysWin();
3 
4// Lottery 結果永遠為「輸」...
5Lottery::alwaysLose();
6 
7// Lottery 的結果會先是「贏」,然後是「輸」,接著會回到其正常的行為...
8Lottery::fix([true, false]);
9 
10// Lottery 會回到正常行為...
11Lottery::determineResultsNormally();

Pipeline

Laravel 的 Pipeline Facade 是一個能將給定輸入「Pipe(輸送)」進一系列 Invokable 類別、閉包、或 Callable 管道的便利功能,能讓管道中一系列類別都有機會檢查並修改輸入,然後再繼續呼叫管道中的下一個 Callable:

1use Closure;
2use App\Models\User;
3use Illuminate\Support\Facades\Pipeline;
4 
5$user = Pipeline::send($user)
6 ->through([
7 function (User $user, Closure $next) {
8 // ...
9 
10 return $next($user);
11 },
12 function (User $user, Closure $next) {
13 // ...
14 
15 return $next($user);
16 },
17 ])
18 ->then(fn (User $user) => $user);
1use Closure;
2use App\Models\User;
3use Illuminate\Support\Facades\Pipeline;
4 
5$user = Pipeline::send($user)
6 ->through([
7 function (User $user, Closure $next) {
8 // ...
9 
10 return $next($user);
11 },
12 function (User $user, Closure $next) {
13 // ...
14 
15 return $next($user);
16 },
17 ])
18 ->then(fn (User $user) => $user);

就像這樣,管道中的各個 Invokable 類別或閉包都會收到輸入值以及一個 $next 閉包。呼叫 $next 閉包就會呼叫管道中的下一個 Callable。讀者可能已經注意到,這個寫法跟 Middleware 非常類似。

當管道中的最後一個 Callable 呼叫了 $next 閉包,就會呼叫傳送給 then 中的 Callable。一般來說,這個 Callable 只會回傳給定的輸入。

當然,就像剛才討論過的,除了 Closure 外,也可以傳入 Invokable Class 給 Pipeline。若提供了 Class 名稱,則該 Class 會被 Laravel 的 Service Container 初始化,以將相依類別注入到 Invokable Class 中:

1$user = Pipeline::send($user)
2 ->through([
3 GenerateProfilePhoto::class,
4 ActivateSubscription::class,
5 SendWelcomeEmail::class,
6 ])
7 ->then(fn (User $user) => $user);
1$user = Pipeline::send($user)
2 ->through([
3 GenerateProfilePhoto::class,
4 ActivateSubscription::class,
5 SendWelcomeEmail::class,
6 ])
7 ->then(fn (User $user) => $user);

Sleep

Laravel 的 Sleep 類別是一個輕便的 Wrapper(包裝),將 PHP 的原生 sleepunsleep 函式包裝起來,提供更強的可測試性,並同時提供對開發人員更友善的時間處理 API:

1use Illuminate\Support\Sleep;
2 
3$waiting = true;
4 
5while ($waiting) {
6 Sleep::for(1)->second();
7 
8 $waiting = /* ... */;
9}
1use Illuminate\Support\Sleep;
2 
3$waiting = true;
4 
5while ($waiting) {
6 Sleep::for(1)->second();
7 
8 $waiting = /* ... */;
9}

Sleep 類別提供了多個方法,能讓你處理不同單位的時間:

1// 暫停執行 90 秒...
2Sleep::for(1.5)->minutes();
3 
4// 暫停執行 2 秒...
5Sleep::for(2)->seconds();
6 
7// 暫停執行 500 微秒...
8Sleep::for(500)->milliseconds();
9 
10// 暫停執行 5,000 毫秒...
11Sleep::for(5000)->microseconds();
12 
13// 暫停直到給定時間...
14Sleep::until(now()->addMinute());
15 
16// PHP 原生「sleep」方法的別名...
17Sleep::sleep(2);
18 
19// PHP 原生「usleep」方法的別名...
20Sleep::usleep(5000);
1// 暫停執行 90 秒...
2Sleep::for(1.5)->minutes();
3 
4// 暫停執行 2 秒...
5Sleep::for(2)->seconds();
6 
7// 暫停執行 500 微秒...
8Sleep::for(500)->milliseconds();
9 
10// 暫停執行 5,000 毫秒...
11Sleep::for(5000)->microseconds();
12 
13// 暫停直到給定時間...
14Sleep::until(now()->addMinute());
15 
16// PHP 原生「sleep」方法的別名...
17Sleep::sleep(2);
18 
19// PHP 原生「usleep」方法的別名...
20Sleep::usleep(5000);

若要輕鬆組合搭配不同單位的時間,可使用 and 方法:

1Sleep::for(1)->second()->and(10)->milliseconds();
1Sleep::for(1)->second()->and(10)->milliseconds();

測試 Sleep

在測試有使用 Sleep 類別或 PHP 原生 sleep 函式的程式碼時,測試也會暫停執行。可想而知,這樣會使測試套件明顯變慢。舉例來說,假設我們要測試下列程式碼:

1$waiting = /* ... */;
2 
3$seconds = 1;
4 
5while ($waiting) {
6 Sleep::for($seconds++)->seconds();
7 
8 $waiting = /* ... */;
9}
1$waiting = /* ... */;
2 
3$seconds = 1;
4 
5while ($waiting) {
6 Sleep::for($seconds++)->seconds();
7 
8 $waiting = /* ... */;
9}

一般來說,測試此程式碼會花費 至少 一秒鐘。所幸,Sleep 類別能讓我們「模擬 (Fake)」暫停,好讓我們的測試套件能保持快速:

1public function test_it_waits_until_ready()
2{
3 Sleep::fake();
4 
5 // ...
6}
1public function test_it_waits_until_ready()
2{
3 Sleep::fake();
4 
5 // ...
6}

在模擬 (Fake) Sleep Class 時,會跳過實際的執行暫停,因此會使測試變快。

一旦模擬了 Sleep 類別,我們就可以針對預期應產生的「Sleep」進行 Assertion 判斷。為了說明如何進行 Assertion,我們先假設我們要測試一個會暫停執行 3 次的程式碼,每次暫停都會增加 1 秒鐘。使用 assertSequence 方法,就可以測試我們的程式碼是否已「Sleep」適當的時間,同時又能保持讓我們的程式快速執行:

1public function test_it_checks_if_ready_four_times()
2{
3 Sleep::fake();
4 
5 // ...
6 
7 Sleep::assertSequence([
8 Sleep::for(1)->second(),
9 Sleep::for(2)->seconds(),
10 Sleep::for(3)->seconds(),
11 ]);
12}
1public function test_it_checks_if_ready_four_times()
2{
3 Sleep::fake();
4 
5 // ...
6 
7 Sleep::assertSequence([
8 Sleep::for(1)->second(),
9 Sleep::for(2)->seconds(),
10 Sleep::for(3)->seconds(),
11 ]);
12}

當然,Sleep 類別還提供了各種其他的 Assertion 判斷能讓你在測試中使用:

1use Carbon\CarbonInterval as Duration;
2use Illuminate\Support\Sleep;
3 
4// 判斷呼叫了 Sleep 3 次...
5Sleep::assertSleptTimes(3);
6 
7// 判斷 Sleep 暫停的時長...
8Sleep::assertSlept(function (Duration $duration): bool {
9 return /* ... */;
10}, times: 1);
11 
12// 判斷 Sleep Class 是否從未被呼叫...
13Sleep::assertNeverSlept();
14 
15// 判斷即使有呼叫 Sleep,也沒有發生暫停執行...
16Sleep::assertInsomniac();
1use Carbon\CarbonInterval as Duration;
2use Illuminate\Support\Sleep;
3 
4// 判斷呼叫了 Sleep 3 次...
5Sleep::assertSleptTimes(3);
6 
7// 判斷 Sleep 暫停的時長...
8Sleep::assertSlept(function (Duration $duration): bool {
9 return /* ... */;
10}, times: 1);
11 
12// 判斷 Sleep Class 是否從未被呼叫...
13Sleep::assertNeverSlept();
14 
15// 判斷即使有呼叫 Sleep,也沒有發生暫停執行...
16Sleep::assertInsomniac();

有時,我們會需要在模擬 Sleep 發生時,執行一些動作。若要在發生模擬 Sleep 時執行動作,可提供規格回呼給 whenFakingSleep 方法。在下方的範例中,我們使用了 Laravel 的時間操作輔助函式來在每個 Sleep 發生的時候立即更改時間:

1use Carbon\CarbonInterval as Duration;
2 
3$this->freezeTime();
4 
5Sleep::fake();
6 
7Sleep::whenFakingSleep(function (Duration $duration) {
8 // 模擬 Sleep 時更改時間...
9 $this->travel($duration->totalMilliseconds)->milliseconds();
10});
1use Carbon\CarbonInterval as Duration;
2 
3$this->freezeTime();
4 
5Sleep::fake();
6 
7Sleep::whenFakingSleep(function (Duration $duration) {
8 // 模擬 Sleep 時更改時間...
9 $this->travel($duration->totalMilliseconds)->milliseconds();
10});

在 Laravel 內部會在需要暫停執行時使用 Sleep Class。舉例來說,retry 輔助函式會在暫停時使用 Sleep Class,以在使用該輔助函式時提升可測試性。

翻譯進度
100% 已翻譯
更新時間:
2024年6月30日 上午8:27:00 [世界標準時間]
翻譯人員:
  • cornch
幫我們翻譯此頁

留言

尚無留言

“Laravel” is a Trademark of Taylor Otwell.
The source documentation is released under MIT license. See laravel/docs on GitHub for details.
The translated documentations are released under MIT license. See cornch/laravel-docs-l10n on GitHub for details.