Работа с массивами практически всегда подразумевает итерацию по его элементам. Самый простой способ выполнить её — циклы.
Обход
<?php
$userNames = ['petya', 'vasya', 'evgeny'];
for ($i = 0; $i < count($userNames); $i++) {
print_r("{$userNames[$i]}\n");
}
// => petya
// => vasya
// => evgeny
https://repl.it/@hexlet/php-arrays-traversal-for-print
В данном коде создаётся массив из трёх элементов — имён. Далее в цикле происходит обход массива и вывод на экран всех имён так, что каждое имя оказывается на новой строке.
Рассмотрим этот этап подробнее. При обходе массива циклом for
, как правило, счётчик играет роль индекса в массиве. Он инициализируется нулём и увеличивается до count($userNames) - 1
, что соответствует индексу последнего элемента.
Интересно производится печать на экран. Элемент массива может участвовать в строковой интерполяции, а значит, мы можем сразу печатать и имя и перевод строки, используя такую конструкцию "{$userNames[$i]}\n"
.
А что, если нам нужно вывести значения в обратном порядке? Для этого есть два способа. Один — идти в прямом порядке, то есть от нулевого индекса до последнего, и каждый раз вычислять нужный индекс по такой формуле размер массива - 1 - текущее значение счётчика
.
Но есть и другой способ. Можно просто идти от верхней границы к нижней. В такой ситуации код меняется на следующий:
<?php
$userNames = ['petya', 'vasya', 'evgeny'];
for ($i = count($userNames) - 1; $i >= 0; $i--) {
print_r("{$userNames[$i]}\n");
}
При таком обходе проверка остановки должна быть именно на >=
, иначе пропустится элемент с индексом 0
.
Изменение
Сам цикл при изменении остаётся тем же самым, меняется только его тело. Предположим, что перед нами стоит задача нормализации списка электронных адресов. Допустим, в нормализацию адресов входит приведение их к нижнему регистру. Тогда код будет выглядеть так:
<?php
$emails = ['VASYA@gmAil.com', 'iGoR@yandex.RU', 'netiD@hot.CoM'];
print_r($emails);
// => Array
// => (
// => [0] => VASYA@gmAil.com
// => [1] => iGoR@yandex.RU
// => [2] => netiD@hot.CoM
// => )
for ($i = 0; $i < count($emails); $i++) {
# strtolower - стандартная функция php
$emails[$i] = strtolower($emails[$i]);
}
print_r($emails);
// => Array
// => (
// => [0] => vasya@gmail.com
// => [1] => igor@yandex.ru
// => [2] => netid@hot.com
// => )
https://repl.it/@hexlet/php-arrays-traversal-for-update
Ключевая строчка: $emails[$i] = strtolower($emails[$i]);
. В ней происходит перезапись элемента под индексом $i
. Иногда полезно создать промежуточную переменную для упрощения анализа кода:
<?php
$email = $emails[$i];
$emails[$i] = strtolower($email);
Инициализация цикла
При инициализации цикла for
в круглых скобках располагаются три блока выражений, разделяемые символом ;
.
Содержимое первого блока инициализации выполняется перед началом цикла и только один раз.
Второй блок определяет условие выполнения цикла и содержит выражение, которое вычисляется перед каждой очередной итерацией. Работа цикла продолжается, если это выражение возвращает true
. Если же проверка оказывается ложной, цикл заканчивает свою работу.
В третьем блоке содержатся выражения, которые обрабатываются в конце итерации цикла. Обычно здесь происходит необходимое преобразование счётчика, например, инкремент.
<?php
$colors = ['red', 'black', 'white', 'green'];
for ($i = 0; $i < count($colors); $i++) {
print_r("{$colors[$i]}\n");
}
В процессе работы цикла выражение, которое содержится в блоке условий вычисляется заново. Это значит, что в нашем примере длина массива count($colors)
будет вычисляться вновь и вновь при каждом проходе цикла. Так как сам массив остаётся неизменным, то повторное вычисление размера оказывается избыточным. Повторения операции можно избежать, если определить переменную за пределами цикла и присвоить ей необходимое значение.
<?php
$colors = ['red', 'black', 'white', 'green'];
$length = count($colors);
for ($i = 0; $i < $length; $i++) {
print_r("{$colors[$i]}\n");
}
Но существует более оптимальное решение: описать несколько выражений в блоке инициализации цикла for
и разделить их запятыми. Это позволяет избегать лишних вычислений, в случае с нашим примером, единожды определив значение length
. А также мы сразу видим переменные, которые используются только внутри цикла.
<?php
$colors = ['red', 'black', 'white', 'green'];
for ($i = 0, $length = count($colors); $i < $length; print($i), $i++) {
print_r("{$colors[$i]}\n");
}
// => red
// => 0black
// => 1white
// => 2green
// => 3
https://repl.it/@hexlet/php-arrays-for-initialize
А вот пример использования нескольких выражений в блоке изменения счётчика:
<?php
for ($i = 0; $i < 5; print("$i\n"), $i++) {
// some code
}
// => 0
// => 1
// => 2
// => 3
// => 4
https://repl.it/@hexlet/php-arrays-for-increment
Рассмотренные блоки могут быть пустыми, при этом сохраняются разделители ;
. Но так делать не рекомендуется. Все блоки должны полным и ясным образом описывать работу цикла.
Дополнительные материалы

Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
- Статья «Как учиться и справляться с негативными мыслями»
- Статья «Ловушки обучения»
- Статья «Сложные простые задачи по программированию»
- Урок «Как эффективно учиться на Хекслете»
- Вебинар «Как самостоятельно учиться»
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.