Массивы в PHP (как и в других языках) представляют собой коллекцию связанных вместе значений. Например в виде массива можно представить меню в ресторане (название блюда — цена) или количество проживающих в городах страны жителей (город страны — количество жителей). Как пояснялось в этой статье, переменная представляет из себя именнованный контейнер в памяти, содержащий определённо значение. В этом смысле массив, это контейнер содержащий множество значений.

Организация массива

Как писалось выше, массив состоит из элементов, каждый из которых имеет ключ и значение. Например массив содержащий информацию о ценах в ресторанном меню может выглядеть так:

Ключ Значение
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 элемента с которого нужно начать делать срез и $length - длину среза.


$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, но они выходят за рамки данной статьи. 



Полезная статья?
(Голосов: 3, Рейтинг: 3.25)
Вам также могут понравиться
Обновление остатков товара на складе в 1С Битрикс

Обновление остатков товара на складе в 1С Битрикс

Как правильно обновлять остатки товара на сайта под управлением CMS 1С Битрикс.

Английский для программистов

Английский для программистов

Почему IT-специалисту необходимо освоить английский язык? Разбираем в статье.

Как подключить CSS и JS файлы к шаблону 1С Битрикс

Как подключить CSS и JS файлы к шаблону 1С Битрикс

Как правильно подключать стили и скрипты к шаблону 1С Битрикс.


Комментарии
Защита от автоматических сообщений
CAPTCHA
Введите слово на картинке