Перейти к содержимому
Теория · Первая программа · урок 5 из 7

Первая функция

До сих пор программы печатали готовый текст и числа. Вернёмся к карточкам с рецептами. В рецепте торта крем описан на отдельной карточке, и основной рецепт не повторяет его шаги, а пишет: «приготовьте крем по карточке крема».

Повар откладывает основную карточку, делает крем по второй и возвращается с готовым кремом туда, где остановился. Так и работает функция в программе.

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

PHP
<?php

function double($x)
{
    return $x * 2;
}

echo double(3), "\n"; // 6
echo double(10), "\n"; // 20

Запись double(3) — это вызов функции. Давайте проследим за первым вызовом:

  1. double(3) отправляет выполнение в функцию double, где $x равно 3.
  2. return $x * 2; считает 6 и возвращает это число туда, где стоял вызов.
  3. echo получает 6 и печатает его.

Второй вызов работает так же с числом 10 и печатает 20.

Объявление функции

Разберём функцию double по частям.

Строка function

Строка function double($x) начинает объявление функции:

  • function — ключевое слово: «объявляю функцию»;
  • double — имя функции, по нему её вызывают;
  • ($x) — параметр в круглых скобках.

Тело функции — инструкции в фигурных скобках. По правилам оформления открывающую фигурную скобку функции ставят на отдельной строке, а тело сдвигают на 4 пробела. Точку с запятой после закрывающей скобки не ставят: объявление функции заканчивается самой скобкой.

Параметры и аргументы

Параметр — имя, которое получает значение при каждом вызове. В PHP такие имена начинаются со знака $, например $x. В вызове double(3) значение 3 — это аргумент, и оно попадает в параметр $x.

На собеседовании новичков часто спрашивают, чем параметр отличается от аргумента:

  • параметр — имя в объявлении функции, например $x;
  • аргумент — значение, которое передают при вызове, например 3.

Слово return

return завершает функцию и возвращает значение, записанное после него: здесь $x * 2. Сам вызов заменяется этим значением: double(3) в строке с echo превращается в 6.

Функция double сама ничего не печатает. Печатает echo, внутри которого стоит вызов.

Куда возвращается результат

Вызов — это переход. PHP откладывает текущую строку, выполняет тело функции и возвращается на то же место с результатом.

Результат можно сохранить под именем. Имя $a, как и $x, хранит значение: запись $a = double(3); кладёт в него 6, а echo $a печатает то, что в нём лежит.

Нажимайте «Следующий шаг» и следите за рамками. Рамка {main} — это сама программа, а рамка double появляется на время вызова и исчезает, когда return отдаёт результат.

ВживуюВызов функции: туда и обратношаг 1 из 9 · рамок: 1

PHP знает функцию double ещё до запуска, но её тело пока не выполняется.

Подсвеченная строка выполняется сейчас, а в каждой рамке — значения программы или одного вызова

Программа напечатала 6 и 13. Во втором вызове double($a) вернул 12, и только потом PHP прибавил к результату 1. Каждый вызов получает свой $x: в первом он равен 3, во втором — 6.

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

Вызов внутри вызова

Аргументом может быть и другой вызов. Тогда сначала выполняется внутренний вызов, а его результат становится аргументом внешнего:

PHP
echo double(double(2)), "\n"; // 8

Разберём по шагам:

  1. Внутренний вызов double(2) возвращает 4.
  2. Внешний вызов получает аргумент 4 и возвращает 8.
  3. echo печатает 8.

Вызов выше объявления

Как вы уже знаете, PHP читает весь файл до запуска. При этом он запоминает функции, объявленные в файле, поэтому вызов может стоять выше объявления:

PHP
<?php

echo triple(4), "\n"; // 12

function triple($x)
{
    return $x * 3;
}

PHP печатает 12, хотя функция triple объявлена ниже строки с вызовом.

Частая ошибка

В функции забыли return:

PHP
<?php

function double($x)
{
    $x * 2; // ✗
}

echo double(3), "\n";

Сообщения об ошибке нет, но программа печатает пустую строку. Функция считает $x * 2 и отбрасывает результат. Вызов без return возвращает null — пустое значение, и echo его не печатает. Исправление — написать return $x * 2;, как в первом примере.

Главное

  • Функцию объявляют словом function: имя, параметры в круглых скобках, тело в фигурных.
  • Параметр — имя в объявлении функции, аргумент — значение в вызове.
  • Вызов уходит в тело функции, а return возвращает значение на место вызова.
  • Во вложенном вызове сначала выполняется внутренний вызов, и его результат становится аргументом внешнего.