- Подробности
-
Категория: PHP. Синтаксис
Дмитрий Лебедев
2001-01-13
То полезное в работе с массивами, чего многие не знают.
Для тех, кому интересно "глубинное" описание принципов работы массиовов в php, могут прочесть вот это. А я поговорю более приземленно.
Начнем с того, что "array" — тип данных, такой же, как integer или string. Если переменная $array — массив, то gettype($array) выдаст "array" (имя переменной взято "от фонаря", и к типу данных оно отношения не имеет), а is_array($array) выдаст true.
Теперь про индексы массива. Кстати, про слово "индекс". Год назад я задался вопросом, что же оно значит, а то "index.htm" было первым и чуть ли не единственным, что приходило в голову. Но я вспомнил! На конвертах бумажной почты была такая надпись "индекс почтового отделения" с трафаретом под цифры. Значит, индексы в массиве — указатели на его элементы :).
PHP поддерживает как скалярные (0, 1, 2…), так и ассоциативные ("a", "b", "c") индексы массивов. Ассоциативными массивами пользуются, например, в функциях работы с MySQL:
$row = mysql_fetch_array($result);
print ($row["field1"]. $row["field2"]. $row["field3"]);
Нет надобности объяснять, чем удобны ассоциативные массивы.
Теперь о создании массивов. Первое средство — функция array:
$array = array($val1, $val2, $val3);
$array2 = array($key1 => $val1, $key2 => $val2, $key3 => $val3);
В первом случае получится скалярный массив, во втором — ассоциативный.
Можно создать массив, попросту указав индекс и значение.
$array[$key] = $val;
Переменная $array, если она не существовала до этого, станет массивом, а в ячейку с индексом $key (не обязательно 0) помещается значение $val. Но самое красивое в php — отсутствие необходимости указывать индекс ячейки!
$new_array[] = "0"; // то же самое, что $new_array[0] = "0"
$new_array[] = "1"; // то же самое, что $new_array[1] = "1"
М-м… что-то я уже скатился до руководства по PHP! Это все там написано :). Кстати, мы часто делаем вывод переменной в тексте так:
print ("test $variable text");
Если попытаться вывести так же элемент массива, ничего не получится. Загляните в мануал, там приведены наглядные примеры на эту тему.
Функции, которые часто приходится использовать для работы с массивами — это sizeof (размер массива) и list & each (выбирают из каждого массива имя элемента и его значение).
Чтобы обработать все элементы скалярного массива, в котором (ВНИМАНИЕ!) индексы элементов представяют собой сплошной числовой ряд (от 0 до $n), достаточно использовать sizeof и цикл:
for ($i=0;$i<sizeof($array);$i++) {
…
};
Если элементы начинаются не с 0, а с известного $m, тогда можно действовать так:
for ($i=$m;$i<sizeof($array)+$m;$i++) {
…
};
Если массив ассоциативный (возможно, смешанный) или мы не знаем, есть ли в ряду индексов пустые места или нет, то пользуемся функциями list и each:
while (list($key, $val) = each($array)) {
Если надо вывести значения элементов в документ, то делаем
print ("…$val…");
Если обработать массив, обращаемся к его элементам:
$array[$key] = somefunction($val);
Почему я специально отметил возможность разрывов в скалярных индексах? Те, кто работал с массивами, например, в Паскале, знают — там массивы объявляются "от сих до сих, проверю, пасть порву". В отличие от Паскаля, в php массивы ничем не ограничены, мы вольны создавать массивы хоть с сотого элемента, предыдущих девяносто девяти просто не будет существовать (соответственно, sizeof такого массива будет 1). В любой момент можно создать новый элемент или удалить существующий (ну, если его не будет, программа ругаться не станет). Поэтому если при отладке программы вы не уверены, что в массиве лежит, сделайте следующее:
while (list($k, $v)=each($array))
print ("$k -- $v<br>");
Среди прочих функций, работающих с массивами, хочется отметить функции array_diff (сравнение массивов), array_rand (получение случайных элементов массива), array_unique (удаление повторов элементов) и in_array (проверка, есть ли заданное значение в массиве).
Что такое array pointer
Как вы видели, функции each и list работают без указания индекса. Естественно, что программа знает, с каким элементом она работает. Указатель, где в массиве программа "находится" в данный момент называется array pointer. Он ни в какой переменной не хранится, никак его получить нельзя (можно получить индекс элемента, на котором стоит поинтер). Но при необходимости поинтер можно двигать на начало, в конец массива, на следующий, предыдущий элемент. Впрочем, используются эти функции редко. Но на всякий случай после обращений к элементам массива и пред работой с функциями, использующими поинтер, выполняйте команду reset($array), чтобы он встал в начало массива.
Многомерность массивов
одномерный массивОпять же, здесь интерпретируемая программа куда более гибка, чем компилируемые. Как мы уже знаем, array — это такой тип данных. Как мы тоже знаем, элемент массива может классический двухмерный массив иметь любой тип данных. Значит, любой элемент массива может иметь тип данных array и быть массивом сам по себе — скалярным или ассоциативным (тогда, как соседи могут быть числами, текстом, чем угодно). В этом вложенном массиве можно создать сколько угодно элементов, и они тоже могут быть массивами. Таким образом многомерность массивов в php реализована не как многомерность, а как древовидная структура. Если вложенные в основной (корневой) массив массивы имеют одинаковый размер, получается "классический" двухмерный массив.
Это была теория многомерности. Теперь практика.
$array[$key] — имеет тип данных массив с элементом типа array"массив". И к этой переменной применимы все описанные функции. Даже чтобы превратить эту переменную в массив, можно использовать функцию array:
$array[$key] = array($val1, $val2, $val3);
Чтобы создать "классический" двухмерный массив, надо использовать вложенные функции array (за примеров — в руководстве по php).
print (sizeof($array[$key]);
Выдаст размер именно массива $array[$key], а не вложенных в двухмерный массив в php него массивов или $array. То же самое и с list & each. Отсутствие индекса при создании новых элементов так же применимо:
$array[$key][] = $val1;
$array[$key][] = $val2;
$array[$key][] = $val3;
В общем, все как с обычным массивом.