Skip to content

帮助函数

介绍

Laravel 包含各种全局 “helper” PHP 函数。其中许多函数由框架本身使用;但是,如果您觉得它们方便,您可以在自己的应用程序中自由使用它们。

可用方法

Arrays & Objects

Numbers

Paths

URLs

杂项

Arrays & Objects

Arr::accessible()

Arr::accessible 方法确定给定的值是否为数组可访问:

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

如果给定的键在数组中尚不存在或设置为 null则 Arr::add 方法会将给定的键/值对添加到数组中:

php
    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::collapse()

Arr::collapse 方法将数组数组折叠为单个数组:

php
    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 方法交叉联接给定的数组,返回具有所有可能排列的笛卡尔积:

php
    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 方法返回两个数组:一个包含键,另一个包含给定数组的值:

php
    use Illuminate\Support\Arr;

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

    // $keys: ['name']

    // $values: ['Desk']

Arr::dot()

Arr::dot 方法将多维数组展平为使用“点”表示法表示深度的单级数组:

php
    use Illuminate\Support\Arr;

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

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

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

Arr::except()

Arr::except 方法从数组中删除给定的键/值对:

php
    use Illuminate\Support\Arr;

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

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

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

Arr::exists()

Arr::exists 方法检查给定的键是否存在于提供的数组中:

php
    use Illuminate\Support\Arr;

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

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

    // true

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

    // false

Arr::first()

Arr::first 方法返回通过给定真值测试的数组的第一个元素:

php
    use Illuminate\Support\Arr;

    $array = [100, 200, 300];

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

    // 200

默认值也可以作为第三个参数传递给方法。如果没有值通过真值测试,则将返回此值:

php
    use Illuminate\Support\Arr;

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

Arr::flatten()

Arr::flatten 方法将多维数组展平为单级数组:

php
    use Illuminate\Support\Arr;

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

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

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

Arr::forget()

Arr::forget 方法使用 “点” 表示法从深度嵌套的数组中删除给定的键/值对:

php
    use Illuminate\Support\Arr;

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

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

    // ['products' => []]

Arr::get()

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

php
    use Illuminate\Support\Arr;

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

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

    // 100

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

php
    use Illuminate\Support\Arr;

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

    // 0

Arr::has()

Arr::has 方法使用 “点” 表示法检查数组中是否存在给定的项或项:

php
    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::hasAny()

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

php
    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::isAssoc()

如果给定数组是关联数组,则 Arr::isAssoc 方法返回 true。如果数组没有以零开头的顺序数字键,则认为该数组是“关联”的:

php
    use Illuminate\Support\Arr;

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

    // true

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

    // false

Arr::isList()

如果给定数组的键是从零开始的连续整数,则 Arr::isList 方法返回 true:

php
    use Illuminate\Support\Arr;

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

    // true

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

    // false

Arr::join()

Arr::join 方法将数组元素与字符串联接起来。使用此方法的第二个参数,您还可以为数组的最后一个元素指定连接字符串:

php
    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 方法按给定的键对数组进行键控。如果多个项目具有相同的键,则只有最后一个项目会出现在新数组中:

php
    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 方法返回通过给定真值测试的数组的最后一个元素:

php
    use Illuminate\Support\Arr;

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

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

    // 300

默认值可以作为第三个参数传递给该方法。如果没有值通过真值测试,则将返回此值:

php
    use Illuminate\Support\Arr;

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

Arr::map()

Arr::map 方法遍历数组并将每个值和键传递给给定的回调。数组值将替换为回调返回的值:

php
    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 方法迭代数组,将每个嵌套项值传递到给定的闭包中。闭包可以自由修改 item 并返回它,从而形成一个新的修改项数组:

php
    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 方法遍历数组并将每个值传递给给定的回调。回调应返回一个包含单个键 / 值对的关联数组:

php
    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 方法仅返回给定数组中的指定键/值对:

php
    use Illuminate\Support\Arr;

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

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

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

Arr::pluck()

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

php
    use Illuminate\Support\Arr;

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

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

    // ['Taylor', 'Abigail']

您还可以指定您希望如何对结果列表进行键控:

php
    use Illuminate\Support\Arr;

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

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

Arr::prepend()

Arr::prepend 方法会将项目推送到数组的开头:

php
    use Illuminate\Support\Arr;

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

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

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

如果需要,您可以指定应用于该值的键:

php
    use Illuminate\Support\Arr;

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

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

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

Arr::prependKeysWith()

Arr::prependKeysWith 在关联数组的所有键名前面加上给定的前缀:

php
    use Illuminate\Support\Arr;

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

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

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

Arr::pull()

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

php
    use Illuminate\Support\Arr;

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

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

    // $name: Desk

    // $array: ['price' => 100]

默认值可以作为第三个参数传递给该方法。如果 key 不存在,将返回此值:

php
    use Illuminate\Support\Arr;

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

Arr::query()

Arr::query 方法将数组转换为查询字符串:

php
    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 方法从数组中返回一个随机值:

php
    use Illuminate\Support\Arr;

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

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

    // 4 - (retrieved randomly)

您还可以指定要作为可选的第二个参数返回的项目数。请注意,即使只需要一个项目,提供此参数也将返回一个数组:

php
    use Illuminate\Support\Arr;

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

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

Arr::set()

Arr::set 方法使用 “点” 表示法在深度嵌套的数组中设置一个值:

php
    use Illuminate\Support\Arr;

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

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

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

Arr::shuffle()

Arr::shuffle 方法随机对数组中的项进行随机排序:

php
    use Illuminate\Support\Arr;

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

    // [3, 2, 5, 1, 4] - (generated randomly)

Arr::sort()

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

php
    use Illuminate\Support\Arr;

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

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

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

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

php
    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 方法按数组的值降序对数组进行排序:

php
    use Illuminate\Support\Arr;

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

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

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

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

php
    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'],
        ]
    */

Arr::sortRecursive()

Arr::sortRecursive 方法对数字索引的子数组使用 sort 函数,对关联子数组使用 ksort 函数递归排序:

php
    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 方法。

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

Arr::take()

Arr::take 方法返回一个具有指定项目数的新数组:

php
    use Illuminate\Support\Arr;

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

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

    // [0, 1, 2]

您还可以传递一个负整数,从数组的末尾获取指定数量的项目:

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

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

    // [4, 5]

Arr::toCssClasses()

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

php
    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'
    */

Arr::toCssStyles()

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

php
use Illuminate\Support\Arr;

$hasColor = true;

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

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

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

此方法为 Laravel 的功能提供支持,允许将类与 Blade 组件的属性 bag 以及 @classBlade 指令合并。

Arr::undot()

Arr::undot 方法将使用 “dot” 表示法的一维数组扩展为多维数组:

php
    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 方法使用给定的闭包过滤数组:

php
    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 值:

php
    use Illuminate\Support\Arr;

    $array = [0, null];

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

    // [0 => 0]

Arr::wrap()

Arr::wrap 方法将给定的值包装在一个数组中。如果给定的值已经是一个数组,则无需修改即可返回:

php
    use Illuminate\Support\Arr;

    $string = 'Laravel';

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

    // ['Laravel']

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

php
    use Illuminate\Support\Arr;

    $array = Arr::wrap(null);

    // []

data_fill()

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

php
    $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]]]

此函数还接受星号作为通配符,并相应地填充目标:

php
    $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 函数使用 “点” 表示法从嵌套数组或对象中检索值:

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

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

    // 100

data_get 函数还接受默认值,如果未找到指定的键,将返回该值:

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

    // 0

该函数还接受使用星号的通配符,这些通配符可以针对数组或对象的任何键:

php
    $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} 占位符可用于检索数组中的第一项或最后一项:

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

data_set()

data_set 函数使用 “点” 表示法在嵌套数组或对象中设置值:

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

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

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

此函数还接受使用星号的通配符,并将相应地在目标上设置值:

php
    $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 作为第四个参数传递给函数:

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

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

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

data_forget()

data_forget 函数使用 “点” 表示法删除嵌套数组或对象中的值:

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

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

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

此函数还接受使用星号的通配符,并相应地删除目标上的值:

php
    $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 函数返回给定数组中的第一个元素:

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

    $first = head($array);

    // 100

last()

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

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

    $last = last($array);

    // 300

Numbers

Number::abbreviate()

Number::abbreviate 方法返回所提供数值的人类可读格式,以及单位的缩写:

php
    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 方法确保给定的数字保持在指定范围内。如果该数字小于最小值,则返回最小值。如果该数字大于最大值,则返回最大值:

php
    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 方法以字符串形式返回给定值的货币表示形式:

php
    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 €

Number::fileSize()

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

php
    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

Number::forHumans()

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

php
    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 方法将给定的数字格式化为特定于语言环境的字符串:

php
    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 方法返回数字的序数表示形式:

php
    use Illuminate\Support\Number;

    $number = Number::ordinal(1);

    // 1st

    $number = Number::ordinal(2);

    // 2nd

    $number = Number::ordinal(21);

    // 21st

Number::pairs()

Number::pairs 方法根据指定的范围和步长值生成数字对(子范围)的数组。此方法可用于将较大的数字范围划分为较小的、可管理的子范围,以用于分页或批处理任务等操作。pairs 方法返回一个数组的数组,其中每个内部数组表示一对(子范围)数字:

php
use Illuminate\Support\Number;

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

// [[1, 10], [11, 20], [21, 25]]

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

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

Number::percentage()

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

php
    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 方法将给定的数字转换为单词字符串:

php
    use Illuminate\Support\Number;

    $number = Number::spell(102);

    // one hundred and two

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

    // quatre-vingt-huit

after 参数允许您指定一个值,之后所有数字都应拼写出来:

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

    // 10

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

    // eleven

until 参数允许您指定一个值,在此之前所有数字都应拼写出来:

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

    // five

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

    // 10

Number::trim()

Number::trim 方法删除给定数字的小数点后的任何尾随零数字:

php
    use Illuminate\Support\Number;

    $number = Number::trim(12.0);

    // 12

    $number = Number::trim(12.30);

    // 12.3

Number::useLocale()

Number::useLocale 方法全局设置默认数字区域设置,这会影响对 Number 类方法的后续调用如何格式化数字和货币:

php
    use Illuminate\Support\Number;

    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        Number::useLocale('de');
    }

Number::withLocale()

Number::withLocale 方法使用指定的 locale 执行给定的闭包,然后在回调执行后恢复原始 locale:

php
    use Illuminate\Support\Number;

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

Paths

app_path()

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

php
    $path = app_path();

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

base_path()

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

php
    $path = base_path();

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

config_path()

config_path 函数返回应用程序的 config 目录的完全限定路径。您还可以使用 config_path 函数在应用程序的配置目录中生成给定文件的完全限定路径:

php
    $path = config_path();

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

database_path()

database_path 函数返回应用程序数据库目录的完全限定路径。您还可以使用 database_path 函数生成数据库目录中给定文件的完全限定路径:

php
    $path = database_path();

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

lang_path()

lang_path 函数返回应用程序的 lang 目录的完全限定路径。您还可以使用 lang_path 函数生成目录中给定文件的完全限定路径:

php
    $path = lang_path();

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

NOTE

默认情况下,Laravel 应用程序框架不包括 lang 目录。如果你想自定义 Laravel 的语言文件,你可以通过 lang:publish Artisan 命令发布它们。

mix()

mix 函数返回版本控制的 Mix 文件的路径:

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

public_path()

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

php
    $path = public_path();

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

resource_path()

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

php
    $path = resource_path();

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

storage_path()

storage_path 函数返回应用程序存储目录的完全限定路径。您还可以使用 storage_path 函数生成 storage 目录中给定文件的完全限定路径:

php
    $path = storage_path();

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

URLs

action()

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

php
    use App\Http\Controllers\HomeController;

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

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

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

asset()

asset 函数使用请求的当前方案(HTTP 或 HTTPS)为资产生成 URL:

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

您可以通过在 .env 文件中设置 ASSET_URL 变量来配置资产 URL 主机。如果您在 Amazon S3 或其他 CDN 等外部服务上托管资产,这可能非常有用:

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

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

route()

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

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

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

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

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

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

secure_asset()

secure_asset 函数使用 HTTPS 为资产生成 URL:

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

secure_url()

secure_url 函数生成指向给定路径的完全限定 HTTPS URL。可以在函数的第二个参数中传递其他 URL 段:

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

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

to_route()

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

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

如有必要,您可以将应分配给重定向的 HTTP 状态代码和任何其他响应标头作为第三个和第四个参数传递给 to_route 方法:

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

url()

url 函数生成指向给定路径的完全限定 URL:

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

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

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

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

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

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

杂项

abort()

abort 函数会抛出一个 HTTP 异常,该异常将由异常处理程序呈现:

php
    abort(403);

您还可以提供异常的消息和应发送到浏览器的自定义 HTTP 响应标头:

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

abort_if()

如果给定的布尔表达式的计算结果为 true则 abort_if 函数会引发 HTTP 异常:

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

abort 方法一样,您也可以将异常的响应文本作为第三个参数提供,并将自定义响应标头数组作为函数的第四个参数提供。

abort_unless()

如果给定的布尔表达式的计算结果为 false则 abort_unless 函数会引发 HTTP 异常:

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

Like the abort method, you may also provide the exception's response text as the third argument and an array of custom response headers as the fourth argument to the function.

app()

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

php
    $container = app();

您可以传递类或接口名称以从容器中解析它:

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

auth()

auth 函数返回一个 authenticator 实例。您可以将其用作 Auth Facade 的替代方案:

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

如果需要,您可以指定要访问的 guard 实例:

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

back()

back 函数生成对用户之前位置的重定向 HTTP 响应

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

    return back();

bcrypt()

bcrypt 函数使用 Bcrypt 对给定值进行哈希处理。您可以使用此函数作为 Hash Facade的替代方案:

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

blank()

blank 函数确定给定的值是否为 “blank”:

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

    // true

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

    // false

有关 blank 的逆函数,请参阅 filled 方法。

broadcast()

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

php
    broadcast(new UserRegistered($user));

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

cache()

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

php
    $value = cache('key');

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

您可以通过将键/值对数组传递给函数来将项目添加到缓存中。您还应该传递缓存值应被视为有效的秒数或持续时间:

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

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

class_uses_recursive()

class_uses_recursive 函数返回类使用的所有特征,包括其所有父类使用的特征:

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

collect()

collect 函数从给定值创建一个 collection 实例:

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

config()

config 函数获取配置变量的值。可以使用 “点” 语法访问配置值,其中包括文件名和您希望访问的选项。可以指定默认值,如果 configuration 选项不存在,则返回默认值:

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

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

您可以通过传递键/值对数组在运行时设置配置变量。但是,请注意,此函数仅影响当前请求的配置值,不会更新您的实际配置值:

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

context()

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

php
    $value = context('trace_id');

    $value = context('trace_id', $default);

您可以通过传递键/值对数组来设置上下文值:

php
    use Illuminate\Support\Str;

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

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

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

csrf_field()

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

    {{ csrf_field() }}

csrf_token()

csrf_token 函数检索当前 CSRF 令牌的值:

php
    $token = csrf_token();

decrypt()

decrypt 函数解密给定的值。您可以使用此函数作为 Crypt Facade的替代方案:

php
    $password = decrypt($value);

dd()

dd 函数转储给定的变量并结束脚本的执行:

php
    dd($value);

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

如果您不想停止脚本的执行,请改用 dump 函数。

dispatch()

dispatch 函数将给定的 作业推送到 Laravel 作业队列中:

php
    dispatch(new App\Jobs\SendEmails);

dispatch_sync()

dispatch_sync 函数将给定作业推送到同步队列,以便立即处理它:

php
    dispatch_sync(new App\Jobs\SendEmails);

dump()

dump 函数转储给定的变量:

php
    dump($value);

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

如果要在转储变量后停止执行脚本,请改用 dd 函数。

encrypt()

encrypt 函数对给定的值进行加密。您可以使用此函数作为 Crypt Facade的替代方案:

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

env()

env 函数检索环境变量的值或返回默认值:

php
    $env = env('APP_ENV');

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

WARNING

如果您在部署过程中执行 config:cache 命令,则应确保仅从配置文件中调用 env 函数。缓存配置后,将不会加载 .env 文件,并且对 env 函数的所有调用都将返回 null

event()

event 函数将给定的 事件分派给其侦听器:

php
    event(new UserRegistered($user));

fake()

fake 函数从容器中解析 Faker 单例,这在模型工厂、数据库种子、测试和原型视图中创建假数据时非常有用:

blade
@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 环境变量设置的。您还可以通过将 locale 传递给 fake 函数来指定 locale。每个 locale 将解析一个单独的单例:

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

filled()

filled 函数确定给定的值是否为 “blank”:

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

    // true

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

    // false

有关 filled 的逆函数,请参阅 blank 方法。

info()

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

php
    info('Some helpful information!');

上下文数据数组也可以传递给函数:

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

literal()

literal 函数创建一个新的 stdClass 实例,并将给定的命名参数作为属性:

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

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

logger()

logger 函数可用于将调试级别消息写入日志

php
    logger('Debug message');

上下文数据数组也可以传递给函数:

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

如果未向函数传递任何值,则将返回 Logger 实例:

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

method_field()

method_field 函数生成一个 HTML 隐藏输入字段,其中包含表单的 HTTP 动词的欺骗值。例如,使用 Blade 语法

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

now()

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

php
    $now = now();

old()

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

php
    $value = old('value');

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

old函数检索刷入会话的旧 input 值:

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

    // Is equivalent to...

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

once()

由于作为函数的第二个参数提供的“默认值”通常是 Eloquent 模型的一个属性,因此 Laravel 允许您简单地将整个 Eloquent 模型作为第二个参数传递给函数。这样做时,Laravel 将假设提供给函数的第一个参数是 Eloquent 属性的名称,该属性应被视为“默认值”:

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

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

once 函数执行给定的回调,并在请求期间将结果缓存在内存中。对具有相同回调的 once 函数的任何后续调用都将返回之前缓存的结果:

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

optional函数接受任何参数,并允许您访问该对象的属性或调用方法。如果给定的对象为 null,则属性和方法将返回 null,而不是导致错误:

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

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

optional函数还接受 closure 作为其第二个参数。如果作为第一个参数提供的值不为 null,则将调用闭包:

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

policy()

policy 方法检索给定类的 policy 实例:

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

redirect()

redirect 函数返回重定向 HTTP 响应,或者如果调用时不带参数,则返回 redirector 实例:

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

    return redirect('/home');

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

report()

report 函数将使用异常处理程序报告异常:

php
    report($e);

report 函数还接受字符串作为参数。当为函数提供字符串时,该函数将创建一个异常,并将给定的字符串作为其消息:

php
    report('Something went wrong.');

report_if()

如果给定条件为 true,则 report_if 函数将使用异常处理程序报告异常:

php
    report_if($shouldReport, $e);

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

report_unless()

如果给定条件为 falsereport_unless 函数将使用异常处理程序报告异常:

php
    report_unless($reportingDisabled, $e);

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

request()

request函数返回当前请求实例或从当前请求中获取输入字段的值:

php
    $request = request();

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

rescue()

rescue 函数执行给定的闭包并捕获其执行期间发生的任何异常。捕获的所有异常都将发送到您的异常处理程序;但是,请求将继续处理:

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

您还可以将第二个参数传递给 rescue 函数。此参数将是如果在执行闭包时发生异常时应返回的 “default” 值:

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

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

可以向 rescue 函数提供 report 参数,以确定是否应通过 report 函数报告异常:

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

resolve()

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

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

response()

response函数创建响应实例或获取响应工厂的实例:

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

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

retry()

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

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

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

php
    use Exception;

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

为方便起见,您可以提供一个数组作为 retry 函数的第一个参数。此数组将用于确定在后续尝试之间休眠的毫秒数:

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

要仅在特定条件下重试,您可以将闭包作为第四个参数传递给retry 函数:

php
    use Exception;

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

session()

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

php
    $value = session('key');

您可以通过将键/值对数组传递给函数来设置值:

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

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

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

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

tap()

tap 函数接受两个参数:任意 $value 和闭包。$value 将传递给闭包,然后由 tap 函数返回。闭包的返回值无关紧要:

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

        $user->save();
    });

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

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

要将 tap 方法添加到类中,您可以将 Illuminate\Support\Traits\Tappable trait 添加到类中。此 trait 的 tap 方法接受 Closure 作为其唯一参数。对象实例本身将被传递给 Closure,然后由 tap 方法返回:

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

throw_if()

如果给定的布尔表达式的计算结果为 true,则 throw_if 函数将引发给定的异常:

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

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

throw_unless()

如果给定的布尔表达式的计算结果为 false,则 throw_unless 函数将引发给定的异常:

php
    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 实例:

php
    $today = today();

trait_uses_recursive()

trait_uses_recursive 函数返回 trait 使用的所有特征:

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

transform()

如果该值不blank则 transform 函数对给定值执行闭包,然后返回闭包的返回值:

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

    $result = transform(5, $callback);

    // 10

默认值或闭包可以作为第三个参数传递给函数。如果给定值为空,则将返回此值:

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

    // The value is blank

validator()

validator 函数使用给定的参数创建一个新的 validator 实例。您可以将其用作 Validator Facade的替代方案:

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

value()

value 函数返回给定的值。但是,如果你将一个闭包传递给函数,闭包将被执行并返回其返回值:

php
    $result = value(true);

    // true

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

    // false

可以将其他参数传递给 value 函数。如果第一个参数是闭包,则附加参数将作为参数传递给闭包,否则它们将被忽略:

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

    // 'Taylor'

view()

view 函数检索一个 view 实例:

php
    return view('auth.login');

with()

with 函数返回给定的值。如果将闭包作为第二个参数传递给函数,则将执行闭包并返回其返回值:

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

基他函数

Benchmarking

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

php
    <?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 类将返回在所有迭代中执行回调所花费的平均毫秒数:

php
    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:

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

Dates

Laravel 包括 Carbon,这是一个强大的日期和时间操作库。要创建新的 Carbon 实例,您可以调用 now 函数。此功能在您的 Laravel 应用程序中全局可用:

php
$now = now();

或者,您可以使用 Illuminate\Support\Carbon 类创建新的 Carbon 实例:

php
use Illuminate\Support\Carbon;

$now = Carbon::now();

有关 Carbon 及其功能的全面讨论,请查阅 Carbon 官方文档

Lottery

Laravel 的 lottery 类可用于根据一组给定的赔率执行回调。当您只想为一定比例的传入请求执行代码时,这可能特别有用:

php
    use Illuminate\Support\Lottery;

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

您可以将 Laravel 的彩票类与其他 Laravel 功能结合使用。例如,您可能希望仅向异常处理程序报告一小部分慢速查询。而且,由于 lottery 类是可调用的,我们可以将类的实例传递给任何接受可调用对象的方法:

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

测试 Lotteries

Laravel 提供了一些简单的方法,让您能够轻松测试应用程序的 lottery 调用:

php
    // 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 的 Pipeline Facade提供了一种便捷的方法,可以通过一系列可调用的类、闭包或可调用对象来“管道”给定的输入,使每个类都有机会检查或修改输入并调用管道中的下一个可调用对象:

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

如您所见,管道中的每个可调用类或闭包都提供了 input 和 $next 闭包。调用 $next 闭包将调用管道中的下一个可调用对象。你可能已经注意到,这与 middleware 非常相似。

当管道中的最后一个可调用对象调用 $next 关闭时,将调用提供给 then 方法的可调用对象。通常,这个 callable 将只返回给定的 input。

当然,如前所述,您不仅限于为 pipeline 提供 closure。您还可以提供可调用的类。如果提供了类名,则该类将通过 Laravel 的服务容器进行实例化,从而允许将依赖项注入到可调用的类中:

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

Sleep

Laravel 的 Sleep 类是 PHP 原生 sleepusleep 函数的轻量级包装器,提供了更大的可测试性,同时还公开了开发人员友好的 API 来处理时间:

php
    use Illuminate\Support\Sleep;

    $waiting = true;

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

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

Sleep 类提供了多种方法,允许您使用不同的时间单位:

php
    // 暂停执行 90 秒...
    Sleep::for(1.5)->minutes();

    // 暂停执行 2 秒...
    Sleep::for(2)->seconds();

    // 暂停执行 500 毫秒...
    Sleep::for(500)->milliseconds();

    // 暂停执行 5000 微秒...
    Sleep::for(5000)->microseconds();

    // 暂停执行直到给定时间...
    Sleep::until(now()->addMinute());

    // PHP 原生 “sleep” 函数的别名...
    Sleep::sleep(2);

    // PHP 的原生 “usleep” 函数的别名...
    Sleep::usleep(5000);

要轻松组合时间单位,::

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

测试 Sleep

当测试使用 Sleep 类或 PHP 的本机 sleep 函数的代码时,您的测试将暂停执行。如您所料,这会使您的测试套件明显变慢。例如,假设您正在测试以下代码:

php
    $waiting = /* ... */;

    $seconds = 1;

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

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

通常,测试此代码至少需要 1 秒钟。幸运的是,Sleep 类允许我们 “假装” 休眠,以便我们的测试套件保持快速:

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

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

    // ...
}

当伪造 Sleep 类时,会绕过实际的执行暂停,从而导致测试速度大大加快。

一旦 Sleep 类被伪造,就可以对应该发生的预期 “sleeps” 进行断言。为了说明这一点,我们假设我们正在测试暂停执行 3 次的代码,每次暂停增加 1 秒。使用 assertSequence 方法,我们可以断言我们的代码 “休眠” 了适当的时间,同时保持测试的快速性:

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

    // ...

    Sleep::assertSequence([
        Sleep::for(1)->second(),
        Sleep::for(2)->seconds(),
        Sleep::for(3)->seconds(),
    ]);
}
php
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(),
    ]);
}

当然,Sleep 类提供了测试时可以使用的各种其他断言:

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

有时,每当应用程序代码中出现假睡眠时执行操作可能很有用。为此,你可以提供对 whenFakingSleep 方法的回调。在下面的示例中,我们使用 Laravel 的时间操作辅助函数来立即按每次睡眠的持续时间推进时间:

php
use Carbon\CarbonInterval as Duration;

$this->freezeTime();

Sleep::fake();

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

由于进度时间是一个常见的要求,因此 fake 方法接受 syncWithCarbon 参数,以便在测试中休眠时保持 Carbon 同步:

php
Sleep::fake(syncWithCarbon: true);

$start = now();

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

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

Laravel 在暂停执行时在内部使用 Sleep 类。例如,重试帮助程序在休眠时使用 Sleep 类,从而在使用该帮助程序时提高可测试性。