Урок 5. Функции
Функция — именованный кусок кода, который можно вызвать сколько угодно раз. Если одно и то же действие встречается в программе дважды, его пора вынести в функцию: так код короче, а исправлять ошибку придётся в одном месте, а не в десяти.
Своя функция
<?php
function greet(string $name): string
{
return "Привет, $name!";
}
echo greet("Анна") . "\n";
echo greet("Олег") . "\n";Привет, Анна!
Привет, Олег!Из чего состоит объявление:
function greet— объявление функции с именемgreet;(string $name)— параметр: значение, которое функция получает при вызове, и его тип;: stringпосле скобок — тип результата;returnвозвращает результат и сразу завершает функцию.
Функция, которая ничего не возвращает, а, например, только выводит текст, получает тип void. Имена функций, в отличие от переменных, не зависят от регистра, но вызывать функцию принято так, как она объявлена. Объявить две функции с одним именем нельзя — будет ошибка Cannot redeclare.
Значения по умолчанию и именованные аргументы
<?php
function power(int $base, int $exp = 2): int
{
return $base ** $exp;
}
echo power(5) . "\n";
echo power(2, 10) . "\n";
echo power(exp: 3, base: 4) . "\n";25
1024
64У параметра $exp есть значение по умолчанию, поэтому при вызове его можно не указывать. Параметры со значением по умолчанию ставят в конец списка. С PHP 8.0 аргументы можно передавать по имени — exp: 3 — в любом порядке. Это удобно, когда параметров много: вызов power(exp: 3, base: 4) читается без заглядывания в объявление.
Типы и strict_types
Типы параметров — подсказка и защита: передать в функцию неподходящее значение не получится. Чаще всего встречаются int, float, string, bool, array, а также:
?string— строка илиnull;int|float— одно из нескольких (с PHP 8.0);void— функция ничего не возвращает;mixed— что угодно.
По умолчанию PHP мягко приводит типы: строку "21" в параметр int он превратит в число 21. Строгий режим включается первой строкой файла:
<?php
declare(strict_types=1);
function twice(int $n): int
{
return $n * 2;
}
echo twice(21) . "\n";
echo twice("21") . "\n";Первый вызов выведет 42, а второй остановит программу ошибкой TypeError с текстом Argument #1 ($n) must be of type int, string given. Без строки declare второй вызов тоже вывел бы 42. Строгий режим ловит ошибки раньше, поэтому его включают во многих проектах. Действует он на вызовы в том файле, где объявлен.
Область видимости
Переменные внутри функции свои. Переменные снаружи функция не видит:
<?php
$site = "glif.by";
function showSite(): void
{
echo $site;
}
showSite();Вместо адреса PHP выведет предупреждение Undefined variable $site. Правильный способ — передать значение параметром: function showSite(string $site) и вызов showSite($site). Существует и слово global, которое открывает функции внешнюю переменную, но так код быстро запутывается: непонятно, кто и где её меняет.
Несколько результатов
Функция возвращает одно значение, но им может быть массив. Его удобно сразу разложить по переменным:
<?php
function minMax(array $numbers): array
{
return [min($numbers), max($numbers)];
}
[$low, $high] = minMax([3, 9, 1, 7]);
echo "От $low до $high\n";От 1 до 9Стрелочные и анонимные функции
Функцию можно создать без имени и передать другой функции. Короче всего — стрелочная функция fn:
<?php
$numbers = [1, 2, 3, 4, 5, 6];
$squares = array_map(fn($n) => $n * $n, $numbers);
$even = array_filter($numbers, fn($n) => $n % 2 === 0);
echo implode(" ", $squares) . "\n";
echo implode(" ", $even) . "\n";1 4 9 16 25 36
2 4 6array_map применяет функцию к каждому элементу и собирает новый массив, array_filter оставляет элементы, для которых функция вернула true. Стрелочная функция состоит из одного выражения и видит переменные снаружи.
Сортировка по своему правилу — usort. Правило сравнивает два элемента; оператор <=> («космический корабль») возвращает -1, 0 или 1:
<?php
$users = [
["name" => "Олег", "age" => 34],
["name" => "Анна", "age" => 19],
["name" => "Ира", "age" => 27],
];
usort($users, fn($a, $b) => $a["age"] <=> $b["age"]);
foreach ($users as $user) {
echo "{$user['name']} ({$user['age']})\n";
}Анна (19)
Ира (27)
Олег (34)Если в функции несколько строк, пишут анонимную функцию function. Внешние переменные ей передают явно через use:
<?php
$discount = 10;
$apply = function (int $price) use ($discount): int {
$result = $price - $discount;
return max($result, 0);
};
echo $apply(25) . "\n";
echo $apply(5) . "\n";15
0Встроенные функции
В PHP тысячи готовых функций: для строк, массивов, дат, файлов, математики. Прежде чем писать свою, поищите готовую: наберите имя функции или задачу в поиске на php.net. У каждой функции там описаны параметры, возвращаемое значение и примеры.
Частые ошибки
- Забыт
return: функция считает, но результата нет. С типом результата (: int) PHP остановит программу ошибкойReturn value must be of type int, none returned. Too few arguments to function— при вызове не хватает аргумента, у которого нет значения по умолчанию.Undefined variableвнутри функции — она не видит переменную снаружи. Передайте значение параметром.Cannot redeclare— функция объявлена дважды. Часто так бывает, когда файл с функциями подключён два раза: подключайте его черезrequire_once(урок 7).
Коротко
- Функция объявляется словом
function, результат возвращаетreturn. - Типы параметров и результата пишутся явно:
function f(int $x): string. - Параметры со значением по умолчанию — в конце; с PHP 8 аргументы можно передавать по имени.
declare(strict_types=1);в начале файла запрещает молчаливое приведение типов.- Внутри функции не видно внешних переменных — передавайте их параметрами.
fn($x) => …— короткая функция дляarray_map,array_filter,usort.