Пока плодятся поспешные минорные релизы Kohana 3.0.6.x, давайте-как лучше рассмотрим полезнейший хэлпер Arr, предназначенный для работы с массивами. Вроде бы ничего сложного, массивы как массивы, а какие удобства обеспечивает один небольшой класс! Итак, к делу.
- Метод
is_assoc(array $array)
. Позволяет проверить, является ли массив ассоциативным или нет. Алгоритм достаточно интересный (впервые увидел двойной вызовarray_keys()
). Стоит отметить, что если в исходном массиве ключи числовые, то все равно вернется TRUE (единственное исключение — массив с индексами от нуля с шагом 1, т.е. типичный неассоциативный массив). - Метод
path($array, $path, $default = NULL)
. Просто жизненно важный метод для работы с многомерными массивами, он позволяет обратиться в вложенному элементу, используя точку в качестве разделителей уровня вложенности. Например, если есть элемент$array['test']['var']['value']
arr::path($array, 'test.var.value')
- Метод
range($step = 10, $max = 100)
вернет массив, заполненный элементами с шагом$step
, вплоть до максимального числа$max
. Не очень удобно, что нельзя указать начальный элемент (для данного метода он всегда будет совпадать с числом$step
). - Метод
get($array, $key, $default = NULL)
, думаю, самый известный в данном классе. Он ищет элемент в массиве, с поддержкой дефолтного значения. Отличается отarr::path()
тем, что ищет только в первом уровне вложенности. - Метод
extract($array, array $keys, $default = NULL)
. Метод, часто используемый для безопасной обработки данных глобальных массивов. Передавая массив$keys
, мы определяем ключи, которые надо извлекать из массива$array
. Все прочие ключи игнорируются. Если по какому-то ключу значение не найдено, подставляется$default
. Например,$user_data = arr::extract($_POST, array('username', 'password', 'remember'), NULL)
$_POST
. - Метод
binary_search($needle, $haystack, $sort = FALSE)
, в ветке 2.3.x использовавшийся для бинарного поиска, теперь просто вызываетarray_search()
, так что смысла в его использовании нет (оставлен для совместимости). - Метод
unshift(array & $array, $key, $val)
позволяет вставить в начало ассоциативного массива значение$val
по ключу$key
. - Метод
map($callback, $array)
рекурсивно применяет функцию$callback
ко всем элементам$array
, в том числе и подмассивам. В отличие от стандартногоarray_map()
,arr::map()
не работает с несколькими массивами (т.е.arr::map('trim', $array1, $array2, $array3)
- Метод
merge(array $a1, array $a2)
рекурсивно объединяет два массива. В отличие отarray_merge_recursive()
, она не принимает более 2х массивов. Кроме того, если массивы неассоциативные, то значения не будут дублироваться. Например,arr::merge(array('foo'), array('foo'))
array('foo')
array('foo', 'foo')
- Метод
overwrite($array1, $array2)
перезаписывает значения массива$array1
значениями из$array2
. При этом новые ключи в$array1
не добавляются. Таким образом, пример из пункта проarr::extract()
можно записать какarr::overwrite(array('username' => null, 'password' => null, 'remember' => null), $_POST);
- Метод
callback($str)
пытается разбить строковое представление вызова функции с параметрами на массив (функция, параметры). Например,arr::callback('foo::bar(1,2,$_POST)')
array(2) { [0]=> array(2) { [0]=> string(3) "foo" [1]=> string(3) "bar" } [1]=> array(3) { [0]=> string(1) "1" [1]=> string(1) "2" [2]=> string(6) "$_POST" } }
Если в строку заключать не в одиночные кавычки, а в двойные, то, что естественно, вместо строки
$_POST
подставится строковое представление этого глобального массива, т.е. строка ‘array‘.В версии 2.3.4 был похожий метод
callback_string()
, но он предусматривал использование квадратных скобок в строке, т.е. ‘foo::bar[1,2]‘. Вероятно это связано с использованием такого синтаксиса в Валидаторе, при объявлении правил. - Метод
flatten($array)
преобразовывает многомерный массив в одномерный. Значения просто переносятся в «корень» массива. При этом ключи сохранятся только для конечных элементов (не являющихся массивами). Пример:
$arr = array ( '1' => array ( '2' => 2, '3' => array ( 4, 6 => 6 ) ), '5' => 5 ); var_dump(arr::flatten($arr));
В результате получим массив:
array(4) { [2]=> int(2) [0]=> int(4) [6]=> int(6) [5]=> int(5) }
У элемента ’4′ ключ сгенерирован заново, а массив под ключом ’3′ исчез, оставив только свое содержимое. Тут стоит обратить внимание, что в целом ключи остались прежними. А что, если у двух элементов будет одно и то же значение ключа? Проверим:
$arr = array ( '1' => array ( '2' => 2, '3' => array ( 4, 5 => 6 ) ), '5' => 5 ); var_dump(arr::flatten($arr));
Здесь я для значения ’6′ поменял ключ. В результате получим:
array(3)
{
[2]=> int(2)
[0]=> int(4)
[5]=> int(5)
}
Один элемент пропал — шестерка была затерта пятеркой, т.к. ключи совпадали. Так что будьте осторожнее с этим методом.
По сравнению с 2.3.4, в хэлпере не хватает таких методов, как rotate()
, remove()
и to_object()
. Но их всегда можно перенести в третью ветку, ничего сложного в этом нет.
На этом наше короткое теоретическое знакомство с данным хэлпером закончено — приступайте к практике. Пользуйтесь этим классом, не изобретайте велосипед
спасибо за статью
А ещё жутко не хватает метода из 2.3.4, который мог по такому пути foo.bar.val установить значение.
Мимошёл ну так его же можно очень просто реализовать
Как я и писал в конце статьи — по сути все эти методы просто копируются и работают
Работая над очередным проектом расширил стандартный Arr следующим образом:
http://pastie.org/1012138
Позволю несколько замечаний:
1. Почему класс абстрактный?
2. Строка №29. Зачем проверка is_array(), если тип параметра указан явно (array & $array)?
3. Функция get_ref(). Какой смысл возвращать указатель на дефолтное значение? Может, тогда уж вставлять его в массив?
4. Функция set(). Стало привычным уже, что первым параметром идет массив. Почему тут он последний? Да и возвращать его зачем? Может тогда уж передавать по ссылке?
1. Потому что это часть библиотеки Mobitech, классы которой не должны иметь инстансов. В проекте добавляется extends класс вида:
class Arr extends Mobitech_Arr {};
2. Верно подмечено. ИМХО, array в параметрах функции был добавлен позже.
3. Например для того, чтобы на вход можно было задать ‘другую ветку’ того же массива и получить на нее ссылку вместо не найденой.
4. Обратите внимание, что в функции set() последний параметр имеет default значение ($haystack = array()) .. Это позволяет делать сокращенную запись вида: Arr::set($path, $value) и на выходе получить новый массив с одной парой $key=>$value. А возвращается он для того, чтобы можно было делать такие штуки:
$this->template->set( Arr::set(‘data’, $data) );
$this->template->set( Arr::set_multi(array(‘data1′ => $data1, ‘data2′ => $data2, ..)) );
2 Богдан и biakaveron, спасибо но догадаться что нужные методы можно вытащить из другого фреймворка не сложно. Речь не о том, отсутствие некоторых вещей в кохане 3, всё же некоторый регресс, ничем не оправданный.
Ч то такое int arr size?
Где нашли?