Предыдущие части: Переменные, строки и среда исполнения, Введение в PHP
Как можно заметить, я не описываю язык от и до. В этом нет смысла, так как для любого языка есть документация, которую нужно просто прочитать.
Я делаю акценты на некоторых особенностях, и на том, что нам понадобится в дальнейшем.
А понадобятся нам, конечно же, коллекции. Что это такое, и для чего используется, я подробно описывал в отдельном цикле.
Какие типы коллекций есть в PHP?
Отвечать на этот вопрос легко и приятно: в PHP есть ровно один тип коллекций, и это ассоциативный массив.
Давайте вспомним, что такое массив. Это область памяти, последовательно заполненная элементами. У нас есть начало массива в виде адреса памяти. Назовём этот адрес "a". Чтобы получить первый элемент массива, нужно прибавить к адресу смещение 0:
a[0]
Чтобы получить второй элемент, нужно прибавить к адресу смещение 1:
a[1]
И так далее.
Посмотрим, как инициализировать массивы в PHP:
$a = [];
Мы создали пустой массив с именем $a.
$a = [1, 2 , 3];
Мы создали массив с именем $a, который состоит из трёх элементов: 1, 2, 3. Эти элементы находятся по соответствующим смещениям от начала массива:
$a[0] = 1
$a[1] = 2
$a[2] = 3
Но трюк здесь в том, что массив – ассоциативный. Это значит, что в нём нет линейных смещений, а есть лишь пары "ключ–значение".
То, что выглядит как смещение, на самом деле является ключом. В данном случае значение "1" хранится с ключом "0", значение "2" с ключом "1" и значение "3" с ключом "2".
Чтобы более наглядно это показать, можно целочисленные ключи заменить на строковые:
$a['0'] = 1
$a['1'] = 2
$a['2'] = 3
PHP не делает разницы между ключом, например, 0 (т.е. целочисленным) и '0' (т.е. строковым). На этом погорели многие программисты.
Также можно использовать любые другие ключи:
$a['one'] = 1
$a['two'] = 2
$a['three'] = 3
Чтобы инициализировать массив с произвольными ключами, нужно написать так:
$a = ['one' => 1, 'two' => 2, 'three' => 3];
Также можно написать, скажем, так:
$a = [0 => 1, 2 => 2, 3 => 3];
Здесь мы начали с ключа 0, затем пропустили ключ 1 и поставили следующим ключ 2. То есть данный массив будет выглядеть так:
$a[0] = 1
$a[2] = 2
$a[3] = 3
В нём не будет элемента с ключом 1.
В общем, нужно помнить две вещи:
- Ключи типа 0 и '0' не различаются
- Это всегда ассоциативные массивы с набором пар "ключ–значение", всё остальное (смещения, номера) лишь иллюзия.
Работа с ассоциативными массивами
Самый простой вариант массива – когда вы его создали с помощью инициализации:
$a = [1, 2, 3, 4, 5];
В этом случае каждый элемент массива автоматически получает последовательное смещение-ключ, начиная с 0. И вы можете работать с таким массивом, например, в цикле:
for ($i = 0; $i < 5; $i++) $a[$i] *= 2;
Вы также можете создать массив динамически, добавляя элементы к изначально пустому массиву:
$a = [];
for ($i = 0; $i < 5; $i++) $a[] = $i;
Конструкция $a[] добавляет в конец массива новый элемент и назначает ему ключ, следующий по порядку.
Также можно записать:
$a = [];
for ($i = 0; $i < 5; $i++) $a[$i] = $i;
Здесь вместо $a[] мы пишем $a[$i]. Это тоже будет создавать новые элементы в массиве с ключом $i. Так как $i меняется в цикле последовательно от 0 до 4, то результат будет тот же, что и выше.
В общем, новый элемент в массиве создаётся в двух случаях:
$a[] = 10;
– создать новый элемент в конце массива, дать ему ключ-смещение автоматически;
$a[$b] = 10;
– создать новый элемент массива с ключом $b. Если такой ключ уже существует в массиве, то новый элемент не создаётся, а его значение просто перезаписывается.
Итераторы
Если массив, в котором ключи являются последовательными числами 0, 1, 2 и т.д., мы можем обойти с помощью цикла, то как быть с массивом, где ключи заданы произвольно? Например:
$a = ['one' => 1, 'two' => 2, 'three' => 3];
Для этого есть конструкция foreach:
foreach($a as $value) echo "$value\n";
Буквально её можно перевести так: "для каждого элемента из $a, который мы назовём $value..."
Переменная $value внутри цикла foreach будет последовательно принимать значения из массива $a, пока они не закончатся.
Второй вариант foreach это:
foreach($a as $key => $value) echo "$key = $value\n";
Это буквально переводится так: "для каждой пары ключ–значение из $a, которую мы назовём $key => $value..."
Отличие здесь в том, что кроме значения элемента массива ($value) мы также получаем его ключ ($key).
Наконец, есть ещё один вариант обхода. Можно получить массив ключей массива:
$a = ['one' => 1, 'two' => 2, 'three' => 3];
$a_keys = array_keys($a);
В результате массив $a_keys будет содержать элементы: 'one', 'two', three'. Этот массив мы можем обойти уже обычным циклом, достать из него ключи, и использовать эти ключи, чтобы уже достать значения из массива $a:
for ($i = 0; $i < 3; $i++) echo $a[$a_keys[$i]] . "\n";
Также можно получить значения массива:
$a_values = array_values($a);
Мы получим массив $a_values, в котором содержатся те же самые значения, что и в массиве $a, но ключи у этих значений будут пересозданы заново в виде смещений 0, 1, 2..., то есть их можно будет обойти простым циклом.
Поиск в массиве
Чтобы найти элемент в массиве, мы можем воспользоваться функцией in_array():
if (in_array('aaa', $a)) echo "OK\n";
В данном примере, если массив $a содержит элемент со значением 'aaa', то результат будет "истина".
Можно также искать не значение элемента, а его ключ:
if (array_key_exists('one', $a)) echo $a['one'];
В данном примере мы ищем ключ 'one', и если он существует, то печатаем значение элемента с этим ключом.
Добавление и удаление элементов
Добавление элементов мы уже рассмотрели (и дополнительно рассмотрим ниже), а вот чтобы удалить элемент, нужно написать так:
unset($a['one']);
В данном примере мы удалили из массива $a элемент с ключом 'one'. При этом неважно, был там такой элемент или нет. Если он был, то он удалится. Если его не было, значит, ничего и не произойдёт.
Мы также можем удалять последний элемент массива с помощью array_pop():
array_pop($a);
В данном примере мы удалили из массива $a последний элемент. Этот последний элемент можно выкинуть, а можно присвоить чему-нибудь, если он нам ещё нужен:
$last = array_pop($a);
Аналогичным образом в конец массива можно добавлять элементы:
array_push($a, 10);
В данном примере мы добавили в конец массива $a элемент со значением 10. Эта конструкция идентична рассмотренной выше:
$a[] = 10;
Разница в том, что в array_push() мы можем добавить сразу несколько значений:
array_push($a, 'one', 'two', 'three');
Как нетрудно заметить, функции array_push() и array_pop() имитируют работу стека.
Длина массива
Для обхода массива с последовательными смещениями и других задач нам нужно знать его длину. Её можно получить с помощью функции count():
$a = [1, 2, 3];
$c = count($a);
Переменная $c будет равна 3.
Заключение
Ассоциативные массивы в PHP – основная структура данных, которая используется повсеместно. Поэтому необходимо освоить все методы работы с ними и помнить о том, чем они являются на самом деле.
Дополнительно в документации PHP описаны функции работы с массивами, которые позволяют строить объединение и пересечение массивов и многое другое.