Yii2: ArrayHelper

В дополнение к богатым возможностям php по работе с массивами, Yii 2.0 предлагает ArrayHelper, который позволяет более эффективно обращаться с массивами.

Получение значений

Получение одного значения

Получение значений элементов массива, объекта или другой сложной структуры, с использованием стандартных методов php очень часто встречается. Всегда необходимо проверить существование нужного ключа в массиве с помощью isset и тогда получить значение или вернуть значение по-умолчанию:

class User
{
    public $name = 'Alex';
}

$array = [
    'foo' => [
        'bar' => new User(),
    ]
];

$value = isset($array['foo']['bar']->name) ? $array['foo']['bar']->name : null;

Yii2 предлагает очень удобный способ сделать тоже самое:

$value = ArrayHelper::getValue($array, 'foo.bar.name');

Первый параметр — массив/объект, из которого нужно получить значение. Второй параметр — способ получения данных, один из следующих вариантов:

  • Имя ключа массива или свойства объекта для получения значения.
  • Набор ключей или свойств, разделенных точками, как в примере выше.
  • Callback-функция, возвращающая значение.

Пример использования callback-функции:

$fullName = ArrayHelper::getValue($user, function ($user, $defaultValue) {
    return $user->firstName . ' ' . $user->lastName;
});

Третий аргумент необязательный, имеет значение null, если не указан. Пример использования:

$username = ArrayHelper::getValue($comment, 'user.username', 'Unknown');

В случае, если необходимо получить значение и сразу же удалить его из массива, нужно использовать метод remove:

$array = ['type' => 'A', 'options' => [1, 2]];
$type = ArrayHelper::remove($array, 'type');

После исполнения данного кода, $array будет содержать только [‘options’ => [1, 2]] и $type будет иметь значение A. Обратите внимание, что, в отличии от getValue, метод remove поддерживает только простые наименование ключей массива.

Проверка существования ключа

ArrayHelper::keyExists действует подобно array_key_exists, за исключением случаев, когда третий аргумент false.  В данном случае, проверка ключа регистронезависима:

$data1 = [
    'userName' => 'Alex',
];
$data2 = [
    'username' => 'Carsten',
];
if (!ArrayHelper::keyExists('username', $data1, false) || !ArrayHelper::keyExists('username', $data2, false)) {
    echo "Please provide username.";
}

Получение столбца

Часто бывает необходимость получить столбец из массива строк данных или объектов.

$data = [
    ['id' => '123', 'data' => 'abc'],
    ['id' => '345', 'data' => 'def'],
];
$ids = ArrayHelper::getColumn($array, 'id');

В результате $ids будет содержать [‘123’, ‘345’].
При необходимости дополнительных изменений или при сложном алгоритме получения данных, в качестве второго аргумента возможно передать анонимную функцию:

$result = ArrayHelper::getColumn($array, function ($element) {
    return $element['id'];
});

Индексация массива по ключу

Для индексации массива по ключу можно применять метод index. Массив должен быть многомерным или массивом объектов. Ключ индексации должен быть ключом вложенного массива, свойством объекта или анонимной функцией, которая возвращает значение ключа для элемента массива.

Если ключевое значение равно null, соответствующий элемент массива будет пропущен и не попадет в результат.

$array = [
    ['id' => '123', 'data' => 'abc'],
    ['id' => '345', 'data' => 'def'],
];
$result = ArrayHelper::index($array, 'id');
// the result is:
// [
//     '123' => ['id' => '123', 'data' => 'abc'],
//     '345' => ['id' => '345', 'data' => 'def'],
// ]

// using anonymous function
$result = ArrayHelper::index($array, function ($element) {
    return $element['id'];
});

Map array

Для маппирования многомерного массива (извлечения пар ключ — значение), можно использовать метод map($array, $from, $to, $group = null). Второй и третий аргументы указывают имена ключей или свойств, значения которых будут парами ключ => значение в результирующем массиве. Четвертый параметр не обязателен, он позволяет сгруппировать результаты по третьему ключу или свойству. Пример использования:

$array = [
    ['id' => '123', 'name' => 'aaa', 'class' => 'x'],
    ['id' => '124', 'name' => 'bbb', 'class' => 'x'],
    ['id' => '345', 'name' => 'ccc', 'class' => 'y'],
);

$result = ArrayHelper::map($array, 'id', 'name');
// the result is:
// [
//     '123' => 'aaa',
//     '124' => 'bbb',
//     '345' => 'ccc',
// ]

$result = ArrayHelper::map($array, 'id', 'name', 'class');
// the result is:
// [
//     'x' => [
//         '123' => 'aaa',
//         '124' => 'bbb',
//     ],
//     'y' => [
//         '345' => 'ccc',
//     ],
// ]

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

Метод multisort(&$array, $key, $direction = SORT_ASC, $sortFlag = SORT_REGULAR) позволяет сортировать массив объектов или многомерный массив по одному или нескольким ключам. Пример:

$data = [
    ['age' => 30, 'name' => 'Alexander'],
    ['age' => 30, 'name' => 'Brian'],
    ['age' => 19, 'name' => 'Barney'],
];
ArrayHelper::multisort($data, ['age', 'name'], [ArrayHelper::SORT_ASC, ArrayHelper::SORT_DESC]);
// После сортировки $data будет содержать:
[
    ['age' => 19, 'name' => 'Barney'],
    ['age' => 30, 'name' => 'Brian'],
    ['age' => 30, 'name' => 'Alexander'],
];

Второй аргумент указывает ключи для сортировки, он может принимать значения:

  • Строка — при сортировке по одному ключу;
  • Массив строк — при сортировке по нескольким ключам;
  • Анонимная функция — в более сложных случаях.
ArrayHelper::multisort($data, function($item) {
    return isset($item['age']) ? ['age', 'name'] : 'name';
});

Третий аргумент определяет направление сортировки. Он может принимать значения ArrayHelper::SORT_ASC или ArrayHelper::SORT_DESC, в случае сортировки по одному ключу. При сортировке по нескольким ключам, можно указать массив направлений.
Последний аргумент — необязательный, соответствует $sortFlag php функции sort() и передается в нее.

Определение типа массива

Бывает очень полезно определить, является ли массив индексированным или ассоциативным. Пример:

// ключи не определены
$indexed = ['Qiang', 'Paul'];
echo ArrayHelper::isIndexed($indexed);

// ключи определены строковыми значениями
$associative = ['framework' => 'Yii', 'version' => '2.0'];
echo ArrayHelper::isAssociative($associative);

html кодирование и декодирование значений

Для кодирования или декодирования специальных символов строковых элементов массива в html, можно использовать следующие методы:

$encoded = ArrayHelper::htmlEncode($data);
$decoded = ArrayHelper::htmlDecode($data);

По-умолчанию кодируются только значения. Для кодирования ключей нужно передать false вторым аргументом. Кодирование использует charset приложения, который может быть переопределен третьи аргументом.

Получение массива из объекта

Не редко бывает необходима конвертация объекта или массива объектов в массив. Например конвертация модели Active Record в массив для предоставления доступа через REST API. Пример использования:

$posts = Post::find()->limit(10)->all();
$data = ArrayHelper::toArray($post, [
    'app\models\Post' => [
        'id',
        'title',
        // the key name in array result => property name
        'createTime' => 'created_at',
        // the key name in array result => anonymous function
        'length' => function ($post) {
            return strlen($post->content);
        },
    ],
]);

Первый аргумент содержит объект для конвертации. В данном случае модель AR Post.

Второй аргумент описывает параметры конвертации. В данном случае это параметры для конвертации модели Post. Каждый параметр может быть:

  • Имя поля для включения в результат как есть;
  • Пара ключ-значение — желаемое значение ключа массива и имя свойства модели для получения значения;
  • Пара ключ-значение — желаемое значение ключа массива и анонимная функция, возвращающая значение.

Результатом конвертации будет:

[
    'id' => 123,
    'title' => 'test',
    'createTime' => '2013-01-01 12:00AM',
    'length' => 301,
]

Так же, реализацией yii\base\Arrayable, возможно реализовать конвертацию объекта в архив для определенного класса.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *