Зарегистрируйтесь для доступа к 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, то есть 3 итерации.

Главные отличия от обычной обработки связаны с логикой вычислений результата. В задачах на агрегацию всегда есть какая-то переменная, которая хранит внутри себя результат работы цикла. В коде выше это $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 больше, чем нужно.

В математике существует понятие нейтральный элемент операции (у каждой операции свой элемент). Это понятие имеет очень простой смысл. Операция с этим элементом не изменяет то значение, над которым проводится операция. В сложении любое число плюс ноль дает само число. При вычитании – тоже самое. Даже у конкатенации есть нейтральный элемент – это пустая строка: '' + 'one' будет 'one'.

Вопрос на самопроверку. Какой нейтральный элемент у операции умножения?

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

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

<?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
Рекомендуемые программы

С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.

Иконка программы PHP-разработчик
Профессия
с нуля
Разработка веб-приложений на Laravel
1 декабря 10 месяцев

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

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

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

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