ArrayHelper
===========
В добавок к [богатому набору функций](http://php.net/manual/en/book.array.php) для работы с массивами, которые есть в самом PHP, Yii Array helper предоставляет свои статические функции, которые могут быть вам полезны.
<<<<<<< HEAD
<<<<<<< HEAD
### Получение одной переменной
=======
## Получение значений
>>>>>>> yiichina/master
=======
## Получение значений
>>>>>>> master
Извлечение значений из массива, объекта или структуры состоящей из них обоих с помощью стандартных средств PHP является довольно скучным занятием. Сперва вам нужно проверить есть ли соответствующий ключ, с помощью `isset`, и, если есть получить, если нет – подставить значение по-умолчанию.
```php
class User
{
public $name = 'Alex';
}
$array = [
'foo' => [
'bar' => new User(),
]
];
$value = isset($array['foo']['bar']->name) ? $array['foo']['bar']->name : null;
```
Yii предлагает очень удобный метод для таких случаев:
```php
$value = ArrayHelper::getValue($array, 'foo.bar.name');
```
Первый аргумент – массив или объект из которого мы извлекаем значение. Второй аргумент определяет как будут извлекаться данные и может выглядеть как один из таких вариантов:
- Имя ключа массива или свойства объекта, значение которого нужно вернуть
- Путь к нужному значению, разделенный точками, как в примере выше
- Callback-функция возвращающая значение
Callback-функция должна выглядеть примерно так:
```php
$fullName = ArrayHelper::getValue($user, function ($user, $defaultValue) {
return $user->firstName . ' ' . $user->lastName;
});
```
Третий, необязательный, аргумент определяет значение по-умолчанию. Если не установлен – равен null. Используется так:
```php
$username = ArrayHelper::getValue($comment, 'user.username', 'Unknown');
```
В случае если вы хотите получить значение и тут же удалить его из массива, вы можете использовать метод `remove`
```php
$array = ['type' => 'A', 'options' => [1, 2]];
$type = ArrayHelper::remove($array, 'type');
```
После выполнения этого кода переменная `$array` будет содержать `['options' => [1, 2]]`, а в переменной `$type` будет значение `А`. В отличие от метода `getValue`, метод `remove` поддерживает только простое имя ключа.
<<<<<<< HEAD
<<<<<<< HEAD
### Проверка наличия ключа
`ArrayHelper::keyExists` работает так же как и стандартный [array_key_exists](http://php.net/manual/en/function.array-key-exists.php). Разница лишь в том, что вы можете установить третий аргумент в `false`. Тогда проверка ключа будет проводиться без учета регистра
=======
## Проверка наличия ключей
`ArrayHelper::keyExists` работает так же как и стандартный [array_key_exists](http://php.net/manual/en/function.array-key-exists.php),
но также может проверять ключи без учёта регистра:
>>>>>>> yiichina/master
=======
## Проверка наличия ключей
`ArrayHelper::keyExists` работает так же как и стандартный [array_key_exists](http://php.net/manual/en/function.array-key-exists.php),
но также может проверять ключи без учёта регистра:
>>>>>>> master
```php
$data1 = [
'userName' => 'Alex',
];
$data2 = [
'username' => 'Carsten',
];
if (!ArrayHelper::keyExists('username', $data1, false) || !ArrayHelper::keyExists('username', $data2, false)) {
echo "Please provide username.";
}
```
<<<<<<< HEAD
<<<<<<< HEAD
### Извлечение колонки
Часто нужно извлечь колонку значений из многомерного массива или объекта..
=======
## Извлечение колонок
Часто нужно извлечь колонку значений из многомерного массива или объекта. Например, список ID.
>>>>>>> yiichina/master
=======
## Извлечение столбцов
Часто нужно извлечь столбец значений из многомерного массива или объекта. Например, список ID.
>>>>>>> master
```php
$data = [
['id' => '123', 'data' => 'abc'],
['id' => '345', 'data' => 'def'],
];
$ids = ArrayHelper::getColumn($array, 'id');
```
Результатом будет `['123', '345']`.
Если нужны какие-то дополнительные трансформации или способ получения значения специфический, вторым аргументом может быть анонимная функция:
```php
$result = ArrayHelper::getColumn($array, function ($element) {
return $element['id'];
});
```
<<<<<<< HEAD
<<<<<<< HEAD
Индексирование массива по определенному ключу
----------------------------
Чтобы проиндексировать массив в соответствии с определенным ключом, используется метод `index` . Входящий массив должен быть многомерным или массивом объектов. Ключом может быть имя ключа вложенного массива, имя свойства объекта или анонимная функция, которая будет возвращать значение ключа по переданному массиву.
=======
## Переиндексация массивов
=======
## Переиндексация массивов
>>>>>>> master
Чтобы проиндексировать массив в соответствии с определенным ключом, используется метод `index` . Входящий массив должен
быть многомерным или массивом объектов. Ключом может быть имя ключа вложенного массива, имя свойства объекта или
анонимная функция, которая будет возвращать значение ключа по переданному массиву.
<<<<<<< HEAD
>>>>>>> yiichina/master
=======
>>>>>>> master
Если значение ключа равно `null`, то соответствующий элемент массива будет опущен и не попадет в результат.
```php
$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'];
});
```
<<<<<<< HEAD
<<<<<<< HEAD
Map array
---------
Для получения map (пар ключ-значение) из многомерного массива или из массива объектов вы можете использовать метод `map`.
=======
## Получение пар ключ-значение
Для получения пар ключ-значение из многомерного массива или из массива объектов вы можете использовать метод `map`.
>>>>>>> yiichina/master
=======
## Получение пар ключ-значение
Для получения пар ключ-значение из многомерного массива или из массива объектов вы можете использовать метод `map`.
>>>>>>> master
Параметры `$from` и `$to` определяют имена ключей или свойств, которые будут использованы в map. Так же, третьим необязательным параметром вы можете задать правила группировки.
```php
$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',
// ],
// ]
```
<<<<<<< HEAD
<<<<<<< HEAD
Сортировка массива
----------
=======
## Многомерная сортировка
>>>>>>> yiichina/master
=======
## Многомерная сортировка
>>>>>>> master
Метод `multisort` помогает сортировать массивы объектов или вложенные массивы по одному или нескольким ключам. Например:
```php
$data = [
['age' => 30, 'name' => 'Alexander'],
['age' => 30, 'name' => 'Brian'],
['age' => 19, 'name' => 'Barney'],
];
ArrayHelper::multisort($data, ['age', 'name'], [SORT_ASC, SORT_DESC]);
```
После сортировки мы получим:
```php
[
['age' => 19, 'name' => 'Barney'],
['age' => 30, 'name' => 'Brian'],
['age' => 30, 'name' => 'Alexander'],
];
```
Второй аргумент, определяющий ключи для сортировки может быть строкой, если это один ключ, массивом, если используются несколько ключей или анонимной функцией, как в примере ниже:
```php
ArrayHelper::multisort($data, function($item) {
return isset($item['age']) ? ['age', 'name'] : 'name';
});
```
Третий аргумент определяет способ сортировки – от большего к меньшему или от меньшего к большему. В случае, если мы сортируем по одному ключу, передаем `SORT_ASC` или `SORT_DESC`. Если сортировка осуществляется по нескольким ключам, вы можете назначить направление сортировки для каждого из них с помощью массива.
Последний аргумент – это флаг, который используется в стандартной функции PHP `sort()`. Посмотреть его возможные значения можно [тут](http://php.net/manual/en/function.sort.php).
<<<<<<< HEAD
<<<<<<< HEAD
Определение типа массива
-----------------------------
=======
## Определение типа массива
>>>>>>> yiichina/master
=======
## Определение типа массива
>>>>>>> master
Удобный способ для определения, является массив индексным или ассоциативным. Вот пример:
```php
// no keys specified
$indexed = ['Qiang', 'Paul'];
echo ArrayHelper::isIndexed($indexed);
// all keys are strings
$associative = ['framework' => 'Yii', 'version' => '2.0'];
echo ArrayHelper::isAssociative($associative);
```
<<<<<<< HEAD
<<<<<<< HEAD
HTML-encoding и HTML-decoding значений
--------------------------------------
=======
## HTML-кодирование и HTML-декодирование значений
>>>>>>> yiichina/master
=======
## HTML-кодирование и HTML-декодирование значений
>>>>>>> master
Для того, чтобы закодировать или раскодировать специальные символы в массиве строк в HTML-сущности, вы можете пользоваться методами ниже:
```php
$encoded = ArrayHelper::htmlEncode($data);
$decoded = ArrayHelper::htmlDecode($data);
```
По умолчанию кодируются только значения. Если установить второй параметр в `false`, то ключи массива будут так же кодированы. Кодирование использует кодировку приложения, которая может быть изменена с помощью третьего аргумента.
## Слияние массивов
<<<<<<< HEAD
<<<<<<< HEAD
Слияние массивов
--------------
=======
## Слияние массивов
>>>>>>> yiichina/master
=======
>>>>>>> master
Слияние двух или больше массивов в один рекурсивно.
Если каждый массив имеет одинаковый ключ, последний будет перезаписывать предыдущий (в отличие от функции array_merge_recursive).
Рекурсивное слияние проводится когда все массивы имеют элемент одного и того же типа с одним и тем же ключом. Для элементов, ключом которого является значение типа integer, элементы из последнего будут добавлены к предыдущим массивам. Вы можете добавлять дополнительные массивы для слияния третьим, четвертым, пятым (и так далее) параметром.
```php
ArrayHelper::merge($a, $b);
```
<<<<<<< HEAD
<<<<<<< HEAD
Получение массива из объекта
-------------------------
=======
## Получение массива из объекта
>>>>>>> yiichina/master
=======
## Получение массива из объекта
>>>>>>> master
Часто нужно конвертировать объект в массив. Наиболее распространенный случай – конвертация модели Active Record в массив.
```php
$posts = Post::find()->limit(10)->all();
$data = ArrayHelper::toArray($posts, [
'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);
},
],
]);
```
Первый аргумент содержит данные, которые вы хотите конвертировать. В нашем случае это Active Record модель `Post`.
Второй аргумент служит для управления процессом конвертации и может быть трех видов:
- просто имя поля
- пара ключ-значение, где ключ определяет ключ в результирующем массиве, а значение – название поля в модели, откуда берется значение.
- пара ключ-значение, где в качестве значения передается callback-функция, которая возвращает значение.
Результат конвертации будет таким:
```php
[
'id' => 123,
'title' => 'test',
'createTime' => '2013-01-01 12:00AM',
'length' => 301,
]
```
Вы можете определить способ конвертации из объекта в массив по-умолчанию реализовав интерфейс
[[yii\base\Arrayable|Arrayable]] в этом классе
## Проверка на присутствие в массиве
Часто необходимо проверить, содержится ли элемент в массиве, или является ли массив подмножеством другого массива.
К сожалению, PHP функция [[in_array()]] не поддерживает подмножества объектов, реализующих интерфейс `\Traversable`.
Для таких случаев [[yii\base\ArrayHelper]] предоставляет [[yii\base\ArrayHelper::isIn()|isIn()]] и
[[yii\base\ArrayHelper::isSubset()|isSubset()]]. Методы принимают такие же параметры, что и [[in_array()]].
```php
// true
ArrayHelper::isIn('a', ['a']);
// true
ArrayHelper::isIn('a', new(ArrayObject['a']));
// true
ArrayHelper::isSubset(new(ArrayObject['a', 'c']), new(ArrayObject['a', 'b', 'c'])
```