翻译进度
43
分块数量
8
参与人数

辅助函数

这是一篇协同翻译的文章,你可以点击『我来翻译』按钮来参与翻译。


数组与对象

Arr::accessible()

Arr::accessible 方法用于判断给定的值是否可通过数组方式访问:

use Illuminate\Support\Arr;
use Illuminate\Support\Collection;

$isAccessible = Arr::accessible(['a' => 1, 'b' => 2]);

// true

$isAccessible = Arr::accessible(new Collection);

// true

$isAccessible = Arr::accessible('abc');

// false

$isAccessible = Arr::accessible(new stdClass);

// false

Arr::add()

Arr::add 方法会在数组中指定键不存在或对应值为 null 时,向数组添加该键值对:

use Illuminate\Support\Arr;

$array = Arr::add(['name' => 'Desk'], 'price', 100);

// ['name' => 'Desk', 'price' => 100]

$array = Arr::add(['name' => 'Desk', 'price' => null], 'price', 100);

// ['name' => 'Desk', 'price' => 100]

Arr::array()

Arr::array 方法使用「点」语法从深层嵌套数组中获取值(与 Arr::get() 类似),但如果请求的值不是数组,则会抛出 InvalidArgumentException 异常:

use Illuminate\Support\Arr;

$array = ['name' => 'Joe', 'languages' => ['PHP', 'Ruby']];

$value = Arr::array($array, 'languages');

// ['PHP', 'Ruby']

$value = Arr::array($array, 'name');

// 抛出 InvalidArgumentException 异常

Arr::boolean()

Arr::boolean 方法使用「点」语法从深层嵌套数组中获取值(与 Arr::get() 类似),但如果请求的值不是布尔值,则会抛出 InvalidArgumentException 异常:

use Illuminate\Support\Arr;

$array = ['name' => 'Joe', 'available' => true];

$value = Arr::boolean($array, 'available');

// true

$value = Arr::boolean($array, 'name');

// 抛出 InvalidArgumentException 异常

Arr::collapse()

dszhxb 翻译于 4个月前

Arr::collapse方法,把数组里的所有子数组合并成一个新数组。

use Illuminate\Support\Arr;

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

// [1, 2, 3, 4, 5, 6, 7, 8, 9]

Arr::crossJoin()

Arr::crossJoin方法会把几个数组交叉放在一起,把所有可能的组合全部列出来。

use Illuminate\Support\Arr;

$matrix = Arr::crossJoin([1, 2], ['a', 'b']);

/*
    [
        [1, 'a'],
        [1, 'b'],
        [2, 'a'],
        [2, 'b'],
    ]
*/

$matrix = Arr::crossJoin([1, 2], ['a', 'b'], ['I', 'II']);

/*
    [
        [1, 'a', 'I'],
        [1, 'a', 'II'],
        [1, 'b', 'I'],
        [1, 'b', 'II'],
        [2, 'a', 'I'],
        [2, 'a', 'II'],
        [2, 'b', 'I'],
        [2, 'b', 'II'],
    ]
*/

Arr::divide()

Arr::divide方法把一个数组返回两个数组,一个包含给定数组的键,另一个包含给定数组的值。

use Illuminate\Support\Arr;

[$keys, $values] = Arr::divide(['name' => 'Desk']);

// $keys: ['name']

// $values: ['Desk']

Arr::dot()

Arr::dot方法多维数组展平为单层数组,层级用「.」隔开,拼成字符串,「.」语法表示原来的层级。

use Illuminate\Support\Arr;

$array = ['products' => ['desk' => ['price' => 100]]];

$flattened = Arr::dot($array);

// ['products.desk.price' => 100]

Arr::except()

Arr::except方法从数组中移除指定的键值对。

use Illuminate\Support\Arr;

$array = ['name' => 'Desk', 'price' => 100];

$filtered = Arr::except($array, ['price']);

// ['name' => 'Desk']

Arr::exists()

Arr::exists方法检查给定键是否存在于数组中,存在返回true,不存在返回false

use Illuminate\Support\Arr;

$array = ['name' => 'John Doe', 'age' => 17];

$exists = Arr::exists($array, 'name');

// true

$exists = Arr::exists($array, 'salary');

// false

不高兴和没头脑 翻译于 3个月前

Arr::first()

Arr::first方法用于获取数组里首个满足指定条件的元素。

use Illuminate\Support\Arr;

$array = [100, 200, 300];

$first = Arr::first($array, function (int $value, int $key) {
    return $value >= 150;
});

// 200

还可以将默认值作为第三个参数传递给该方法。当数组里没有任何元素满足条件时,方法就会直接返回这个默认值。

use Illuminate\Support\Arr;

$first = Arr::first($array, $callback, $default);

Arr::flatten()

Arr::flatten方法将一个多维数组展平成单层数组。

use Illuminate\Support\Arr;

$array = ['name' => 'Joe', 'languages' => ['PHP', 'Ruby']];

$flattened = Arr::flatten($array);

// ['Joe', 'PHP', 'Ruby']

Arr::float()

Arr::float方法使用「.」语法从深层嵌套数组里取值(与 Arr::get() 相同),只有当键存在且对应值「不是 float类型」时,才会抛出 InvalidArgumentException

use Illuminate\Support\Arr;

$array = ['name' => 'Joe', 'balance' => 123.45];

$value = Arr::float($array, 'balance');

// 123.45

$value = Arr::float($array, 'name');

// throws InvalidArgumentException

Arr::forget()

Arr::forget方法使用「.」语法定位并删除深层嵌套数组中的指定键值对。注意:只会移除目标那一层,若因此导致父级为空数组,父级本身仍会保留。

use Illuminate\Support\Arr;

$array = ['products' => ['desk' => ['price' => 100]]];

Arr::forget($array, 'products.desk');

// ['products' => []]

Arr::from()

Arr::from方法会把各种输入统一转成普通 PHP 数组,支持数组、对象以及几个常见的Laravel接口,如Arrayable,Enumerable,Jsonable,JsonSerializable。甚至TraversableWeakMap,它都能搞定。

use Illuminate\Support\Arr;

//标准对象 → 数组
Arr::from((object) ['foo' => 'bar']); // ['foo' => 'bar']

// 实现了 Jsonable 的自定义对象 → 先转 JSON 再转数组
class TestJsonableObject implements Jsonable
{
    public function toJson($options = 0)
    {
        return json_encode(['foo' => 'bar']);
    }
}

Arr::from(new TestJsonableObject); // ['foo' => 'bar']
不高兴和没头脑 翻译于 3个月前

Arr::get()

Arr::get 方法使用 “.” 表示法从深度嵌套数组中检索值:

use Illuminate\Support\Arr;

$array = ['products' => ['desk' => ['price' => 100]]];

$price = Arr::get($array, 'products.desk.price');

// 100

Arr::get 方法还接受一个默认值,如果指定的键不在数组中,则返回该默认值:

use Illuminate\Support\Arr;

$discount = Arr::get($array, 'products.desk.discount', 0);

// 0

Arr::has()

Arr::has 方法使用 “.” 表示法检查给定的一个或多个元素是否存在于数组中:

use Illuminate\Support\Arr;

$array = ['product' => ['name' => 'Desk', 'price' => 100]];

$contains = Arr::has($array, 'product.name');

// true

$contains = Arr::has($array, ['product.price', 'product.discount']);

// false

Arr::hasAll()

Arr::hasAll 方法使用 “.” 表示法来确定给定数组中是否存在所有指定的键:

use Illuminate\Support\Arr;

$array = ['name' => 'Taylor', 'language' => 'PHP'];

Arr::hasAll($array, ['name']); // true
Arr::hasAll($array, ['name', 'language']); // true
Arr::hasAll($array, ['name', 'IDE']); // false

Arr::hasAny()

Arr::hasAny 方法使用 “.” 表示法检查给定集合中的任何元素是否存在于数组中:

use Illuminate\Support\Arr;

$array = ['product' => ['name' => 'Desk', 'price' => 100]];

$contains = Arr::hasAny($array, 'product.name');

// true

$contains = Arr::hasAny($array, ['product.name', 'product.discount']);

// true

$contains = Arr::hasAny($array, ['category', 'product.discount']);

// false

Arr::integer()

Arr::integer 方法使用 “.” 表示法从深度嵌套数组中检索值(就像 Arr::get() 一样),但如果请求的值不是 int ,则会抛出 InvalidArgumentException 异常:

use Illuminate\Support\Arr;

$array = ['name' => 'Joe', 'age' => 42];

$value = Arr::integer($array, 'age');

// 42

$value = Arr::integer($array, 'name');

// throws InvalidArgumentException
SuperEggs 翻译于 3周前

Arr::isAssoc()

如果提供的数组是一个关联数组,那么Arr::isAssoc 方法将返回 true 。 如果一个数组没有从 0 开始的连续数值键,可以被认为是“关联的”:

use Illuminate\Support\Arr;

$isAssoc = Arr::isAssoc(['product' => ['name' => 'Desk', 'price' => 100]]);

// true

$isAssoc = Arr::isAssoc([1, 2, 3]);

// false

Arr::isList()

如果提供的数组的键是从 0 开始的连续数值键,那么 Arr::isList 方法将返回 true

use Illuminate\Support\Arr;

$isList = Arr::isList(['foo', 'bar', 'baz']);

// true

$isList = Arr::isList(['product' => ['name' => 'Desk', 'price' => 100]]);

// false

Arr::join()

Arr::join 方法将数组元素通过一个字符串拼接起来。通过方法的第二个参数,你可以指定数组最后一个元素的拼接字符串:

use Illuminate\Support\Arr;

$array = ['Tailwind', 'Alpine', 'Laravel', 'Livewire'];

$joined = Arr::join($array, ', ');

// Tailwind, Alpine, Laravel, Livewire

$joined = Arr::join($array, ', ', ' and ');

// Tailwind, Alpine, Laravel and Livewire

Arr::keyBy()

Arr::keyBy 方法将按照提供的键对数组进行加键。如果多个元素存在相同的键,则只有最后一个元素出现在新数组中:

use Illuminate\Support\Arr;

$array = [
    ['product_id' => 'prod-100', 'name' => 'Desk'],
    ['product_id' => 'prod-200', 'name' => 'Chair'],
];

$keyed = Arr::keyBy($array, 'product_id');

/*
    [
        'prod-100' => ['product_id' => 'prod-100', 'name' => 'Desk'],
        'prod-200' => ['product_id' => 'prod-200', 'name' => 'Chair'],
    ]
*/

Arr::last()

Arr::last 方法返回数组中最后一个符合条件的元素:

use Illuminate\Support\Arr;

$array = [100, 200, 300, 110];

$last = Arr::last($array, function (int $value, int $key) {
    return $value >= 150;
});

// 300
maxlcoder 翻译于 3周前

将一个默认值作为第三个参数传入该方法。当数组中没有值符合条件时将返回该默认值:

use Illuminate\Support\Arr;

$last = Arr::last($array, $callback, $default);

Arr::map()

Arr::map 方法遍历数组并将每个元素的值和键传递给回调函数。数组将会被回调函数的返回值替代:

use Illuminate\Support\Arr;

$array = ['first' => 'james', 'last' => 'kirk'];

$mapped = Arr::map($array, function (string $value, string $key) {
    return ucfirst($value);
});

// ['first' => 'James', 'last' => 'Kirk']

Arr::mapSpread()

Arr::mapSpread 方法遍历数组,将每个嵌套的元素传递给闭包。这个闭包可以自由修改元素并返回,从而形成一个由修改后元素组成的新数组:

use Illuminate\Support\Arr;

$array = [
    [0, 1],
    [2, 3],
    [4, 5],
    [6, 7],
    [8, 9],
];

$mapped = Arr::mapSpread($array, function (int $even, int $odd) {
    return $even + $odd;
});

/*
    [1, 5, 9, 13, 17]
*/

Arr::mapWithKeys()

Arr::mapWithKeys 方法遍历数组并将每个值都传递给指定的回调函数。这个回调函数应该返回一个包含单个键值对的关联数组:

use Illuminate\Support\Arr;

$array = [
    [
        'name' => 'John',
        'department' => 'Sales',
        'email' => 'john@example.com',
    ],
    [
        'name' => 'Jane',
        'department' => 'Marketing',
        'email' => 'jane@example.com',
    ]
];

$mapped = Arr::mapWithKeys($array, function (array $item, int $key) {
    return [$item['email'] => $item['name']];
});

/*
    [
        'john@example.com' => 'John',
        'jane@example.com' => 'Jane',
    ]
*/

Arr::only()

Arr::only 方法从指定的数组中返回特定键值对:

use Illuminate\Support\Arr;

$array = ['name' => 'Desk', 'price' => 100, 'orders' => 10];

$slice = Arr::only($array, ['name', 'price']);

// ['name' => 'Desk', 'price' => 100]
maxlcoder 翻译于 2周前

Arr::partition()

Arr::partition 方法可以结合 PHP 数组结构来分离数组中符合条件和不符条件的元素:

<?php

use Illuminate\Support\Arr;

$numbers = [1, 2, 3, 4, 5, 6];

[$underThree, $equalOrAboveThree] = Arr::partition($numbers, function (int $i) {
    return $i < 3;
});

dump($underThree);

// [1, 2]

dump($equalOrAboveThree);

// [3, 4, 5, 6]

Arr::pluck()

Arr::pluck 方法从数组中检索给定键的全部值:

use Illuminate\Support\Arr;

$array = [
    ['developer' => ['id' => 1, 'name' => 'Taylor']],
    ['developer' => ['id' => 2, 'name' => 'Abigail']],
];

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

// ['Taylor', 'Abigail']

你也可以指定生产列表的键:

use Illuminate\Support\Arr;

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

// [1 => 'Taylor', 2 => 'Abigail']

Arr::prepend()

Arr::prepend 方法将会在数组头部添加一个元素:

use Illuminate\Support\Arr;

$array = ['one', 'two', 'three', 'four'];

$array = Arr::prepend($array, 'zero');

// ['zero', 'one', 'two', 'three', 'four']

如果需要,你也可以指定这个值对应的键:

use Illuminate\Support\Arr;

$array = ['price' => 100];

$array = Arr::prepend($array, 'Desk', 'name');

// ['name' => 'Desk', 'price' => 100]

Arr::prependKeysWith()

Arr::prependKeysWith 对关联数组的全部键都添加一个指定的前缀:

use Illuminate\Support\Arr;

$array = [
    'name' => 'Desk',
    'price' => 100,
];

$keyed = Arr::prependKeysWith($array, 'product.');

/*
    [
        'product.name' => 'Desk',
        'product.price' => 100,
    ]
*/

Arr::pull()

Arr::pull 方法从数组中返回并删除一个键值对:

use Illuminate\Support\Arr;

$array = ['name' => 'Desk', 'price' => 100];

$name = Arr::pull($array, 'name');

// $name: Desk

// $array: ['price' => 100]
maxlcoder 翻译于 2周前

方法第三个参数传一个默认值。则这个值在键不存在时返回:

use Illuminate\Support\Arr;

$value = Arr::pull($array, $key, $default);

Arr::query()

Arr::query 方法将数组转换为查询字符串(URL 问号后的部分 ):

use Illuminate\Support\Arr;

$array = [
    'name' => 'Taylor',
    'order' => [
        'column' => 'created_at',
        'direction' => 'desc'
    ]
];

Arr::query($array);

// name=Taylor&order[column]=created_at&order[direction]=desc

Arr::random()

Arr::random 方法从数组中随机返回一个值:

use Illuminate\Support\Arr;

$array = [1, 2, 3, 4, 5];

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

// 4 - (retrieved randomly)

你可以通过可选的第二个参数来指定返回的元素数量。注意当提供这个参数时,即使只需要一个元素它也会返回一个数组:

use Illuminate\Support\Arr;

$items = Arr::random($array, 2);

// [2, 5] - (retrieved randomly)

Arr::reject()

Arr::reject 方法通过闭包来移除数组中的元素:

use Illuminate\Support\Arr;

$array = [100, '200', 300, '400', 500];

$filtered = Arr::reject($array, function (string|int $value, int $key) {
    return is_string($value);
});

// [0 => 100, 2 => 300, 4 => 500]

Arr::select()

Arr::select 方法从一个数组中筛选出一个数组:

use Illuminate\Support\Arr;

$array = [
    ['id' => 1, 'name' => 'Desk', 'price' => 200],
    ['id' => 2, 'name' => 'Table', 'price' => 150],
    ['id' => 3, 'name' => 'Chair', 'price' => 300],
];

Arr::select($array, ['name', 'price']);

// [['name' => 'Desk', 'price' => 200], ['name' => 'Table', 'price' => 150], ['name' => 'Chair', 'price' => 300]]

maxlcoder 翻译于 2周前

Arr::set()

Arr::set 该方法使用 “点” 符号在深层嵌套数组中设置一个值:

use Illuminate\Support\Arr;

$array = ['products' => ['desk' => ['price' => 100]]];

Arr::set($array, 'products.desk.price', 200);

// ['products' => ['desk' => ['price' => 200]]]

Arr::shuffle()

Arr::shuffle 该方法会随机打乱数组中的元素:

use Illuminate\Support\Arr;

$array = Arr::shuffle([1, 2, 3, 4, 5]);

// [3, 2, 5, 1, 4] - (随机生成)

Arr::sole()

Arr::sole 该方法使用给定的闭包从数组中获取单个值。如果数组中有多个值与给定的真值测试匹配,将会抛出 Illuminate\Support\MultipleItemsFoundException 异常。如果没有值与真值测试匹配,将会抛出 Illuminate\Support\ItemNotFoundException 异常:

use Illuminate\Support\Arr;

$array = ['Desk', 'Table', 'Chair'];

$value = Arr::sole($array, fn (string $value) => $value === 'Desk');

// 'Desk'

Arr::sort()

Arr::sort 该方法会按数组的值对数组进行排序:

use Illuminate\Support\Arr;

$array = ['Desk', 'Table', 'Chair'];

$sorted = Arr::sort($array);

// ['Chair', 'Desk', 'Table']

你也可以根据给定闭包的结果对数组进行排序:

use Illuminate\Support\Arr;

$array = [
    ['name' => 'Desk'],
    ['name' => 'Table'],
    ['name' => 'Chair'],
];

$sorted = array_values(Arr::sort($array, function (array $value) {
    return $value['name'];
}));

/*
    [
        ['name' => 'Chair'],
        ['name' => 'Desk'],
        ['name' => 'Table'],
    ]
*/

Arr::sortDesc()

Arr::sortDesc 该方法按值对数组进行降序排序:

use Illuminate\Support\Arr;

$array = ['Desk', 'Table', 'Chair'];

$sorted = Arr::sortDesc($array);

// ['Table', 'Desk', 'Chair']

你也可以根据给定闭包的结果对数组进行排序:

use Illuminate\Support\Arr;

$array = [
    ['name' => 'Desk'],
    ['name' => 'Table'],
    ['name' => 'Chair'],
];

$sorted = array_values(Arr::sortDesc($array, function (array $value) {
    return $value['name'];
}));

/*
    [
        ['name' => 'Table'],
        ['name' => 'Desk'],
        ['name' => 'Chair'],
    ]
*/
Lwzi 翻译于 1周前

Arr::sortRecursive()

Arr::sortRecursive 该方法会递归地对数组进行排序,对于数值索引的子数组使用 sort 函数,对于关联子数组使用 ksort 函数:

use Illuminate\Support\Arr;

$array = [
    ['Roman', 'Taylor', 'Li'],
    ['PHP', 'Ruby', 'JavaScript'],
    ['one' => 1, 'two' => 2, 'three' => 3],
];

$sorted = Arr::sortRecursive($array);

/*
    [
        ['JavaScript', 'PHP', 'Ruby'],
        ['one' => 1, 'three' => 3, 'two' => 2],
        ['Li', 'Roman', 'Taylor'],
    ]
*/

如果您希望结果按降序排序,可以使用Arr::sortRecursiveDesc方法。

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

Arr::string()

Arr::string 该方法使用 “点” 表示法从深度嵌套的数组中检索值(就像 Arr::get() 所做的那样),但如果请求的值不是 string,则会抛出 InvalidArgumentException

use Illuminate\Support\Arr;

$array = ['name' => 'Joe', 'languages' => ['PHP', 'Ruby']];

$value = Arr::string($array, 'name');

// Joe

$value = Arr::string($array, 'languages');

// throws InvalidArgumentException

Arr::take()

Arr::take 方法返回一个包含指定数量元素的新数组:

use Illuminate\Support\Arr;

$array = [0, 1, 2, 3, 4, 5];

$chunk = Arr::take($array, 3);

// [0, 1, 2]

你也可以传入一个负整数,从数组的末尾获取指定数量的元素:

$array = [0, 1, 2, 3, 4, 5];

$chunk = Arr::take($array, -2);

// [4, 5]

Arr::toCssClasses()

Arr::toCssClasses 方法会有条件地编译一个 CSS 类字符串。该方法接收一个类数组,数组的键包含你希望添加的类,而值是一个布尔表达式。如果数组元素具有数字键,则它将始终包含在渲染的类列表中:

use Illuminate\Support\Arr;

$isActive = false;
$hasError = true;

$array = ['p-4', 'font-bold' => $isActive, 'bg-red' => $hasError];

$classes = Arr::toCssClasses($array);

/*
    'p-4 bg-red'
*/
Lwzi 翻译于 1周前

Arr::toCssStyles()

Arr::toCssStyles 会有条件地编译 CSS 样式字符串。该方法接受一个类数组,其中数组的键包含你希望添加的一个或多个类,而值则是一个布尔表达式。如果数组元素具有数字键,则它将始终包含在渲染的类列表中:

use Illuminate\Support\Arr;

$hasColor = true;

$array = ['background-color: blue', 'color: blue' => $hasColor];

$classes = Arr::toCssStyles($array);

/*
    'background-color: blue; color: blue;'
*/

这个方法为 Laravel 的功能提供了支持,例如允许将类与 Blade 组件的属性包合并(参见文档:/docs/laravel/12.x/blade#conditionally-merge-classes),以及使用 @class Blade 指令(参见文档:/docs/laravel/12.x/blade#conditional-classes)。

Arr::undot()

Arr::undot 该方法会将使用 “点” 符号的一维数组展开为多维数组:

use Illuminate\Support\Arr;

$array = [
    'user.name' => 'Kevin Malone',
    'user.occupation' => 'Accountant',
];

$array = Arr::undot($array);

// ['user' => ['name' => 'Kevin Malone', 'occupation' => 'Accountant']]

Arr::where()

Arr::where 该方法使用给定的闭包来过滤数组:

use Illuminate\Support\Arr;

$array = [100, '200', 300, '400', 500];

$filtered = Arr::where($array, function (string|int $value, int $key) {
    return is_string($value);
});

// [1 => '200', 3 => '400']

Arr::whereNotNull()

Arr::whereNotNull 该方法会从给定数组中移除所有null值:

use Illuminate\Support\Arr;

$array = [0, null];

$filtered = Arr::whereNotNull($array);

// [0 => 0]

Arr::wrap()

Arr::wrap 该方法会将给定的值包装到一个数组中。如果给定的值已经是一个数组,它将被原样返回,不做任何修改:

use Illuminate\Support\Arr;

$string = 'Laravel';

$array = Arr::wrap($string);

// ['Laravel']
Lwzi 翻译于 1周前

如果给定值为 null,则会返回一个空数组:

use Illuminate\Support\Arr;

$array = Arr::wrap(null);

// []

data_fill()

data_fill 函数使用“.”表示法在嵌套数组或对象中设置缺失值:

$data = ['products' => ['desk' => ['price' => 100]]];

data_fill($data, 'products.desk.price', 200);

// ['products' => ['desk' => ['price' => 100]]]

data_fill($data, 'products.desk.discount', 10);

// ['products' => ['desk' => ['price' => 100, 'discount' => 10]]]

此函数也接受“星号”作为通配符,并会相应地填充目标位置:

$data = [
    'products' => [
        ['name' => 'Desk 1', 'price' => 100],
        ['name' => 'Desk 2'],
    ],
];

data_fill($data, 'products.*.price', 200);

/*
    [
        'products' => [
            ['name' => 'Desk 1', 'price' => 100],
            ['name' => 'Desk 2', 'price' => 200],
        ],
    ]
*/

data_get()

data_get 函数使用“.”符号从嵌套数组或对象中检索值:

$data = ['products' => ['desk' => ['price' => 100]]];

$price = data_get($data, 'products.desk.price');

// 100

data_get 函数也接受一个默认值,如果找不到指定的键,则会返回该默认值:

$discount = data_get($data, 'products.desk.discount', 0);

// 0

该函数也支持使用“星号”作为通配符,可以匹配数组或对象中的任何键:

$data = [
    'product-one' => ['name' => 'Desk 1', 'price' => 100],
    'product-two' => ['name' => 'Desk 2', 'price' => 150],
];

data_get($data, '*.name');

// ['Desk 1', 'Desk 2'];

可以使用 {first}{last} 占位符来获取数组中的第一个或最后一个元素:

$flight = [
    'segments' => [
        ['from' => 'LHR', 'departure' => '9:00', 'to' => 'IST', 'arrival' => '15:00'],
        ['from' => 'IST', 'departure' => '16:00', 'to' => 'PKX', 'arrival' => '20:00'],
    ],
];

data_get($flight, 'segments.{first}.arrival');

// 15:00
她来听我的演唱会 翻译于 1周前

data_set()

data_set 函数使用“点(dot)”表示法,在嵌套数组或对象中设置一个值:

$data = ['products' => ['desk' => ['price' => 100]]];

data_set($data, 'products.desk.price', 200);

// ['products' => ['desk' => ['price' => 200]]]

该函数同样支持使用星号(*)作为通配符,并会相应地在目标上设置值:

$data = [
    'products' => [
        ['name' => 'Desk 1', 'price' => 100],
        ['name' => 'Desk 2', 'price' => 150],
    ],
];

data_set($data, 'products.*.price', 200);

/*
    [
        'products' => [
            ['name' => 'Desk 1', 'price' => 200],
            ['name' => 'Desk 2', 'price' => 200],
        ],
    ]
*/

默认情况下,任何已存在的值都会被覆盖。如果你希望仅在值不存在时才进行设置,可以将 false 作为第四个参数传递给该函数:

$data = ['products' => ['desk' => ['price' => 100]]];

data_set($data, 'products.desk.price', 200, overwrite: false);

// ['products' => ['desk' => ['price' => 100]]]

data_forget()

data_forget 函数使用“点(dot)”表示法,从嵌套数组或对象中移除一个值:

$data = ['products' => ['desk' => ['price' => 100]]];

data_forget($data, 'products.desk.price');

// ['products' => ['desk' => []]]

该函数同样支持使用星号(*)作为通配符,并会相应地移除目标中的值:

$data = [
    'products' => [
        ['name' => 'Desk 1', 'price' => 100],
        ['name' => 'Desk 2', 'price' => 150],
    ],
];

data_forget($data, 'products.*.price');

/*
    [
        'products' => [
            ['name' => 'Desk 1'],
            ['name' => 'Desk 2'],
        ],
    ]
*/

head()

head 函数返回给定数组中的第一个元素:

$array = [100, 200, 300];

$first = head($array);

// 100

last()

last 函数返回给定数组中的最后一个元素:

$array = [100, 200, 300];

$last = last($array);

// 300

数值(Numbers)

Number::abbreviate()

无与伦比 翻译于 4天前

Number::abbreviate 方法返回所提供数值的人类可读格式,并对单位进行缩写表示:

use Illuminate\Support\Number;

$number = Number::abbreviate(1000);

// 1K

$number = Number::abbreviate(489939);

// 490K

$number = Number::abbreviate(1230000, precision: 2);

// 1.23M

Number::clamp()

Number::clamp 方法用于确保给定的数字保持在指定的范围内。如果该数字小于最小值,则返回最小值;如果该数字大于最大值,则返回最大值:

use Illuminate\Support\Number;

$number = Number::clamp(105, min: 10, max: 100);

// 100

$number = Number::clamp(5, min: 10, max: 100);

// 10

$number = Number::clamp(10, min: 10, max: 100);

// 10

$number = Number::clamp(20, min: 10, max: 100);

// 20

Number::currency()

Number::currency 方法以字符串形式返回给定数值的货币表示:

use Illuminate\Support\Number;

$currency = Number::currency(1000);

// $1,000.00

$currency = Number::currency(1000, in: 'EUR');

// €1,000.00

$currency = Number::currency(1000, in: 'EUR', locale: 'de');

// 1.000,00 €

$currency = Number::currency(1000, in: 'EUR', locale: 'de', precision: 0);

// 1.000 €

Number::defaultCurrency()

Number::defaultCurrency 方法返回 Number 类当前使用的默认货币:

use Illuminate\Support\Number;

$currency = Number::defaultCurrency();

// USD

Number::defaultLocale()

Number::defaultLocale 方法返回 Number 类当前使用的默认区域设置(locale):

use Illuminate\Support\Number;

$locale = Number::defaultLocale();

// en

Number::fileSize()

Number::fileSize 方法以字符串形式返回给定字节值的文件大小表示:

use Illuminate\Support\Number;

$size = Number::fileSize(1024);

// 1 KB

$size = Number::fileSize(1024 * 1024);

// 1 MB

$size = Number::fileSize(1024, precision: 2);

// 1.00 KB
无与伦比 翻译于 4天前

Number::forHumans()

Number::forHumans 方法返回所提供数值的人类可读格式

use Illuminate\Support\Number;

$number = Number::forHumans(1000);

// 1 thousand

$number = Number::forHumans(489939);

// 490 thousand

$number = Number::forHumans(1230000, precision: 2);

// 1.23 million

Number::format()

Number::format 方法将给定的数字格式化为特定区域设置(locale)的字符串

use Illuminate\Support\Number;

$number = Number::format(100000);

// 100,000

$number = Number::format(100000, precision: 2);

// 100,000.00

$number = Number::format(100000.123, maxPrecision: 2);

// 100,000.12

$number = Number::format(100000, locale: 'de');

// 100.000

Number::ordinal()

Number::ordinal 方法返回数字的序数形式

use Illuminate\Support\Number;

$number = Number::ordinal(1);

// 1st

$number = Number::ordinal(2);

// 2nd

$number = Number::ordinal(21);

// 21st

Number::pairs()

Number::pairs 方法基于指定的范围和步长值生成一组数字对(子区间)数组。该方法可用于将较大的数字范围拆分为更小、易于管理的子区间,例如用于分页或批量任务处理。pairs 方法返回一个数组,其中每个内部数组表示一对数字(一个子区间):

use Illuminate\Support\Number;

$result = Number::pairs(25, 10);

// [[0, 9], [10, 19], [20, 25]]

$result = Number::pairs(25, 10, offset: 0);

// [[0, 10], [10, 20], [20, 25]]

Number::percentage()

Number::percentage 方法以字符串形式返回给定数值的百分比表示

use Illuminate\Support\Number;

$percentage = Number::percentage(10);

// 10%

$percentage = Number::percentage(10, precision: 2);

// 10.00%

$percentage = Number::percentage(10.123, maxPrecision: 2);

// 10.12%

$percentage = Number::percentage(10, precision: 2, locale: 'de');

// 10,00%

Number::spell()

Number::spell 方法将给定的数字转换为文字形式的字符串

use Illuminate\Support\Number;

$number = Number::spell(102);

// one hundred and two

$number = Number::spell(88, locale: 'fr');

// quatre-vingt-huit
无与伦比 翻译于 4天前

after 参数允许你指定一个值,在该值之后的所有数字将被拼写为文字形式:

$number = Number::spell(10, after: 10);

// 10

$number = Number::spell(11, after: 10);

// eleven

until 参数允许你指定一个值,在该值之前的所有数字将被拼写为文字形式:

$number = Number::spell(5, until: 10);

// five

$number = Number::spell(10, until: 10);

// 10

Number::spellOrdinal()

Number::spellOrdinal 方法以文字形式的字符串返回数字的序数表示:

use Illuminate\Support\Number;

$number = Number::spellOrdinal(1);

// first

$number = Number::spellOrdinal(2);

// second

$number = Number::spellOrdinal(21);

// twenty-first

Number::trim()

Number::trim 方法会移除给定数字中小数点后多余的尾随零

use Illuminate\Support\Number;

$number = Number::trim(12.0);

// 12

$number = Number::trim(12.30);

// 12.3

Number::useLocale()

Number::useLocale 方法在全局范围内设置默认的数字区域设置(locale),这将影响随后对 Number 类方法的调用中数字和货币的格式化方式:

use Illuminate\Support\Number;

/**
 * 引导(Bootstrap)任何应用服务。
 */
public function boot(): void
{
    Number::useLocale('de');
}

Number::withLocale()

Number::withLocale 方法使用指定的区域设置执行给定的闭包,并在回调执行完成后恢复原始的区域设置:

use Illuminate\Support\Number;

$number = Number::withLocale('de', function () {
    return Number::format(1500);
});

Number::useCurrency()

Number::useCurrency 方法在全局范围内设置默认的数字货币,这将影响随后对 Number 类方法的调用中货币的格式化方式:

use Illuminate\Support\Number;

/**
 * 引导(Bootstrap)任何应用服务。
 */
public function boot(): void
{
    Number::useCurrency('GBP');
}
无与伦比 翻译于 4天前

Number::withCurrency()

Number::withCurrency 方法使用指定的货币执行给定的闭包,并在回调执行完成后恢复原来的货币:

use Illuminate\Support\Number;

$number = Number::withCurrency('GBP', function () {
    // ...
});

Paths

app_path()

app_path 函数返回应用程序 app 目录的完全限定路径。你也可以使用 app_path 函数生成相对于应用目录的某个文件的完全限定路径:

$path = app_path();

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

base_path()

base_path 函数返回应用程序根目录的完全限定路径。你也可以使用 base_path 函数生成相对于项目根目录的某个文件的完全限定路径:

$path = base_path();

$path = base_path('vendor/bin');

config_path()

config_path 函数返回应用程序 config 目录的完全限定路径。你也可以使用 config_path 函数生成应用程序配置目录中某个文件的完全限定路径:

$path = config_path();

$path = config_path('app.php');

database_path()

database_path 函数返回应用程序 database 目录的完全限定路径。你也可以使用 database_path 函数生成数据库目录中某个文件的完全限定路径:

$path = database_path();

$path = database_path('factories/UserFactory.php');
无与伦比 翻译于 3天前

lang_path()

lang_path 函数返回应用程序 lang 目录的完全限定路径。你也可以使用 lang_path 函数生成该目录中某个文件的完全限定路径:

$path = lang_path();

$path = lang_path('en/messages.php');

[!注意]
默认情况下,Laravel 应用程序骨架并不包含 lang 目录。如果你希望自定义 Laravel 的语言文件,可以通过 lang:publish Artisan 命令将它们发布出来。

mix()

mix 函数返回一个 已版本化的 Mix 文件 的路径:

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

public_path()

public_path 函数返回应用程序 public 目录的完全限定路径。你也可以使用 public_path 函数生成 public 目录中某个文件的完全限定路径:

$path = public_path();

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

resource_path()

resource_path 函数返回应用程序 resources 目录的完全限定路径。你也可以使用 resource_path 函数生成 resources 目录中某个文件的完全限定路径:

$path = resource_path();

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

storage_path()

storage_path 函数返回应用程序 storage 目录的完全限定路径。你也可以使用 storage_path 函数生成 storage 目录中某个文件的完全限定路径:

$path = storage_path();

$path = storage_path('app/file.txt');
无与伦比 翻译于 3天前

URLs

action()

action 函数为给定的控制器操作生成一个 URL:

use App\Http\Controllers\HomeController;

$url = action([HomeController::class, 'index']);

如果该方法接收路由参数,你可以将它们作为第二个参数传递给该方法:

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

asset()

asset 函数使用当前请求的协议(HTTP 或 HTTPS)为一个资源生成 URL:

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

你可以通过在 .env 文件中设置 ASSET_URL 变量来配置资源 URL 的主机。这在你将资源托管在诸如 Amazon S3 或其他 CDN 等外部服务上时非常有用:

// ASSET_URL=http://example.com/assets

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

route()

route 函数为给定的 命名路由 生成一个 URL:

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

如果该路由接收参数,你可以将它们作为第二个参数传递给该函数:

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

默认情况下,route 函数会生成一个绝对 URL。如果你希望生成相对 URL,可以将 false 作为第三个参数传递给该函数:

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

secure_asset()

secure_asset 函数使用 HTTPS 为一个资源生成 URL:

$url = secure_asset('img/photo.jpg');
无与伦比 翻译于 3天前

secure_url()

secure_url 函数为给定的路径生成一个完全限定的 HTTPS URL。你可以在该函数的第二个参数中传递额外的 URL 片段:

$url = secure_url('user/profile');

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

to_route()

to_route 函数为给定的 命名路由 生成一个 重定向 HTTP 响应

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

如有需要,你可以将应分配给该重定向的 HTTP 状态码以及任何额外的响应头,作为第三个和第四个参数传递给 to_route 方法:

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

uri()

uri 函数为给定的 URI 生成一个 流式(fluent)URI 实例

$uri = uri('https://example.com')
    ->withPath('/users')
    ->withQuery(['page' => 1])

如果传递给 uri 函数的是一个包含可调用控制器和方法对的数组,该函数将为该控制器方法的路由路径创建一个 Uri 实例:

use App\Http\Controllers\UserController;

$uri = uri([UserController::class, 'show'], ['user' => $user])

如果该控制器是可调用的(invokable),你只需提供控制器类名即可:

use App\Http\Controllers\UserIndexController;

$uri = uri(UserIndexController::class);

如果传递给 uri 函数的值与某个 命名路由 的名称匹配,则会为该路由的路径生成一个 Uri 实例:

$uri = uri('users.show', ['user' => $user]);
无与伦比 翻译于 3天前

url()

url 函数为给定的路径生成一个完全限定的 URL:

$url = url('user/profile');

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

如果未提供路径,则会返回一个 Illuminate\Routing\UrlGenerator 实例:

$current = url()->current();

$full = url()->full();

$previous = url()->previous();

其他

abort()

abort 函数会抛出一个 HTTP 异常,该异常将由 异常处理器 进行渲染:

abort(403);

你也可以提供该异常的消息以及应发送到浏览器的自定义 HTTP 响应头:

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

abort_if()

abort_if 函数在给定的布尔表达式计算结果为 true 时抛出一个 HTTP 异常:

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

abort 方法一样,你也可以将异常的响应文本作为第三个参数传递给该函数,并将自定义响应头数组作为第四个参数传递给该函数。

abort_unless()

abort_unless 函数在给定的布尔表达式计算结果为 false 时抛出一个 HTTP 异常:

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

abort 方法一样,你也可以将异常的响应文本作为第三个参数传递给该函数,并将自定义响应头数组作为第四个参数传递给该函数。

app()

app 函数返回 服务容器 实例:

$container = app();
无与伦比 翻译于 3天前

你可以传递一个类名或接口名,以便从容器中解析它:

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

auth()

auth 函数返回一个 认证器 实例。你可以将其作为 Auth 门面的替代方案来使用:

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

如有需要,你可以指定要访问的守卫实例:

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

back()

back 函数生成一个指向用户上一个位置的 重定向 HTTP 响应

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

return back();

bcrypt()

bcrypt 函数使用 Bcrypt 对给定的值进行 哈希处理。你可以将该函数作为 Hash 门面的替代方案来使用:

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

blank()

blank 函数用于判断给定的值是否为“空白”:

blank('');
blank('   ');
blank(null);
blank(collect());

// true

blank(0);
blank(true);
blank(false);

// false

关于 blank 的相反判断,请参阅 filled 方法。

broadcast()

broadcast 函数将给定的 事件 广播 给其监听器:

broadcast(new UserRegistered($user));

broadcast(new UserRegistered($user))->toOthers();

cache()

cache 函数可用于从 缓存 中获取值。如果给定的键在缓存中不存在,则会返回一个可选的默认值:

$value = cache('key');

$value = cache('key', 'default');
无与伦比 翻译于 3天前

你可以通过向该函数传递一个由键 / 值对组成的数组来向缓存中添加项目。你还应传递缓存值应被视为有效的秒数或持续时间:

cache(['key' => 'value'], 300);

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

class_uses_recursive()

class_uses_recursive 函数返回某个类所使用的所有 trait,包括其所有父类所使用的 trait:

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

collect()

collect 函数从给定的值创建一个 集合 实例:

$collection = collect(['Taylor', 'Abigail']);

config()

config 函数获取某个 配置 变量的值。配置值可以使用“点”语法来访问,其中包含你希望访问的文件名和选项。如果配置选项不存在,可以指定一个默认值并在此情况下返回:

$value = config('app.timezone');

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

你可以通过传递一个由键 / 值对组成的数组在运行时设置配置变量。不过请注意,该函数只会影响当前请求的配置值,并不会更新实际的配置文件中的值:

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

context()

context 函数从 当前上下文 中获取一个值。如果上下文键不存在,可以指定一个默认值并在此情况下返回:

$value = context('trace_id');

$value = context('trace_id', $default);
无与伦比 翻译于 3天前

你可以通过传递一个由键 / 值对组成的数组来设置上下文值:

use Illuminate\Support\Str;

context(['trace_id' => Str::uuid()->toString()]);

cookie()

cookie 函数创建一个新的 Cookie 实例:

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

csrf_field()

csrf_field 函数生成一个包含 CSRF 令牌值的 HTML hidden 输入字段。例如,使用 Blade 语法

{{ csrf_field() }}

csrf_token()

csrf_token 函数获取当前 CSRF 令牌的值:

$token = csrf_token();

decrypt()

decrypt 函数对给定的值进行 解密。你可以将该函数作为 Crypt 门面的替代方案来使用:

$password = decrypt($value);

dd()

dd 函数输出(dump)给定的变量并终止脚本的执行:

dd($value);

dd($value1, $value2, $value3, ...);

如果你不希望中断脚本的执行,请改用 dump 函数。

dispatch()

dispatch 函数将给定的 任务(job) 推送到 Laravel 的 任务队列 中:

dispatch(new App\Jobs\SendEmails);

dispatch_sync()

dispatch_sync 函数将给定的任务推送到 同步(sync) 队列中,以便立即处理:

dispatch_sync(new App\Jobs\SendEmails);
无与伦比 翻译于 3天前

dump()

The dump function dumps the given variables:

dump($value);

dump($value1, $value2, $value3, ...);

If you want to stop executing the script after dumping the variables, use the dd function instead.

encrypt()

The encrypt function encrypts the given value. You may use this function as an alternative to the Crypt facade:

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

env()

The env function retrieves the value of an environment variable or returns a default value:

$env = env('APP_ENV');

$env = env('APP_ENV', 'production');

[!WARNING]
If you execute the config:cache command during your deployment process, you should be sure that you are only calling the env function from within your configuration files. Once the configuration has been cached, the .env file will not be loaded and all calls to the env function will return null.

event()

The event function dispatches the given event to its listeners:

event(new UserRegistered($user));

fake()

The fake function resolves a Faker singleton from the container, which can be useful when creating fake data in model factories, database seeding, tests, and prototyping views:

@for($i = 0; $i < 10; $i++)
    <dl>
        <dt>Name</dt>
        <dd>{{ fake()->name() }}</dd>

        <dt>Email</dt>
        <dd>{{ fake()->unique()->safeEmail() }}</dd>
    </dl>
@endfor

By default, the fake function will utilize the app.faker_locale configuration option in your config/app.php configuration. Typically, this configuration option is set via the APP_FAKER_LOCALE environment variable. You may also specify the locale by passing it to the fake function. Each locale will resolve an individual singleton:

fake('nl_NL')->name()

filled()

The filled function determines whether the given value is not "blank":

filled(0);
filled(true);
filled(false);

// true

filled('');
filled('   ');
filled(null);
filled(collect());

// false

For the inverse of filled, see the blank method.

info()

The info function will write information to your application's log:

info('Some helpful information!');

An array of contextual data may also be passed to the function:

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

literal()

The literal function creates a new stdClass instance with the given named arguments as properties:

$obj = literal(
    name: 'Joe',
    languages: ['PHP', 'Ruby'],
);

$obj->name; // 'Joe'
$obj->languages; // ['PHP', 'Ruby']

logger()

The logger function can be used to write a debug level message to the log:

logger('Debug message');

An array of contextual data may also be passed to the function:

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

A logger instance will be returned if no value is passed to the function:

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

method_field()

The method_field function generates an HTML hidden input field containing the spoofed value of the form's HTTP verb. For example, using Blade syntax:

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

now()

The now function creates a new Illuminate\Support\Carbon instance for the current time:

$now = now();

old()

The old function retrieves an old input value flashed into the session:

$value = old('value');

$value = old('value', 'default');

Since the "default value" provided as the second argument to the old function is often an attribute of an Eloquent model, Laravel allows you to simply pass the entire Eloquent model as the second argument to the old function. When doing so, Laravel will assume the first argument provided to the old function is the name of the Eloquent attribute that should be considered the "default value":

{{ old('name', $user->name) }}

// Is equivalent to...

{{ old('name', $user) }}

once()

The once function executes the given callback and caches the result in memory for the duration of the request. Any subsequent calls to the once function with the same callback will return the previously cached result:

function random(): int
{
    return once(function () {
        return random_int(1, 1000);
    });
}

random(); // 123
random(); // 123 (cached result)
random(); // 123 (cached result)

When the once function is executed from within an object instance, the cached result will be unique to that object instance:

<?php

class NumberService
{
    public function all(): array
    {
        return once(fn () => [1, 2, 3]);
    }
}

$service = new NumberService;

$service->all();
$service->all(); // (cached result)

$secondService = new NumberService;

$secondService->all();
$secondService->all(); // (cached result)

optional()

The optional function accepts any argument and allows you to access properties or call methods on that object. If the given object is null, properties and methods will return null instead of causing an error:

return optional($user->address)->street;

{!! old('name', optional($user)->name) !!}

The optional function also accepts a closure as its second argument. The closure will be invoked if the value provided as the first argument is not null:

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

policy()

The policy method retrieves a policy instance for a given class:

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

redirect()

The redirect function returns a redirect HTTP response, or returns the redirector instance if called with no arguments:

return redirect($to = null, $status = 302, $headers = [], $https = null);

return redirect('/home');

return redirect()->route('route.name');

report()

The report function will report an exception using your exception handler:

report($e);

The report function also accepts a string as an argument. When a string is given to the function, the function will create an exception with the given string as its message:

report('Something went wrong.');

report_if()

The report_if function will report an exception using your exception handler if the given condition is true:

report_if($shouldReport, $e);

report_if($shouldReport, 'Something went wrong.');

report_unless()

The report_unless function will report an exception using your exception handler if the given condition is false:

report_unless($reportingDisabled, $e);

report_unless($reportingDisabled, 'Something went wrong.');

request()

The request function returns the current request instance or obtains an input field's value from the current request:

$request = request();

$value = request('key', $default);

rescue()

The rescue function executes the given closure and catches any exceptions that occur during its execution. All exceptions that are caught will be sent to your exception handler; however, the request will continue processing:

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

You may also pass a second argument to the rescue function. This argument will be the "default" value that should be returned if an exception occurs while executing the closure:

return rescue(function () {
    return $this->method();
}, false);

return rescue(function () {
    return $this->method();
}, function () {
    return $this->failure();
});

A report argument may be provided to the rescue function to determine if the exception should be reported via the report function:

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

resolve()

The resolve function resolves a given class or interface name to an instance using the service container:

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

response()

The response function creates a response instance or obtains an instance of the response factory:

return response('Hello World', 200, $headers);

return response()->json(['foo' => 'bar'], 200, $headers);

retry()

The retry function attempts to execute the given callback until the given maximum attempt threshold is met. If the callback does not throw an exception, its return value will be returned. If the callback throws an exception, it will automatically be retried. If the maximum attempt count is exceeded, the exception will be thrown:

return retry(5, function () {
    // Attempt 5 times while resting 100ms between attempts...
}, 100);

If you would like to manually calculate the number of milliseconds to sleep between attempts, you may pass a closure as the third argument to the retry function:

use Exception;

return retry(5, function () {
    // ...
}, function (int $attempt, Exception $exception) {
    return $attempt * 100;
});

For convenience, you may provide an array as the first argument to the retry function. This array will be used to determine how many milliseconds to sleep between subsequent attempts:

return retry([100, 200], function () {
    // Sleep for 100ms on first retry, 200ms on second retry...
});

To only retry under specific conditions, you may pass a closure as the fourth argument to the retry function:

use Exception;

return retry(5, function () {
    // ...
}, 100, function (Exception $exception) {
    return $exception instanceof RetryException;
});

session()

The session function may be used to get or set session values:

$value = session('key');

You may set values by passing an array of key / value pairs to the function:

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

The session store will be returned if no value is passed to the function:

$value = session()->get('key');

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

tap()

The tap function accepts two arguments: an arbitrary $value and a closure. The $value will be passed to the closure and then be returned by the tap function. The return value of the closure is irrelevant:

$user = tap(User::first(), function (User $user) {
    $user->name = 'Taylor';

    $user->save();
});

If no closure is passed to the tap function, you may call any method on the given $value. The return value of the method you call will always be $value, regardless of what the method actually returns in its definition. For example, the Eloquent update method typically returns an integer. However, we can force the method to return the model itself by chaining the update method call through the tap function:

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

To add a tap method to a class, you may add the Illuminate\Support\Traits\Tappable trait to the class. The tap method of this trait accepts a Closure as its only argument. The object instance itself will be passed to the Closure and then be returned by the tap method:

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

throw_if()

The throw_if function throws the given exception if a given boolean expression evaluates to true:

throw_if(! Auth::user()->isAdmin(), AuthorizationException::class);

throw_if(
    ! Auth::user()->isAdmin(),
    AuthorizationException::class,
    'You are not allowed to access this page.'
);

throw_unless()

The throw_unless function throws the given exception if a given boolean expression evaluates to false:

throw_unless(Auth::user()->isAdmin(), AuthorizationException::class);

throw_unless(
    Auth::user()->isAdmin(),
    AuthorizationException::class,
    'You are not allowed to access this page.'
);

today()

The today function creates a new Illuminate\Support\Carbon instance for the current date:

$today = today();

trait_uses_recursive()

The trait_uses_recursive function returns all traits used by a trait:

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

transform()

The transform function executes a closure on a given value if the value is not blank and then returns the return value of the closure:

$callback = function (int $value) {
    return $value * 2;
};

$result = transform(5, $callback);

// 10

A default value or closure may be passed as the third argument to the function. This value will be returned if the given value is blank:

$result = transform(null, $callback, 'The value is blank');

// The value is blank

validator()

The validator function creates a new validator instance with the given arguments. You may use it as an alternative to the Validator facade:

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

value()

The value function returns the value it is given. However, if you pass a closure to the function, the closure will be executed and its returned value will be returned:

$result = value(true);

// true

$result = value(function () {
    return false;
});

// false

Additional arguments may be passed to the value function. If the first argument is a closure then the additional parameters will be passed to the closure as arguments, otherwise they will be ignored:

$result = value(function (string $name) {
    return $name;
}, 'Taylor');

// 'Taylor'

view()

The view function retrieves a view instance:

return view('auth.login');

with()

The with function returns the value it is given. If a closure is passed as the second argument to the function, the closure will be executed and its returned value will be returned:

$callback = function (mixed $value) {
    return is_numeric($value) ? $value * 2 : 0;
};

$result = with(5, $callback);

// 10

$result = with(null, $callback);

// 0

$result = with(5, null);

// 5

when()

The when function returns the value it is given if a given condition evaluates to true. Otherwise, null is returned. If a closure is passed as the second argument to the function, the closure will be executed and its returned value will be returned:

$value = when(true, 'Hello World');

$value = when(true, fn () => 'Hello World');

The when function is primarily useful for conditionally rendering HTML attributes:

<div {!! when($condition, 'wire:poll="calculate"') !!}>
    ...
</div>

Other Utilities

Benchmarking

Sometimes you may wish to quickly test the performance of certain parts of your application. On those occasions, you may utilize the Benchmark support class to measure the number of milliseconds it takes for the given callbacks to complete:

<?php

use App\Models\User;
use Illuminate\Support\Benchmark;

Benchmark::dd(fn () => User::find(1)); // 0.1 ms

Benchmark::dd([
    'Scenario 1' => fn () => User::count(), // 0.5 ms
    'Scenario 2' => fn () => User::all()->count(), // 20.0 ms
]);

By default, the given callbacks will be executed once (one iteration), and their duration will be displayed in the browser / console.

To invoke a callback more than once, you may specify the number of iterations that the callback should be invoked as the second argument to the method. When executing a callback more than once, the Benchmark class will return the average amount of milliseconds it took to execute the callback across all iterations:

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

Sometimes, you may want to benchmark the execution of a callback while still obtaining the value returned by the callback. The value method will return a tuple containing the value returned by the callback and the amount of milliseconds it took to execute the callback:

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

Dates

Laravel includes Carbon, a powerful date and time manipulation library. To create a new Carbon instance, you may invoke the now function. This function is globally available within your Laravel application:

$now = now();

Or, you may create a new Carbon instance using the Illuminate\Support\Carbon class:

use Illuminate\Support\Carbon;

$now = Carbon::now();

For a thorough discussion of Carbon and its features, please consult the official Carbon documentation.

Deferred Functions

While Laravel's queued jobs allow you to queue tasks for background processing, sometimes you may have simple tasks you would like to defer without configuring or maintaining a long-running queue worker.

Deferred functions allow you to defer the execution of a closure until after the HTTP response has been sent to the user, keeping your application feeling fast and responsive. To defer the execution of a closure, simply pass the closure to the Illuminate\Support\defer function:

use App\Services\Metrics;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use function Illuminate\Support\defer;

Route::post('/orders', function (Request $request) {
    // Create order...

    defer(fn () => Metrics::reportOrder($order));

    return $order;
});

By default, deferred functions will only be executed if the HTTP response, Artisan command, or queued job from which Illuminate\Support\defer is invoked completes successfully. This means that deferred functions will not be executed if a request results in a 4xx or 5xx HTTP response. If you would like a deferred function to always execute, you may chain the always method onto your deferred function:

defer(fn () => Metrics::reportOrder($order))->always();

Cancelling Deferred Functions

If you need to cancel a deferred function before it is executed, you can use the forget method to cancel the function by its name. To name a deferred function, provide a second argument to the Illuminate\Support\defer function:

defer(fn () => Metrics::report(), 'reportMetrics');

defer()->forget('reportMetrics');

Disabling Deferred Functions in Tests

When writing tests, it may be useful to disable deferred functions. You may call withoutDefer in your test to instruct Laravel to invoke all deferred functions immediately:

test('without defer', function () {
    $this->withoutDefer();

    // ...
});
use Tests\TestCase;

class ExampleTest extends TestCase
{
    public function test_without_defer(): void
    {
        $this->withoutDefer();

        // ...
    }
}

If you would like to disable deferred functions for all tests within a test case, you may call the withoutDefer method from the setUp method on your base TestCase class:

<?php

namespace Tests;

use Illuminate\Foundation\Testing\TestCase as BaseTestCase;

abstract class TestCase extends BaseTestCase
{
    protected function setUp(): void// [tl! add:start]
    {
        parent::setUp();

        $this->withoutDefer();
    }// [tl! add:end]
}

Lottery

Laravel's lottery class may be used to execute callbacks based on a set of given odds. This can be particularly useful when you only want to execute code for a percentage of your incoming requests:

use Illuminate\Support\Lottery;

Lottery::odds(1, 20)
    ->winner(fn () => $user->won())
    ->loser(fn () => $user->lost())
    ->choose();

You may combine Laravel's lottery class with other Laravel features. For example, you may wish to only report a small percentage of slow queries to your exception handler. And, since the lottery class is callable, we may pass an instance of the class into any method that accepts callables:

use Carbon\CarbonInterval;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Lottery;

DB::whenQueryingForLongerThan(
    CarbonInterval::seconds(2),
    Lottery::odds(1, 100)->winner(fn () => report('Querying > 2 seconds.')),
);

Testing Lotteries

Laravel provides some simple methods to allow you to easily test your application's lottery invocations:

// Lottery will always win...
Lottery::alwaysWin();

// Lottery will always lose...
Lottery::alwaysLose();

// Lottery will win then lose, and finally return to normal behavior...
Lottery::fix([true, false]);

// Lottery will return to normal behavior...
Lottery::determineResultsNormally();

Pipeline

Laravel's Pipeline facade provides a convenient way to "pipe" a given input through a series of invokable classes, closures, or callables, giving each class the opportunity to inspect or modify the input and invoke the next callable in the pipeline:

use Closure;
use App\Models\User;
use Illuminate\Support\Facades\Pipeline;

$user = Pipeline::send($user)
    ->through([
        function (User $user, Closure $next) {
            // ...

            return $next($user);
        },
        function (User $user, Closure $next) {
            // ...

            return $next($user);
        },
    ])
    ->then(fn (User $user) => $user);

As you can see, each invokable class or closure in the pipeline is provided the input and a $next closure. Invoking the $next closure will invoke the next callable in the pipeline. As you may have noticed, this is very similar to middleware.

When the last callable in the pipeline invokes the $next closure, the callable provided to the then method will be invoked. Typically, this callable will simply return the given input.

Of course, as discussed previously, you are not limited to providing closures to your pipeline. You may also provide invokable classes. If a class name is provided, the class will be instantiated via Laravel's service container, allowing dependencies to be injected into the invokable class:

$user = Pipeline::send($user)
    ->through([
        GenerateProfilePhoto::class,
        ActivateSubscription::class,
        SendWelcomeEmail::class,
    ])
    ->then(fn (User $user) => $user);

Sleep

Laravel's Sleep class is a light-weight wrapper around PHP's native sleep and usleep functions, offering greater testability while also exposing a developer friendly API for working with time:

use Illuminate\Support\Sleep;

$waiting = true;

while ($waiting) {
    Sleep::for(1)->second();

    $waiting = /* ... */;
}

The Sleep class offers a variety of methods that allow you to work with different units of time:

// Return a value after sleeping...
$result = Sleep::for(1)->second()->then(fn () => 1 + 1);

// Sleep while a given value is true...
Sleep::for(1)->second()->while(fn () => shouldKeepSleeping());

// Pause execution for 90 seconds...
Sleep::for(1.5)->minutes();

// Pause execution for 2 seconds...
Sleep::for(2)->seconds();

// Pause execution for 500 milliseconds...
Sleep::for(500)->milliseconds();

// Pause execution for 5,000 microseconds...
Sleep::for(5000)->microseconds();

// Pause execution until a given time...
Sleep::until(now()->addMinute());

// Alias of PHP's native "sleep" function...
Sleep::sleep(2);

// Alias of PHP's native "usleep" function...
Sleep::usleep(5000);

To easily combine units of time, you may use the and method:

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

Testing Sleep

When testing code that utilizes the Sleep class or PHP's native sleep functions, your test will pause execution. As you might expect, this makes your test suite significantly slower. For example, imagine you are testing the following code:

$waiting = /* ... */;

$seconds = 1;

while ($waiting) {
    Sleep::for($seconds++)->seconds();

    $waiting = /* ... */;
}

Typically, testing this code would take at least one second. Luckily, the Sleep class allows us to "fake" sleeping so that our test suite stays fast:

it('waits until ready', function () {
    Sleep::fake();

    // ...
});
public function test_it_waits_until_ready()
{
    Sleep::fake();

    // ...
}

When faking the Sleep class, the actual execution pause is by-passed, leading to a substantially faster test.

Once the Sleep class has been faked, it is possible to make assertions against the expected "sleeps" that should have occurred. To illustrate this, let's imagine we are testing code that pauses execution three times, with each pause increasing by a single second. Using the assertSequence method, we can assert that our code "slept" for the proper amount of time while keeping our test fast:

it('checks if ready three times', function () {
    Sleep::fake();

    // ...

    Sleep::assertSequence([
        Sleep::for(1)->second(),
        Sleep::for(2)->seconds(),
        Sleep::for(3)->seconds(),
    ]);
}
public function test_it_checks_if_ready_three_times()
{
    Sleep::fake();

    // ...

    Sleep::assertSequence([
        Sleep::for(1)->second(),
        Sleep::for(2)->seconds(),
        Sleep::for(3)->seconds(),
    ]);
}

Of course, the Sleep class offers a variety of other assertions you may use when testing:

use Carbon\CarbonInterval as Duration;
use Illuminate\Support\Sleep;

// Assert that sleep was called 3 times...
Sleep::assertSleptTimes(3);

// Assert against the duration of sleep...
Sleep::assertSlept(function (Duration $duration): bool {
    return /* ... */;
}, times: 1);

// Assert that the Sleep class was never invoked...
Sleep::assertNeverSlept();

// Assert that, even if Sleep was called, no execution paused occurred...
Sleep::assertInsomniac();

Sometimes it may be useful to perform an action whenever a fake sleep occurs in your application code. To achieve this, you may provide a callback to the whenFakingSleep method. In the following example, we use Laravel's time manipulation helpers to instantly progress time by the duration of each sleep:

use Carbon\CarbonInterval as Duration;

$this->freezeTime();

Sleep::fake();

Sleep::whenFakingSleep(function (Duration $duration) {
    // Progress time when faking sleep...
    $this->travel($duration->totalMilliseconds)->milliseconds();
});

As progressing time is a common requirement, the fake method accepts a syncWithCarbon argument to keep Carbon in sync when sleeping within a test:

Sleep::fake(syncWithCarbon: true);

$start = now();

Sleep::for(1)->second();

$start->diffForHumans(); // 1 second ago

Laravel uses the Sleep class internally whenever it is pausing execution. For example, the retry helper uses the Sleep class when sleeping, allowing for improved testability when using that helper.

Timebox

Laravel's Timebox class ensures that the given callback always takes a fixed amount of time to execute, even if its actual execution completes sooner. This is particularly useful for cryptographic operations and user authentication checks, where attackers might exploit variations in execution time to infer sensitive information.

If the execution exceeds the fixed duration, Timebox has no effect. It is up to the developer to choose a sufficiently long time as the fixed duration to account for worst-case scenarios.

The call method accepts a closure and a time limit in microseconds, and then executes the closure and waits until the time limit is reached:

use Illuminate\Support\Timebox;

(new Timebox)->call(function ($timebox) {
    // ...
}, microseconds: 10000);

If an exception is thrown within the closure, this class will respect the defined delay and re-throw the exception after the delay.

URI

Laravel's Uri class provides a convenient and fluent interface for creating and manipulating URIs. This class wraps the functionality provided by the underlying League URI package and integrates seamlessly with Laravel's routing system.

You can create a Uri instance easily using static methods:

use App\Http\Controllers\UserController;
use App\Http\Controllers\InvokableController;
use Illuminate\Support\Uri;

// Generate a URI instance from the given string...
$uri = Uri::of('https://example.com/path');

// Generate URI instances to paths, named routes, or controller actions...
$uri = Uri::to('/dashboard');
$uri = Uri::route('users.show', ['user' => 1]);
$uri = Uri::signedRoute('users.show', ['user' => 1]);
$uri = Uri::temporarySignedRoute('user.index', now()->addMinutes(5));
$uri = Uri::action([UserController::class, 'index']);
$uri = Uri::action(InvokableController::class);

// Generate a URI instance from the current request URL...
$uri = $request->uri();

Once you have a URI instance, you can fluently modify it:

$uri = Uri::of('https://example.com')
    ->withScheme('http')
    ->withHost('test.com')
    ->withPort(8000)
    ->withPath('/users')
    ->withQuery(['page' => 2])
    ->withFragment('section-1');

Inspecting URIs

The Uri class also allows you to easily inspect the various components of the underlying URI:

$scheme = $uri->scheme();
$host = $uri->host();
$port = $uri->port();
$path = $uri->path();
$segments = $uri->pathSegments();
$query = $uri->query();
$fragment = $uri->fragment();

Manipulating Query Strings

The Uri class offers several methods that may be used to manipulate a URI's query string. The withQuery method may be used to merge additional query string parameters into the existing query string:

$uri = $uri->withQuery(['sort' => 'name']);

The withQueryIfMissing method may be used to merge additional query string parameters into the existing query string if the given keys do not already exist in the query string:

$uri = $uri->withQueryIfMissing(['page' => 1]);

The replaceQuery method may be used to complete replace the existing query string with a new one:

$uri = $uri->replaceQuery(['page' => 1]);

The pushOntoQuery method may be used to push additional parameters onto a query string parameter that has an array value:

$uri = $uri->pushOntoQuery('filter', ['active', 'pending']);

The withoutQuery method may be used to remove parameters from the query string:

$uri = $uri->withoutQuery(['page']);

Generating Responses From URIs

The redirect method may be used to generate a RedirectResponse instance to the given URI:

$uri = Uri::of('https://example.com');

return $uri->redirect();

Or, you may simply return the Uri instance from a route or controller action, which will automatically generate a redirect response to the returned URI:

use Illuminate\Support\Facades\Route;
use Illuminate\Support\Uri;

Route::get('/redirect', function () {
    return Uri::to('/index')
        ->withQuery(['sort' => 'name']);
});

本文章首发在 LearnKu.com 网站上。

本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
贡献者:8
讨论数量: 2
发起讨论 只看当前版本


PerFe
Arr::dot() 对二维数组返回预期不一致
0 个点赞 | 2 个回复 | 代码速记 | 课程版本 8.x
wolfgreen
transform() 和 with() 不是差不多么?
0 个点赞 | 0 个回复 | 分享 | 课程版本 5.5