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']) ```