- Организация массива
- Операции с массивами
- Создание и модификация массива
- Перебор массивов
- Сортировка массива
- Объединение массивов
- Разделение массива на части
- Получение элементов массива
- Получить первый элемент массива
- Получить последний элемент массива
- Получить часть массива
- Извлечь первый элемент из массива
- Извлечь последний элемент из массива
- Извлечь часть элементов из массива
- Выбрать все значений массива
- Выбрать все ключи массива
- Получить случайное значение из массива
- Глобальные массивы
- Многомерные массивы
Организация массива
Как писалось выше, массив состоит из элементов, каждый из которых имеет ключ и значение. Например массив содержащий информацию о ценах в ресторанном меню может выглядеть так:
Ключ | Значение |
---|---|
breakfast | 700 |
dinner | 1500 |
supper | 1100 |
Массив может иметь только один элемент с заданным ключом, т.е. в приведённом выше массиве не может быть двух элементов с ключом
dinner
. При попытке «добавить» второй dinner
, мы просто перезапишем значение уже существующего элемента. В данном примере мы рассмотрели наиболее частый случай организации массива, а именно в виде ассоциативного. Ассоциативный массив удобнее использовать в коде, т.к. его ключи имеют осмысленные наименования (ассоциируются с какими-то частями приложения или данными которые обрабатывает скрипт). Но есть более простой пример массив, это числовые массивы. При их создании не нужно указывать ключ, он задаётся автоматически в виде целого числа, начиная с нуля.Ключ | Значение |
---|---|
0 | 700 |
1 | 1500 |
2 | 1100 |
Рассмотрим пример:
//Пример создания ассоциативного массива
$menuPrice = [
'breakfast' => 700,
'dinner' => 1500,
'supper' => 1100
];
//Пример создания «числового» массива
$prices = [700, 1500, 1100];
В первом случае элементы массива представляют из себя пару ключ-значение, где в качестве ключа используются строковые названия «блюд» (приёмов пищи на самом деле, но пусть будет блюд), а значение это цена блюда. Во втором же случае я указал только цены, при этом интерпретатор PHP автоматически проставит ключи элементам массива.
Операции с массивами
Один из случаев ключевой операции с массивами, а именно его создание мы рассмотрели выше. А как ещё можно создать массив? Самый простой случай, это создание пустого массива:
//Создаём пустой массив
$array = [];
Создание и модификация массива
Пустой массив может служить заготовкой под определённую коллекцию данных. Конечно его можно не определять заранее и создать прямо в цикле где он должен заполняться, но тогда это будет менее понятный код.
Вы так же можете заполнить массив на лету, например данными из базы данных:
//Заполняем массив данными из БД
$users = [];
//...некая выборка значения, например пользователей users
while($user = $db->query('SELECT * FROM users')->fetch(PDO::FETCH_ASSOC)){
$users[] = $user;
}
Перебор массивов
С другой стороны готовый массив можно перебрать и например вывести его элементы на экран:
//Перебор массива
$week = ['Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота', 'Воскресенье'];
//Выведем список дней недели
echo '<ul>';
foreach ($week as $key => $day) {
echo '<li>'. $day .'</li>';
}
echo '</ul>';
Вообще в php существует больше 70 функций для работы с массивами, однако в большинстве случаев вы будет использовать не больше двадцати. Приведу некоторые из них:
- in_array — проверяет присутствие элемента в массиве
- key_exists — проверяет присутствует ли в массиве указанный ключ или индекс
- array_search — осуществляет поиск заданного значения в массиве и возвращает ключ первого найденного значения
- array_merge — объединяет 2 и более массивов в один
- array_chunk — разбивает массив на части
Сортировка массива
Отдельным блоком может идти операции связанные с сортировкой массив. В PHP существует несколько встроенных функций для быстрой сортировки массивов, например по возрастанию/убыванию значения или в алфавитном порядке. Причём сортировка может идти как по ключам массива так и по значениям. Одной из интересных возможностей предоставляет функция usort()
, при помощи которой вы можете отсортировать элементы массива используя собственный алгоритм сравнения. Рассмотрим пример:
//Пользовательская функция сравнения элементов массива
function compare($a, $b)
{
if ($a == $b) {
return 0;
}
return ($a < $b) ? -1 : 1;
}
//Заданный массив с числами идущими не по порядку
$numbers = [3, 2, 5, 6, 1];
//Вызываем функцию usort() передав ей массив и имя нашей пользовательской функции сравнения
usort($numbers, 'compare');
В результате выполнения данного примера получим такой массив:
array(5) {
[0]=>int(1)
[1]=>int(2)
[2]=>int(3)
[3]=>int(5)
[4]=>int(6)
}
Как вы понимаете данный пример максимально упрощён. Но внутри вашей функции compare()
можно реализовать любой алгоритм сравнения элементов. Главное правильно возвращать значение, ноль — если элементы не отличаются и их не надо менять местами и 1 или -1 если нужно изменить порядок элементов.
Вы так же можете пробросить в тело функции compare()
внешнюю переменную используя анонимную функцию и ключевое слово use
:
//Пользовательская функция сравнения элементов массива
$params = ['min_value'=>0, 'max_value'=>3];
function compare($params){
return function ($a, $b) use ($params)
{
if ($a == $b) {
return 0;
}
if($a < $b && $a >= $params['min_value'] && $a <= $params['max_value']){
return -1;
} else {
return 1;
}
};
}
//Заданный массив с числами идущими не по порядку
$numbers = [3, 2, 5, 6, 1];
//Вызываем функцию usort() передав ей массив и имя нашей пользовательской функции сравнения
usort($numbers, compare($params));
Как видите теперь compare()
принимает параметры $params
и возвращает анонимную функцию в которой уже реализован ваш алгоритм сравнения в котором используются переданные параметры. Результат при таком алгоритме изменится:
array(5) {
[0]=>int(1)
[1]=>int(2)
[2]=>int(3)
[3]=>int(6)
[4]=>int(5)
}
Грубо говоря сортировка по возрастанию шла пока значение $a
попадало в диапазон от 0 до 3-х. Более подробно о сортировке массивов читайте в отдельной статье.
Объединение массивов
Для объединения двух и более массивов в php предусмотрена функцияarray_merge()
. Она создаёт новый массив последовательно присоединяя массивы.
//Фрукты
$fruits = [
'Яблоки',
'Апельсины',
'Грушки'
];
//Овощи
$vegetables = [
'Картофель',
'Огурцы',
'Помидоры'
];
//Объединяем массивы
$plants = array_merge($fruits, $vegetables);
echo '<pre>';
print_r($plants);
echo '</pre>';
Результат:
Array
(
[0] => Яблоки
[1] => Апельсины
[2] => Грушки
[3] => Картофель
[4] => Огурцы
[5] => Помидоры
)
Разделение массива на части
Чтобы разделить массив на части, используйте функциюarray_chunk()
принимающую 2 аргумента, сам массив и число указывающее на то, по сколько частей делить исходный массив. Функция создаст новый многомерный массив, разделённый на части.
//Фрукты
$fruits = [
'Яблоки',
'Апельсины',
'Грушки',
'Слива',
'Персик',
'Абрикос',
'Алыча',
'Вишня',
'Черешня',
];
$arr = array_chunk($fruits, 3); //Делим массив, оставляя в каждом подмассиве 3 элемента из исходного
echo '<pre>';
print_r($arr);
echo '</pre>';
Результат:
Array
(
[0] => Array
(
[0] => Яблоки
[1] => Апельсины
[2] => Грушки
)
[1] => Array
(
[0] => Слива
[1] => Персик
[2] => Абрикос
)
[2] => Array
(
[0] => Алыча
[1] => Вишня
[2] => Черешня
)
)
В исходном массиве 9 элементов, мы делим его на массивы по 3 элемента в каждом, получаем в итоге 3 массива. Если исходный массив не делится поровну, последний подмассив, будет содержать то, что осталось в исходном после разделения на предыдущие. Например если в данном примере в качестве второго аргумента передать array_chunk()
число 4 получим такой результат:
Array
(
[0] => Array
(
[0] => Яблоки
[1] => Апельсины
[2] => Грушки
[3] => Слива
)
[1] => Array
(
[0] => Персик
[1] => Абрикос
[2] => Алыча
[3] => Вишня
)
[2] => Array
(
[0] => Черешня
)
)
2 массива по 4 элемента и 1 с оставшимся одним элементом. Получение элементов массива
Помимо обычного перебора или обращения по индексу или ключу, в php предусмотрен набор функций для получения определённых элементов или частей массива.Получить первый элемент массива
Функцияcurrent()
получает первый элемент массива, точнее элемент на который в данный момент указывает внутренний указатель массива. По умолчанию первый элемент.
$arr = [
'Первый элемент',
'Второй элемент',
'Третий элемент',
'Четвёртый элемент',
'Пятый элемент',
'Шестой элемент',
'Седьмой элемент',
'Восьмой элемент',
'Девятый элемент',
'Десятый элемент',
];
//По умолчанию первый элемент
var_dump(current($arr));
Результат:
string(27) "Первый элемент"
Однако мы можем сдвинуть указатель функциями next()
, prev()
и получить другой результат.
$arr = [
'Первый элемент',
'Второй элемент',
'Третий элемент',
'Четвёртый элемент',
'Пятый элемент',
'Шестой элемент',
'Седьмой элемент',
'Восьмой элемент',
'Девятый элемент',
'Десятый элемент',
];
//Сдвинем внутренний указатель на 2 шага
next($arr);
next($arr);
var_dump(current($arr));
Результат
string(27) "Третий элемент"
Функция reset()
сбросит указатель опять на первый элемент.Получить последний элемент массива
Опять работаем с указателями, функцияend()
поставит указатель на последний элемент массива.
$arr = [
'Первый элемент',
'Второй элемент',
'Третий элемент',
'Четвёртый элемент',
'Пятый элемент',
'Шестой элемент',
'Седьмой элемент',
'Восьмой элемент',
'Девятый элемент',
'Десятый элемент',
];
var_dump(end($arr));
Результат:
string(29) "Десятый элемент"
Получить часть массива
В php предусмотрена возможность получить часть (срез) массива. Основано на внутенних индексах элементов массива, подобно работе со строками, мы передаём функцииarray_slice($arr, $offest, $length)
три аргумента, наш массив $arr
индекс $offest
элемента с которого нужно начать делать срез и $leng
th
- длину среза.
$arr = [
'Первый элемент',
'Второй элемент',
'Третий элемент',
'Четвёртый элемент',
'Пятый элемент',
'Шестой элемент',
'Седьмой элемент',
'Восьмой элемент',
'Девятый элемент',
'Десятый элемент',
];
$slice = array_slice($arr, 2, 5);
echo '<pre>';
print_r($slice);
echo '</pre>';
Результат
Array
(
[0] => Третий элемент
[1] => Четвёртый элемент
[2] => Пятый элемент
[3] => Шестой элемент
[4] => Седьмой элемент
)
Если $length
будет больше чем количество элементов оставшихся в массиве с индекса $offset
, мы просто получим массив до конца.Извлечь первый элемент из массива
Иногда при обработке массивов, нам нужно не просто получить его элемент, но при этом и удалить его в исходном массиве, чтобы он не участвовал в последующих операциях над массивом. Для этого предусмотрена функция array_shift() - извлекает и возвращает первый элемент массива.
$arr = [
'Первый элемент',
'Второй элемент',
'Третий элемент',
];
$firstItem = array_shift($arr);
echo $firstItem . '<br/>';
echo '<pre>';
print_r($arr);
echo '</pre>';
Результат
Первый элемент
Array
(
[0] => Второй элемент
[1] => Третий элемент
)
Извлечь последний элемент из массива
Есть аналог array_shift(), функция array_pop() - извлекает последний элемент из массива и возвращает его значение
$arr = [
'Первый элемент',
'Второй элемент',
'Третий элемент',
];
$firstItem = array_pop($arr);
echo $firstItem . '<br/>';
echo '<pre>';
print_r($arr);
echo '</pre>';
Результат:
Третий элемент
Array
(
[0] => Первый элемент
[1] => Второй элемент
)
Извлечь часть элементов из массива
Подобную операцию можно провернуть над частью массива, предварительно получив срез с помощьюarray_slice()
а затем воспользовавшись array_diff()
мы получим разницу между исходным массивом и срезом.$arr = [
'Первый элемент',
'Второй элемент',
'Третий элемент',
];
$slice = array_slice($arr, 0, 2); //Срез
$diff = array_diff($arr, $slice); //Разница между срезом и исходным массивом
echo '<pre>';
print_r($slice);
echo '</pre>';
echo '<pre>';
print_r($diff);
echo '</pre>';
Результат:
Array
(
[0] => Первый элемент
[1] => Второй элемент
)
Array
(
[2] => Третий элемент
)
Так иногда решают задачи не стандартной сетки в вёрстке, когда в первой строке выводится 2 элемента, во второй 3, начиная с 3-й строки по 4. Можно предварительно попилить массив с товарами на такие отрезки и удобно в цикле выводить их на странице.Выбрать все значений массива
Для получения всех значений массива (игнорируя ключи) используется функция array_values(), она создаёт новый массив со стандартными числовыми ключами (0, 1, 2 ...) оставляя в новом массиве только значения.
$arr = [
'key1' => 'value1',
'key2' => 'value2',
'key3' => 'value3',
];
$values = array_values($arr);
echo '<pre>';
print_r($values);
echo '</pre>';
Результат:
Array
(
[0] => value1
[1] => value2
[2] => value3
)
Выбрать все ключи массива
Аналогично значениям, вы можете получить только ключи массива.
$arr = [
'key1' => 'value1',
'key2' => 'value2',
'key3' => 'value3',
];
$values = array_keys($arr);
echo '<pre>';
print_r($values);
echo '</pre>';
Результат:
Array
(
[0] => key1
[1] => key2
[2] => key3
)
Получить случайное значение из массива
Если вы пишите программу лотереи а призы харните в массиве, воспользуйтесь функцией array_rand() чтобы отдать игроку случайны приз, она получает и возвращает случайны индекс массива.
$arr = [
'пусто',
'пусто',
'пусто',
'Автомоболь!',
'пусто',
'пусто',
];
var_dump($arr[array_rand($arr)]);
Результат:
string(10) "пусто"
Эх, повезёт в следующий раз.Глобальные массивы
В PHP начиная с версии 4 ввели такой сущность как «суперглобальные массивы». Это особые переменные доступные в любой части приложения и содержат информацию, например о состоянии сервера (массив $_SERVER) сессии, куках или переданных от пользователя запросах, одним словом о состоянии среды выполнения приложения. На данный момент в PHP доступно девять суперглобальных массивов:
Наименование | Описание массива |
$GLOBALS | Этот массив содержим все переменные объявленные в скрипте, при этом имена переменных являются ключами этого массива. |
$_SERVER | Данный массив содержит всю информацию о сервере, а так же настройки среды в которой выполняется скрипт |
$_GET | Массив переменных переданных PHP скрипту по средствам GET запроса (через адресную строку браузера или другими методами, например curl()) |
$_POST | Так же как и GET содержит переданные скрипту переменные, только уже методом POST |
$_COOKIE | Содержим coockies-ы пользователя |
$_REQUEST | Объединяет в себе массивы $GET, $POST и $COOKIE. Не рекомендуется использовать, не безопасно, хотя и удобно. |
$_FILES | Содержим список файлов загружаемых на сервер через веб-формы (имя, временный путь, размеры и т.д.) |
$_ENV | Содержит переменные окружения в котором запущен PHP скрипт |
$_SESSION | В данном массиве содержаться все переменные сессии текущего пользователя |
Чаще всего, вы будете сталкиваться с массивами $_GET и $_POST т.к. с их помощью в скрипты на сервере передаются данные от клиентской части (через веб-формы).
Многомерные массивы
Как вы уже знаете, элементы массива могут содержать в качестве значения данные любого типа, строки, числа, логические, в том числе и другие массивы. Массив состоящий из других массивов называется многомерным или вложенным массивом. На практике используется 2-3 уровня вложенности для хранения каких-либо связанных структурных данных (например данных о покупателях магазина или каталоге товаров), обработка массивов большей вложенности усложняется и используется не часто.
Давайте разберёмся как создавать и взаимодействовать с многомерными массивами.
Создание многомерных массивов
В первую очередь создадим простой двумерный массив сотрудников организации:
//Многомерный массив сотрудников
$multilevelArray1 = [
[
'username'=>'Александр',
'age' => 32,
'position' => 'Программист'
],
[
'username'=>'Анастасия',
'age' => 33,
'position' => 'Логопед'
],
[
'username'=>'Елена',
'age' => 29,
'position' => 'Бухгалтер'
]
];
Массив $multilavelArray
содержим в себе три других массива описывающих некоторые параметры сотрудников, а именно имя, возраст и должность. Эти данные могли бы быть получены из БД или сложной веб-формы. Обратите внимание что в «родительском» массиве мы не указывали символьных ключей, поэтому массивам внутри были просто присвоены числовые индексы 0, 1, 2. Давайте теперь распределим наших сотрудников по отделам и добавим ещё одного сотрудника.
//Многомерный массив сотрудников
$multilevelArray2 = [
'DEPARTMENT_IT' => [
[
'username'=>'Александр',
'age' => 32,
'position' => 'Программист'
]
],
'DEPARTMENT_EDUCATION'=> [
[
'username'=>'Анастасия',
'age' => 33,
'position' => 'Логопед'
]
],
'DEPARTMENT_FINANCE' => [
[
'username'=>'Екатерина',
'age' => 39,
'position' => 'Главный бугалтер'
],
[
'username'=>'Елена',
'age' => 29,
'position' => 'Бухгалтер'
]
]
];
Теперь мы имеем многомерный массив в котором на «первом уровне» хранятся отделы компании, а уже внутри отделов сотрудники. При этом отдел имеет символьный ключ, например DEPARTMENT_IT
— отдел IT. Немного усложним наш пример и добавим информацию о наименовании отделов и времени работы, а сотрудников отдела поместим на уровень ниже:
$multilevelArray3 = [
'DEPARTMENT_IT' => [
'TITLE' => 'It отдел',
'WORK_TIME' => 'с 09:00 до 23:00',
'STAFF' => [
[
'username'=>'Александр',
'age' => 32,
'position' => 'Программист'
]
]
],
'DEPARTMENT_EDUCATION'=> [
'TITLE' => 'Отдел образования и развития',
'WORK_TIME' => 'с 08:00 до 17:00',
'STAFF' => [
[
'username'=>'Анастасия',
'age' => 33,
'position' => 'Логопед'
]
]
],
'DEPARTMENT_FINANCE' => [
'TITLE' => 'Отдел бухгалтерии',
'WORK_TIME' => 'с 09:00 до 18:00',
'STAFF' =>[
[
'username'=>'Екатерина',
'age' => 39,
'position' => 'Главный бухгалтер'
],
[
'username'=>'Елена',
'age' => 29,
'position' => 'Бухгалтер'
]
]
]
];
Как видите используя многомерные массивы можно строить довольно сложные структуры данных с которыми в последствии предстоит работать нашему веб-приложению.
Доступ к элементам многомерного массива
Рассмотрим как получить доступ к элементам многомерного массива. В качестве примера возьмём выше описанные массивы сотрудников компании. Но перед этим предлагаю набросать небольшую функцию, которая позволит удобно просматривать содержимое переменных в вашем коде. Я часто использую её в работе:
/**
* Обёртка для print_r() и var_dump()
* @param $val - значение
* @param string $name - заголовок
* @param bool $mode - использовать var_dump() или print_r()
* @param bool $die - использовать die() после вывода
*/
function print_p($val, $name = 'Содержимое переменной', $mode = false, $die = false){
echo '<pre>'.(!empty($name) ? $name.': ' : ''); if($mode) { var_dump($val); } else { print_r($val); } echo '</pre>';
if($die) die;
}
Эта функция простая обёртка для просмотра содержимого переменной при помощи print_r()
или var_dump()
тегов <pre>...</pre>
. Берите на вооружение.
И так, давайте узнаем имена и возраст всех сотрудников из первого двумерного массива:
echo '<h3>Сотрудники компании</h3>';
foreach ($multilevelArray1 as $key => $item) {
echo '<b>Имя:</b> ' . $item['username'] . ' <b>должность:</b> ' . $item['position'] . '<br/>';
}
В результате выполнения этого кода, получим такой список в html:Представьте что мы не знаем что содержится в переменной
$multilevelArray3
, но нас просят как-то представить структуру компании на странице «О компании». Тут нам пригодится функция print_p()
описанная выше. Вызовем следующий код:
//Просмотр переменной $multilevelArray3
print_p($multilevelArray3, 'Структура компании', true);
В результате, на экране мы увидим такое сообщение:Мы видим что в
$multilevelArray3
хранится многоуровневый массив, на первом уровне которого находятся разделы компании с описанием, а внутри разделов по ключу STAFF доступен массив сотрудников этого отдела. Зная это мы можем написать следующий код, чтобы представить структуру компании:
echo '<h2>Компания ООО "Рога-и-Копыта"</h2>';
foreach ($multilevelArray3 as $departmentKey => $department) { ?>
<div class="department">
<h3><?=$department['TITLE']?></h3>
<i>Режим работы: <?=$department['WORK_TIME']?></i>
<? if(count($department['STAFF']) > 0) { //проверяем есть ли сотрудники в отделе ?>
<div class="staff">
<h5>В отделе работают:</h5>
<? foreach ($department['STAFF'] as $key => $item) { ?>
<div class="item">
<ul>
<li><b>Имя:</b> <?=$item['username'];?></li>
<li><b>Полных лет:</b> <?=$item['age'];?></li>
<li><b>Должность:</b> <?=$item['position'];?></li>
</ul>
</div><br/>
<? } ?>
</div>
<? } ?>
</div>
<hr>
<? } ?>
Получим такую страницу:Таким образом можно вывести например страницу контактов сайта, на которой должны быть «координаты» должностных лиц отвечающих за то или иное направление деятельности компании. Оформление сами понимаете зависит от вашей фантазии и дизайна сайта.
Обработка многомерного массива
Один из примеров обработки массива был представлен выше, когда мы просто вывели на экран содержимое многомерного массива в удобном для пользователя виде. Однако это далеко не всё что можно делать с массивами. Например мы можешь осуществить некий поиск по элементам узнать сколько сотрудников старше 30 лет работает в нашей компании:
//Количество искомых сотрудников
$counter = 0;
//Обработка каждого элемента массива
array_walk_recursive( $multilevelArray3, function ($value, $key) use (&$counter) {
if($key == 'age'){
if($value > 30){
$counter++;
}
}
}, $counter);
echo 'Количество сотрудников старше 30 лет: ' . $counter;
Здесь мы применили функцию array_walk_recursive() которая обходит каждый элемент массива вне зависимости от его вложенности и применяет к элементу пользовательскую функцию. В данном случае лямбда функция проверяет что текущий элемент это возраст и что его значение больше 30 и наращивает определённый во вне счётчик. Чтобы получить доступ в область видимости где применён счётчик используется конструкция use
и ссылка на переменную &$counter
. В результате вы увидите сообщение: Количество сотрудников старше 30 лет: 3.
Существует множество примеров обработки массивов в PHP, но они выходят за рамки данной статьи.