Новые функции массива в PHP 8.4
array_find
, array_find_key
, array_all
и array_any
. Кроме того, приведены аналоги в Laravel, для достижения тех же результатов.Введение
PHP 8.4 выйдет в ноябре 2024 года и представит несколько новых функций для работы с массивами:
array_find
array_find_key
array_any
array_all
Кратко рассмотрим эти новые функции и как их использовать в проектах на PHP 8.4.
Если вы Laravel разработчик, то возможно заметили, что уже есть подобные функции в классах Illuminate\Support\Collection
и Illuminate\Support\Arr
. Но мне нравится, что эти функции будут встроенными в PHP и поэтому будут доступны в любом PHP-проекте.
Для тех кто разрабатывает в Laravel, я покажу эквиваленты новых функций массивов PHP 8.4 в Laravel, чтобы можно было реализовать тот же функционал в своих Laravel проектах, не дожидаясь выхода PHP 8.4.
Функция array_find
Функция array_find
возвращает значение первого элемента, соответствующего критериям, заданным в обратном вызове. Если ни один элемент не соответствует запросу, функция возвращает null
.
Рассмотрим простой пример. Представим, что есть массив товаров, и нужно найти товар со штрих-кодом 123456
:
$products = [
[
'name' => 'Macbook Pro',
'type' => 'Laptop',
'barcode' => 123456,
],
[
'name' => 'Framework Laptop 13',
'type' => 'Laptop',
'barcode' => 789012,
],
[
'name' => 'Samsung Galaxy S24',
'type' => 'Phone',
'barcode' => 135791,
],
];
// Поиск товара со штрих-кодом 123456
$findProduct = array_find(
array: $products,
callback: function (array $product): bool {
return $product['barcode'] == 123456;
},
);
После выполнения вышеприведённого кода значение $findProduct
станет равным:
[
'name'=> 'Macbook Pro',
'type' => 'Laptop',
'barcode' => 123456,
]
Можно сделать код ещё немного чище, используя в качестве второго аргумента стрелочную функцию:
$findProduct = array_find(
array: $products,
callback: fn (array $product): bool => $product['barcode'] === 123456,
);
Код, вернёт тот же результат, что и в предыдущем примере.
Если ни один элемент не удовлетворяет требованиям обратного вызова, функция вернёт null
. Давайте посмотрим на примере:
$nonExistentProduct = array_find(
array: $products,
callback: fn (array $product): bool => $product['barcode'] === 'invalid',
);
В этом случае $nonExistentProduct
будет равен null
.
Эквивалент array_find
в Laravel
В Laravel аналогичного результата можно добиться с помощью метода Arr::first
:
use Illuminate\Support\Arr;
$findProduct = Arr::first(
$products,
fn (array $product): bool => $product['barcode'] === 123456,
);
Функция array_find_key
Эта функция аналогична функции array_find
, но вместо возвращения значения первого элемента, соответствующего обратному вызову, она возвращает ключ первого элемента, соответствующего обратному вызову.
Возьмём массив $products
из предыдущего примера. На этот раз нужно найти ключ товара со штрих-кодом 789012
:
$products = [
[
'name' => 'Macbook Pro',
'type' => 'Laptop',
'barcode' => 123456,
],
[
'name' => 'Framework Laptop 13',
'type' => 'Laptop',
'barcode' => 789012,
],
[
'name' => 'Samsung Galaxy S24',
'type' => 'Phone',
'barcode' => 135791,
],
];
// Поиск ключа к товару со штрих-кодом 789012
$findProduct = array_find_key(
array: $products,
callback: fn (array $product): bool => $product['barcode'] === 789012,
);
После выполнения вышеприведённого кода $findProduct
будет равен 1
, поскольку товар является вторым элементом в массиве.
Если ни один элемент не удовлетворяет условиям обратного вызова, функция вернёт null
. Давайте рассмотрим это на примере:
$nonExistentProduct = array_find_key(
array: $products,
callback: fn (array $product): bool => $product['barcode'] === 'invalid',
);
В этом случае $nonExistentProduct
будет равен null
.
Эквивалент array_find_key
в Laravel
В Laravel можно добиться аналогичного результата, используя комбинацию методов array_keys
и Arr::first
:
use Illuminate\Support\Arr;
$firstProductKey = Arr::first(
array_keys($products),
fn (int $key): bool => $products[$key]['barcode'] === 789012,
);
В приведённом выше коде сначала используется array_keys
для получения массива ключей массива $products
. Затем с помощью Arr::first
находится первый ключ, соответствующий обратному вызову. Это немного более многословный способ, чем встроенная функция PHP, но результат тот же.
Функция array_any
Функция array_any
позволяет проверить, что хотя бы один элемент массива соответствует критериям, заданным в обратном вызове. Если какой-либо элемент соответствует обратному вызову, функция возвращает true
. Если ни один элемент не соответствует обратному вызову, функция возвращает false
.
Используя массив $products
, проверим, имеет ли какой-либо из товаров тип Laptop
:
$anyProductsAreLaptops = array_any(
array: $products,
callback: fn (array $product): bool => $product['type'] === 'Laptop',
);
В данном случае $anyProductsAreLaptops
будет равно true
, потому что хотя бы один из продуктов в массиве является ноутбуком.
Если ни один элемент не соответствует обратному вызову, функция вернёт false
. Давайте рассмотрим это на примере:
$anyProductsAreInvalid = array_any(
array: $products,
callback: fn (array $product): bool => $product['type'] === 'Invalid',
);
В этом случае $anyProductsAreInvalid
будет равно false
.
Эквивалент array_any
в Laravel
В Laravel можно получить тот же результат, используя метод contains
на коллекции:
use Illuminate\Support\Collection;
$anyProductsAreLaptops = Collection::make($products)->contains(
fn (array $product): bool => $product['type'] === 'Laptop',
);
В приведённом выше коде из массива $products
создаётся коллекция, а затем с помощью метода contains
проверяется, является ли какой-либо из продуктов в коллекции ноутбуком.
Функция array_all
Функция array_all
аналогична функции array_any
, но вместо того, чтобы проверять, соответствует ли хотя бы один элемент обратному вызову, она проверяет, соответствуют ли все элементы обратному вызову. Если все элементы соответствуют обратному вызову, функция возвращает true
. Если какой-либо элемент не соответствует обратному вызову, функция возвращает false
.
Давайте проверим, все ли товары в массиве $products
являются ноутбуками:
$allProductsAreLaptops = array_all(
array: $products,
callback: fn (array $product): bool => $product['type'] === 'Laptop',
);
В этом случае $allProductsAreLaptops
будет равно false
, потому что не все товары в массиве являются ноутбуками.
Эквивалент array_all
в Laravel
В Laravel можно получить тот же результат, используя метод every
на коллекции:
use Illuminate\Support\Collection;
$allProductsAreLaptops = Collection::make($products)->every(
fn (array $product): bool => $product['type'] === 'Laptop',
);
В приведённом выше коде из массива $products
создаётся коллекция, а затем с помощью метода every
проверяется, все ли товары в коллекции являются ноутбуками.
Заключение
Надеюсь, эта статья продемонстрировала, как можно использовать новые функции массивов, представленные в PHP 8.4. Она также должна была дать представление, как можно достичь аналогичной функциональности в Laravel, используя классы Illuminate\Support\Collection
и Illuminate\Support\Arr
.