Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Использование циклов Основы PHP

Итерации цикла

Есть отдельный класс задач, который не может обойтись без циклов — он называется агрегированием данных. К таким задачам относятся поиск максимального и минимального значения, вычисление суммы и среднего арифметического и так далее. Их главная особенность в том, что результат зависит от всего набора данных. Для расчета суммы нужно сложить все числа, для вычисления максимального нужно сравнить все числа.

С такими задачами хорошо знакомы те, кто занимаются числами — например, бухгалтеры или маркетологи. Обычно их выполняют в таблицах в Microsoft Excel или Google Sheets. Именно эту тему мы изучим в этом уроке.

Разберем самый простой пример – поиск суммы набора чисел. Реализуем функцию, которая складывает числа в указанном диапазоне, включая границы. Диапазоном в данном случае называется ряд чисел от какого-то начала до определенного конца. Например, диапазон [1, 10] включает в себя все целые числа от 1 до 10.

<?php

sumNumbersFromRange(5, 7); // 5 + 6 + 7 = 18
sumNumbersFromRange(1, 2); // 1 + 2 = 3

// [1, 1] Диапазон с одинаковым началом и концом – тоже диапазон
// Он в себя включает ровно одно число – саму границу диапазона
sumNumbersFromRange(1, 1); // 1
sumNumbersFromRange(100, 100); // 100

Для реализации этого кода нам понадобится цикл по двум причинам:

  • Сложение чисел — это итеративный процесс, то есть он повторяется для каждого числа
  • Количество итераций зависит от размера диапазона

Перед тем, как смотреть код, попробуйте ответить на вопросы ниже:

  • Каким значением инициализировать счетчик?
  • Как он будет изменяться?
  • Когда цикл должен остановиться?

Попробуйте сначала подумать над этими вопросами, а затем посмотрите код ниже:

<?php

  function sumNumbersFromRange ($start, $finish)
  {
      // Технически можно менять $start
      // Но входные аргументы нужно оставлять в исходном значении
      // Это сделает код проще для анализа
      $i = $start;
      $sum = 0; // Инициализация суммы

      while ($i <= $finish) { // Двигаемся до конца диапазона
          $sum = $sum + $i; // Считаем сумму для каждого числа
          $i = $i + 1; // Переходим к следующему числу в диапазоне
      }

      // Возвращаем получившийся результат
      return $sum;
  };

Общая структура цикла здесь стандартна. В нем есть три компонента:

  • Счетчик, который инициализируется начальным значением диапазона
  • Сам цикл с условием остановки при достижении конца диапазона
  • Изменение счетчика в конце тела цикла

Количество итераций в таком цикле равно $finish - $start + 1. То есть для диапазона от 5 до 7 – это 7 - 5 + 1, то есть три итерации.

Главные отличия от обычной обработки связаны с логикой вычислений результата. В задачах на агрегацию всегда есть какая-то переменная, которая хранит внутри себя результат работы цикла. В коде выше это $sum. На каждой итерации цикла происходит ее изменение, прибавление следующего числа в диапазоне: $sum = $sum + $i.

Весь процесс выглядит так:

<?php

// Для вызова sumNumbersFromRange(2, 5);
$sum = 0;
$sum = $sum + 2; // 2
$sum = $sum + 3; // 5
$sum = $sum + 4; // 9
$sum = $sum + 5; // 14
// 14 – результат сложения чисел в диапазоне [2, 5]

У переменной $sum есть начальное значение, равное 0. Зачем вообще задавать значение? Любая повторяющаяся операция начинается с какого-то значения. Нельзя просто так объявить переменную и начать с ней работать внутри цикла. Это может приводить к ошибкам:

<?php

// начальное значение не задано
// PHP автоматически делает его равным NULL
$sum;

// первая итерация цикла
$sum = $sum + 2; // ?

В результате такого вызова внутри $sum окажется верный результат, но интерпретатор выведет ошибку: PHP Notice: Undefined variable: sum. Она возникает из-за попытки использовать неопределенную переменную. Значит какое-то значение все же нужно. Почему в коде выше выбран 0? Очень легко проверить, что все остальные варианты приведут к неверному результату. Если начальное значение будет равно 1, то результат получится на 1 больше, чем нужно.

В математике у каждой операции существует нейтральный элемент этой операции. Операция с этим элементом не изменяет то значение, над которым проводится операция:

  • Ноль при сложении: любое число + ноль = само число
  • Ноль при вычитании: любое число - ноль = само число
  • Пустая строка при конкатенации: '' + 'string' будет 'string'

Агрегация данных (Строки)

Агрегация применяется не только к числам, но и к строкам. Это такие задачи, в которых строка формируется динамически — то есть заранее неизвестно, какого она размера и что будет содержать.

Представьте себе функцию, которая умеет умножать строку, то есть повторять ее указанное количество раз:

<?php

repeat('hexlet', 3); // 'hexlethexlethexlet'

Принцип работы этой функции довольно простой — в цикле происходит «наращивание» строки указанное количество раз:

<?php

function repeat($text, $times)
{
    // Нейтральный элемент для строк – пустая строка
    $result = '';
    $i = 1;

    while ($i <= $times) {
        // Каждый раз добавляем строку к результату
        $result = "{$result}{$text}";
        $i = $i + 1;
    }

    return $result;
}

Распишем выполнение этого кода по шагам:

<?php

// Для вызова repeat('hexlet', 3);
$result = '';
$result = "{$result}hexlet"; // hexlet
$result = "{$result}hexlet"; // hexlethexlet
$result = "{$result}hexlet"; // hexlethexlethexlet

Обход строк

Циклы подходят не только для обработки чисел, но и при работе со строками — и это благодаря возможности получить конкретный символ по его индексу. Ниже пример кода, который распечатывает буквы каждого слова на отдельной строке:

<?php

function printNameBySymbol($name)
{
    $i = 0;
    // Такая проверка будет выполняться до конца строки,
    // включает последний символ
    // Его индекс — `длина строки - 1`
    while ($i < strlen($name)) {
        // Обращаемся к символу по индексу
        print_r("$name[$i]\n");
        $i = $i + 1;
    }
}

$name = 'Arya';
printNameBySymbol($name);
// => 'A'
// => 'r'
// => 'y'
// => 'a'

https://replit.com/@hexlet/php-basics-loops-using-printnamebysymbol

Самое главное в этом коде — поставить правильное условие в while. Это можно сделать сразу двумя способами:

  • $i < strlen($name)
  • $i <= strlen($name) - 1

Оба способа приводят к одному результату.

Формирование строк в циклах

Еще одно использование циклов – формирование строк. Подобная задача нередко встречается в веб-программировании. Она сводится к обычной агрегации с применением интерполяции или конкатенации.

Есть одна задача, крайне популярная на собеседованиях — это переворот строки. Ее можно решить множеством разных способов, но именно посимвольный перебор считается базовым.

Рассмотрим пример работы этой функции:

<?php

reverse('Hexlet'); // telxeH

Общая идея переворота состоит в следующем — нужно брать символы по очереди с начала строки и соединять их в обратном порядке. Звучит довольно просто. Давайте проверим:

<?php

function reverse($str)
{
    $i = 0;
    // Нейтральный элемент для строк — это пустая строка
    $result = '';

    while ($i < strlen($str)) {
        $currentChar = $str[$i];
        // Соединяем в обратном порядке
        $result = "{$currentChar}{$result}";
        // Тоже самое через конкатенацию
        // $result = $currentChar . $result;
        $i = $i + 1;
    }

    return $result;
}

$name = 'Bran';
reverse($name); // 'narB'
// Проверка нейтрального элемента
reverse(''); // ''

https://replit.com/@hexlet/php-basics-loops-using-reverse

Единственный сложный момент в этом коде – прочувствовать, как собирается сама строка. Так как каждый следующий символ прикрепляется к результирующей строке слева, то, в конечном итоге, строка оказывается перевернута.


Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты

Об обучении на Хекслете

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы
профессия
от 6 300 ₽ в месяц
Разработка веб-приложений на Laravel
10 месяцев
с нуля
Старт 2 мая

Используйте Хекслет по-максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»