Работа с массивами в PHP: правильный путь

В этом уроке мы рассмотрим практические примеры работы с рядом PHP-шных функций для работы с массивами. Этот материал пригодится каждому PHP разработчику: позволит писать компактный и читабельный код.

Основы

Давайте начнём с простой функции, которая оперирует ключами и значениями элементов массивов. Одной из таких функций является array_combine(), которая создаёт новый массив из двух существующих: первый использует для создания ключей, второй в качестве значений:

$keys = ['sky', 'grass', 'orange'];
$values = ['blue', 'green', 'orange'];

$array = array_combine($keys, $values);
print_r($array);

// Array
// (
// 	[sky] => blue
// 	[grass] => green
// 	[orange] => orange
// )

В этом же разрезе вам могут пригодиться функции array_values(). Она извлекает из ассоциативного массива значения; array_keys() возвращает только ключи заданного массива; array_flip() меняет местами ключи и значения:

print_r(array_keys($array)); // ['sky', 'grass', 'orange']
print_r(array_values($array)); // ['blue', 'green', 'orange']
print_r(array_flip($array));

// Array
// (
// 	[blue] => sky
// 	[green] => grass
// 	[orange] => orange
// )

Сокращение кода

Функция list(), которая по сути является конструкцией языка, позволяет быстро присвоить значения массива ряду переменных. Простой пример работы с функцией list():

// define array
$array = ['a', 'b', 'c'];

// without list()
$a = $array[0];
$b = $array[1];
$c = $array[2];

// with list()
list($a, $b, $c) = $array;

Данный приём блестяще вписывается в совместную работу с функциями preg_slit() или explode(). Извлекать можно только те значения, которые действительно нужны:

$string = 'hello|wild|world';
list($hello, , $world) = explode('|', $string);
echo("$hello, $world"); // hello, world

Также функцию list() можно поместить в foreach:

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

foreach ($arrays as list($a, $b)) {
    $c = $a + $b;
    echo($c . ', '); // 3, 7, 11,
}

Чтобы извлечь значения из ассоциативного массива можно воспользоваться функцией extract(). В результате вы получите целый ряд переменных (имена которых совпадают с ключами массива):

$array = [
    'clothes' => 't-shirt',
    'size'	=> 'medium',
    'color'   => 'blue',
];

extract($array);

echo("$clothes $size $color"); // t-shirt medium blue

При работе с функцией extract() следует быть осторожным, особенно во время взаимодействия с пользовательскими данными (результатами запросов), поэтому рекомендуется использовать флаги EXTR_IF_EXISTS и EXTR_PREFIX_ALL.

Чтобы сделать противоположное действие можно воспользоваться функцией compact(), которая сформирует массив из ряда переменных:

$clothes = 't-shirt';
$size = 'medium';
$color = 'blue';

$array = compact('clothes', 'size', 'color');
print_r($array);

// Array
// (
// 	[clothes] => t-shirt
// 	[size] => medium
// 	[color] => blue
// )

Функции фильтрации

Для фильтрации данных лучшим образом подойдёт функция array_filter(). В качестве параметров необходимо передать массив и анонимную функцию-обработчик. Для того чтобы оставить элемент в массиве следует вернуть true, в обратном случае false:

$numbers = [20, -3, 50, -99, 55];

$positive = array_filter($numbers, function($number) {
    return $number > 0;
});

print_r($positive); // [0 => 20, 2 => 50, 4 => 55]

Фильтрацию можно произвести и по ключам. Для этого следует воспользоваться третьим параметром, флагом ARRAY_FILTER_USE_KEY или ARRAY_FILTER_USE_BOTH.

Вдобавок к этому, можете вызвать array_filter() без аргументов. В результате из массива будут удалены все пустые значения:

$numbers = [-1, 0, 1];

$not_empty = array_filter($numbers);

print_r($not_empty); // [0 => -1, 2 => 1]

Для того чтобы получить из массива только уникальные значения следует вызвать функцию array_unique(). Стоит отметить, что в результирующий массив войдут только первые найденные элементы:

$array = [1, 1, 1, 1, 2, 2, 2, 3, 4, 5, 5];
$uniques = array_unique($array);

print_r($uniques);

// Array
// (
// 	[0] => 1
// 	[4] => 2
// 	[7] => 3
// 	[8] => 4
// 	[9] => 5
// )

Функция array_column() будет полезна если вам необходимо извлечь определённый столбец многомерного массива. Это может быть результат SQL запроса или данные из файла CSV. Вам следует указать массив и название колонки:

$array = [
    ['id' => 1, 'title' => 'tree'],
    ['id' => 2, 'title' => 'sun'],
    ['id' => 3, 'title' => 'cloud'],
];

$ids = array_column($array, 'id');

print_r($ids); // [1, 2, 3]

В PHP 7 функция array_column() получила небольшой апгрэйд: возможность взаимодействия с полями объекта. Это в значительной мере упрощает работу с массивами моделей:

$cinemas = Cinema::find()->all();
$cinema_ids = array_column($cinemas, 'id'); // php7 forever!

Обход массивов

array_map() позволяет обойти все элементы массива и указать функцию обратного вызова. Вы можете передать как анонимку, так и название существующей функции. В результате получите массив с преобразованными значениями:

$cities = ['Berlin', 'KYIV', 'Amsterdam', 'Riga'];
$aliases = array_map('strtolower', $cities);

print_r($aliases); // ['berlin', 'kyiv, 'amsterdam', 'riga']

$numbers = [1, -2, 3, -4, 5];
$squares = array_map(function($number) {
    return $number ** 2;
}, $numbers);

print_r($squares);  // [1, 4, 9, 16, 25]

Существует устойчивое заблуждение, что в функцию обратного вызова нельзя одновременно передавать и ключи, и значения. Это не так:

$model = ['id' => 7, 'name'=>'James'];

$callback = function($key, $value) {
    return "$key is $value";
};

$res = array_map($callback, array_keys($model), $model);
print_r($res);

// Array
// (
// 	[0] => id is 7
// 	[1] => name is James
// )

Это не самая лучшая реализация. Давайте воспользуемся функцией array_walk(). Она похожа на array_map(), но работает чуть иначе. Во-первых, исходные данные передаются по ссылке, в результате чего array_walk() обработает переданный массив, а не создаст новый. Таким образом мы сможем передать значения и ключи исходного массива по ссылке:

$fruits = [
    'banana' => 'yellow',
    'apple' => 'green',
    'orange' => 'orange',
];

array_walk($fruits, function(&$value, $key) {
    $value = "$key is $value";
});

print_r($fruits);

// Array
// (
// 	[banana] => banana is yellow
// 	[apple] => apple is green
// 	[orange] => orange is orange
// )

Объединение массивов

Вызов функции array_merge() — самый просто способ объединить несколько массивов. Все данные будут слиты воедино, повторяющиеся данные перезапишутся:

$array1 = ['a' => 'a', 'b' => 'b', 'c' => 'c'];
$array2 = ['a' => 'A', 'b' => 'B', 'D' => 'D'];

$merge = array_merge($array1, $array2);
print_r($merge);
// Array
// (
//     [a] => A
//     [b] => B
//     [c] => c
//     [D] => D
// )

Для того чтобы удалить значения одного массива из другого массива воспользуйтесь функцией array_diff(). Обратная операция реализуется при помощи вызова array_intersect(). Примеры:

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

$diff = array_diff($array1, $array2);
print_r($diff); // [0 => 1, 1 => 2]

$intersect = array_intersect($array1, $array2);
print_r($intersect);  // [2 => 3, 3 => 4]

Математические операции

С помощью функции array_sum() можно посчитать сумму элементов массива; array_product() перемножит все значения; array_reduce() позволит применить свою собственную формулу:

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

echo(array_sum($numbers)); // 15
echo(array_product($numbers)); // 120

echo(array_reduce($numbers, function($carry, $item) {
    return $carry ? $carry / $item : 1;
})); // 0.0083 = 1/2/3/4/5

Функция array_count_values() поможет посчитать количество всех уникальных значений массива:

$things = ['apple', 'apple', 'banana', 'tree', 'tree', 'tree'];
$values = array_count_values($things);

print_r($values);

// Array
// (
// 	[apple] => 2
// 	[banana] => 1
// 	[tree] => 3
// )

Генерирование массивов

Для того чтобы сформировать массив из заданного количества элементов, и задать им единое значение следует воспользоваться функцией array_fill():

$bind = array_fill(0, 5, '?');
print_r($bind); // ['?', '?', '?', '?', '?']

Чтобы получить массив, элементы которого должно варьировать в диапазоне часов или букв следует вызывать функцию range():

$letters = range('a', 'z');
print_r($letters); // ['a', 'b', ..., 'z']

$hours = range(0, 23);
print_r($hours); // [0, 1, 2, ..., 23]

Чтобы обрезать массив — получить первые три элемента — достаточно вызвать функцию array_slice():

$numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
$top = array_slice($numbers, 0, 3);
print_r($top); // [1, 2, 3]

Сортировка массивов

Следует знать, что все PHP-шные функции сортировки работают с исходными массивами по ссылке и возвращают true в случае успеха и false при неудаче. Функция sort() сортирует элементы массива в возрастающем порядке и присваивает новые ключи элементам массива. Разновидности сортировки в зависимости от префиксной буквы:

  • a, сортировка, сохраняющая отношения между ключами и значениями
  • k, сортировка по ключам
  • r, сортировка в прямом/обратном порядке
  • u, сортировка при помощи пользовательской функции

Доступны комбинации видов сортировки:

  a k r u
a asort   arsort uasort
k   ksort krsort  
r arsort krsort rsort  
u uasort     usort

Работаем с массивами как профи

Поистине крутые вещи начинают происходить, когда мы комбинируем несколько вышеупомянутых функций. К примеру мы можем убрать из массива все пустые значения, вызвав array_filter() и array_map():

$values = ['say  ', '  bye', ' ', ' to', ' spaces ', '   '];

$words = array_filter(array_map('trim', $values));
print_r($words); // ['say', 'bye', 'to', 'spaces']

Чтобы получить идентификаторы и названия объектов моделей достаточно вызывать array_combine() и array_column():

$models = [$model1, $model2, $model3];

$id_to_title = array_combine(
    array_column($models, 'id'),
    array_column($models, 'title')
);

Подсчёт трёх самых часто используемых элемента массива можно осуществить вызовом array_count_values(), arsort() и array_slice():

$letters = ['a', 'a', 'a', 'a', 'b', 'b', 'c', 'd', 'd', 'd', 'd', 'd'];

$values = array_count_values($letters); // get key to count array
arsort($values); // sort descending preserving key
$top = array_slice($values, 0, 3); // get top 3

print_r($top);
// Array
// (
// 	[d] => 5
// 	[a] => 4
// 	[b] => 2
// )

Комбинация функций array_sum() и array_map() позволит с лёгкостью подсчитать сумму товаров в корзине:

$order = [
    ['product_id' => 1, 'price' => 99, 'count' => 1],
    ['product_id' => 2, 'price' => 50, 'count' => 2],
    ['product_id' => 2, 'price' => 17, 'count' => 3],
];

$sum = array_sum(array_map(function($product_row) {
    return $product_row['price'] * $product_row['count'];
}, $order));

print_r($sum); // 250

Заключение

Данный урок — лишний повод убедиться в том, что знание элементарных функций поможет сделать ваш код более ёмким и читабельным. Конечно же это далеко не весь список функций для работы с массивами, которые есть в PHP. Ещё больше возможностей открываются в случае использования специальных параметров и флагов. В этом уроке мы рассмотрели основы основ, о которых должен знать каждый PHP разработчик.

Данный урок подготовлен для вас командой сайта ruseller.com
Источник урока: https://code.tutsplus.com/tutorials/working-with-php-arrays-in-the-right-way--cms-28606
Перевел: Станислав Протасевич
Урок создан: 27 Апреля 2017
Просмотров: 17740
Правила перепечатки


5 последних уроков рубрики "PHP"

  • Фильтрация данных с помощью zend-filter

    Когда речь идёт о безопасности веб-сайта, то фраза "фильтруйте всё, экранируйте всё" всегда будет актуальна. Сегодня поговорим о фильтрации данных.

  • Контекстное экранирование с помощью zend-escaper

    Обеспечение безопасности веб-сайта — это не только защита от SQL инъекций, но и протекция от межсайтового скриптинга (XSS), межсайтовой подделки запросов (CSRF) и от других видов атак. В частности, вам нужно очень осторожно подходить к формированию HTML, CSS и JavaScript кода.

  • Подключение Zend модулей к Expressive

    Expressive 2 поддерживает возможность подключения других ZF компонент по специальной схеме. Не всем нравится данное решение. В этой статье мы расскажем как улучшили процесс подключение нескольких модулей.

  • Совет: отправка информации в Google Analytics через API

    Предположим, что вам необходимо отправить какую-то информацию в Google Analytics из серверного скрипта. Как это сделать. Ответ в этой заметке.

  • Подборка PHP песочниц

    Подборка из нескольких видов PHP песочниц. На некоторых вы в режиме online сможете потестить свой код, но есть так же решения, которые можно внедрить на свой сайт.

^ Наверх ^