翻译进度
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 翻译于 4周前

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 翻译于 3周前

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 翻译于 3周前

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

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 翻译于 3周前

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 翻译于 2周前

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 翻译于 2周前

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 翻译于 2周前

如果给定值为 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
她来听我的演唱会 翻译于 2周前

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

无与伦比 翻译于 1周前

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
无与伦比 翻译于 1周前

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
无与伦比 翻译于 1周前

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');
}
无与伦比 翻译于 1周前

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');
无与伦比 翻译于 1周前

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');
无与伦比 翻译于 1周前

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');
无与伦比 翻译于 1周前

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]);
无与伦比 翻译于 1周前

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();
无与伦比 翻译于 1周前

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

$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');
无与伦比 翻译于 1周前

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

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);
无与伦比 翻译于 1周前

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

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);
无与伦比 翻译于 1周前

dump()

dump 函数用于输出给定的变量:

dump($value);

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

如果你希望在输出变量后停止脚本的执行,请改用 dd 函数。

encrypt()

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

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

env()

env 函数用于获取环境变量的值,或者在环境变量不存在时返回一个默认值:

$env = env('APP_ENV');

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

[!警告]
如果你在部署过程中执行了 config:cache 命令,请确保你只在配置文件中调用 env 函数。一旦配置被缓存,.env 文件将不会被加载,所有对 env 函数的调用都将返回 null

event()

event 函数会将给定的事件分发给其监听器:

event(new UserRegistered($user));

fake()

fake 函数从容器中解析一个 Faker 单例,这在创建模型工厂、数据库填充、测试以及原型视图中的虚假数据时非常有用:

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

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

默认情况下,fake 函数将使用 config/app.php 配置文件中的 app.faker_locale 配置选项。通常,该配置选项是通过 APP_FAKER_LOCALE 环境变量来设置的。你也可以通过向 fake 函数传递参数来指定语言环境。每种语言环境都会解析为一个独立的单例:

fake('nl_NL')->name()
无与伦比 翻译于 1天前

filled()

filled 函数用于判断给定的值是否不是“空白(blank)”:

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

// true

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

// false

filled 的反向判断请参见 blank 方法。

info()

info 函数会将信息写入应用程序的日志中:

info('Some helpful information!');

也可以向该函数传递一个包含上下文数据的数组:

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

literal()

literal 函数使用给定的具名参数作为属性,创建一个新的 stdClass 实例:

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

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

logger()

logger 函数可用于向日志中写入一条 debug 级别的消息:

logger('Debug message');

也可以向该函数传递一个包含上下文数据的数组:

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

如果在调用该函数时未传入任何值,则会返回一个 logger 实例:

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

method_field()

method_field 函数会生成一个 HTML 的 hidden 输入字段,其中包含表单 HTTP 动词的伪造(spoofed)值。例如,使用 Blade 语法

<form method="POST">
    {{ method_field('DELETE') }}
</form>
无与伦比 翻译于 1天前

now()

now 函数会为当前时间创建一个新的 Illuminate\Support\Carbon 实例:

$now = now();

old()

old 函数用于获取闪存到 session 中的旧输入值

$value = old('value');

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

由于传递给 old 函数的第二个参数(“默认值”)通常是一个 Eloquent 模型的属性,Laravel 允许你直接将整个 Eloquent 模型作为第二个参数传入 old 函数。在这种情况下,Laravel 会假定传给 old 函数的第一个参数是应当作为“默认值”的 Eloquent 属性名称:

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

// Is equivalent to...

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

once()

once 函数会执行给定的回调,并在一次请求的生命周期内将结果缓存到内存中。之后任何使用相同回调再次调用 once 函数时,都会返回之前缓存的结果:

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

random(); // 123
random(); // 123(缓存的结果)
random(); // 123(缓存的结果)

once 函数在对象实例内部执行时,缓存的结果将只对该对象实例唯一:

<?php

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

$service = new NumberService;

$service->all();
$service->all(); //(缓存的结果)

$secondService = new NumberService;

$secondService->all();
$secondService->all(); //(缓存的结果)

optional()

optional 函数接受任意参数,并允许你访问该对象的属性或调用其方法。如果给定的对象为 null,则访问属性或调用方法时会返回 null,而不会引发错误:

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

{!! old('name', optional($user)->name) !!}
无与伦比 翻译于 1天前

optional 函数还可以接受一个闭包作为第二个参数。当作为第一个参数传入的值不为 null 时,该闭包将会被调用:

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

policy()

policy 方法用于获取指定类的一个 policy 实例:

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

redirect()

redirect 函数会返回一个重定向 HTTP 响应,如果在调用时未传入任何参数,则会返回重定向器(redirector)实例:

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

return redirect('/home');

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

report()

report 函数会使用你的异常处理器来上报一个异常:

report($e);

report 函数同样接受一个字符串作为参数。当向该函数传入字符串时,函数会使用该字符串作为异常消息来创建一个异常:

report('Something went wrong.');

report_if()

当给定的条件为 true 时,report_if 函数会使用你的异常处理器来上报一个异常:

report_if($shouldReport, $e);

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

report_unless()

当给定的条件为 false 时,report_unless 函数会使用你的异常处理器来上报一个异常:

report_unless($reportingDisabled, $e);

report_unless($reportingDisabled, 'Something went wrong.');
无与伦比 翻译于 1天前

request()

request 函数会返回当前的请求实例,或者获取当前请求中的某个输入字段的值:

$request = request();

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

rescue()

rescue 函数会执行给定的闭包,并捕获执行过程中发生的任何异常。所有捕获的异常都会发送到你的异常处理器;但是请求会继续处理:

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

你也可以向 rescue 函数传递第二个参数。该参数将在执行闭包时发生异常时作为“默认值”返回:

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

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

可以向 rescue 函数提供一个 report 参数,用于确定异常是否应该通过 report 函数上报:

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

resolve()

resolve 函数使用服务容器将给定的类或接口名称解析为一个实例:

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

response()

response 函数会创建一个响应实例,或者获取响应工厂的实例:

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

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

retry()

retry 函数会尝试执行给定的回调,直到达到指定的最大尝试次数。如果回调没有抛出异常,则返回其返回值。如果回调抛出异常,则会自动重试。如果超过最大尝试次数,则会抛出异常:

return retry(5, function () {
    // 尝试 5 次,每次尝试之间休息 100 毫秒…
}, 100);
无与伦比 翻译于 1天前

如果你希望手动计算两次尝试之间需要休眠的毫秒数,可以将一个闭包作为第三个参数传递给 retry 函数:

use Exception;

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

为了方便起见,你可以将一个数组作为第一个参数传递给 retry 函数。该数组将用于确定后续每次尝试之间需要休眠的毫秒数:

return retry([100, 200], function () {
    // 第一次重试休眠 100 毫秒,第二次重试休眠 200 毫秒……
});

如果只希望在特定条件下进行重试,可以将一个闭包作为第四个参数传递给 retry 函数:

use Exception;

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

session()

session 函数可用于获取或设置 会话 的值:

$value = session('key');

你可以通过向该函数传递一个键 / 值对数组来设置值:

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

如果未向该函数传递任何值,则将返回会话存储实例:

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

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

tap()

tap 函数接收两个参数:一个任意的 $value 和一个闭包。$value 会被传递给该闭包,然后由 tap 函数返回。闭包的返回值并不重要:

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

    $user->save();
});

如果没有向 tap 函数传递闭包,你可以在给定的 $value 上调用任意方法。无论你调用的方法在其定义中实际返回什么,该方法的返回值始终都会是 $value。例如,Eloquent 的 update 方法通常返回一个整数。然而,我们可以通过 tap 函数链式调用 update 方法,强制该方法返回模型本身:

$user = tap($user)->update([
    'name' => $name,
    'email' => $email,
]);
无与伦比 翻译于 18小时前

要向一个类中添加 tap 方法,你可以将 Illuminate\Support\Traits\Tappable trait 添加到该类中。该 trait 的 tap 方法只接收一个 Closure 作为参数。对象实例本身会被传递给该闭包,然后由 tap 方法返回:

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

throw_if()

如果给定的布尔表达式计算结果为 truethrow_if 函数将抛出指定的异常:

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

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

throw_unless()

如果给定的布尔表达式计算结果为 falsethrow_unless 函数将抛出指定的异常:

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

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

today()

today 函数会为当前日期创建一个新的 Illuminate\Support\Carbon 实例:

$today = today();

trait_uses_recursive()

trait_uses_recursive 函数返回某个 trait 所使用的所有 trait:

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

transform()

如果给定的值不是 blanktransform 函数会对该值执行一个闭包,并返回该闭包的返回值:

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

$result = transform(5, $callback);

// 10

你可以将一个默认值或闭包作为该函数的第三个参数传入。如果给定的值是 blank,则会返回该值:

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

// The value is blank
无与伦比 翻译于 18小时前

validator()

validator 函数会使用给定的参数创建一个新的 验证器 实例。你可以将其作为 Validator 门面(facade)的替代方案来使用:

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

value()

value 函数会返回传入的值。不过,如果你向该函数传递一个闭包,则会执行该闭包,并返回其返回值:

$result = value(true);

// true

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

// false

你可以向 value 函数传递额外的参数。如果第一个参数是一个闭包,那么这些附加参数将作为参数传递给该闭包;否则它们将被忽略:

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

// 'Taylor'

view()

view 函数用于获取一个 视图 实例:

return view('auth.login');

with()

with 函数会返回传入的值。如果向该函数传递一个闭包作为第二个参数,则会执行该闭包,并返回其返回值:

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

当给定的条件计算结果为 true 时,when 函数会返回传入的值;否则返回 null。如果向该函数传递一个闭包作为第二个参数,则会执行该闭包,并返回其返回值:

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

$value = when(true, fn () => 'Hello World');
无与伦比 翻译于 18小时前

when 函数主要用于有条件地渲染 HTML 属性

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

其他工具

基准测试(Benchmarking)

有时你可能希望快速测试应用程序中某些部分的性能。在这种情况下,你可以使用 Benchmark 支持类来测量给定回调执行完成所需的毫秒数:

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

默认情况下,给定的回调只会执行一次(一次迭代),并且其耗时会显示在浏览器 / 控制台中。

如果希望多次调用某个回调,可以将该回调应执行的迭代次数作为方法的第二个参数指定。当回调被执行多次时,Benchmark 类将返回该回调在所有迭代中的平均执行时间(毫秒)

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

有时,你可能希望在对回调执行进行基准测试的同时,仍然获取该回调返回的值。value 方法会返回一个元组,其中包含回调返回的值以及执行该回调所花费的毫秒数:

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

日期(Dates)

Laravel 内置了功能强大的日期与时间处理库 Carbon。要创建一个新的 Carbon 实例,你可以调用 now 函数。该函数在你的 Laravel 应用中是全局可用的:

$now = now();
无与伦比 翻译于 18小时前

或者,你也可以使用 Illuminate\Support\Carbon 类来创建一个新的 Carbon 实例:

use Illuminate\Support\Carbon;

$now = Carbon::now();

关于 Carbon 及其功能的更全面说明,请查阅 官方 Carbon 文档

延迟函数(Deferred Functions)

虽然 Laravel 的 队列任务 允许你将任务放入队列以进行后台处理,但有时你可能只需要延迟执行一些简单的任务,而不希望配置或维护一个长期运行的队列工作进程。

延迟函数允许你在 HTTP 响应发送给用户之后 再执行一个闭包,从而让你的应用保持快速、响应灵敏。要延迟执行一个闭包,只需将该闭包传递给 Illuminate\Support\defer 函数即可:

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

Route::post('/orders', function (Request $request) {
    // 创建订单……

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

    return $order;
});

默认情况下,只有当调用 Illuminate\Support\defer 的 HTTP 响应、Artisan 命令或队列任务 成功完成 时,延迟函数才会被执行。这意味着,如果请求返回了 4xx5xx 的 HTTP 响应,延迟函数将不会被执行。如果你希望延迟函数始终执行,可以在延迟函数后链式调用 always 方法:

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

取消延迟函数(Cancelling Deferred Functions)

如果你需要在延迟函数执行之前将其取消,可以使用 forget 方法根据函数名称来取消该延迟函数。要为延迟函数命名,可以在调用 Illuminate\Support\defer 函数时提供第二个参数:

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

defer()->forget('reportMetrics');
无与伦比 翻译于 18小时前

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 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
贡献者:8
讨论数量: 2
发起讨论 只看当前版本


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