ProfiPHPProfiPHP
  1. Главная
  2. Самоучитель PHP 7
  3. Функции

Функции

В PHP существуют огромное количество встроенных функций, которые применяются для самых разнообразных задач. Но помимо них, разработчики могут создавать собственные пользовательские функции, которые представляют собой фрагмент программы, предназначенный для реализации определенных действий, выполнение которых достигается вызовом функции в требуемом месте программы. Функции могут принимать несколько аргументов и возвращать полученное значение, но основное предназначение функций является исключение дублирующих фрагментов кода и добиться повторного его использования.

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


Для объявления функции необходимо воспользоваться ключевым словом Function, после которого следует имя функции, в круглых скобках параметры функции и в фигурных скобках тело функции:
function myFunction()
{
// операторы
}
Стандарт кодирования PSR рекомендует имя функции задавать в camelCase-стиле с первой строчной буквой, чтобы отличать функции от классов.
Функция может возвращать значение. Для этого необходимо использовать конструкция return:
function myFunction()
{
// операторы
return 0;
}
Продемонстрируем пример, где функция вычисляет сумму двух чисел:
<?php
function getSum()
{
$sum = 1 + 2;
return $sum;
}
echo getSum(); // 3
В данном примере функция не принимает ни одного аргумента, а просто вычисляет сумму и возвращает полученный результат. После этого она вызывается в теле конструкции Echo для вывода результата в браузер. Можно изменить функцию так, чтобы вывод осуществлялся исключительно в теле функции, для этого необходимо конструкцию return изменить на echo. Однако такой подход обычно не приветствуется, то есть сильно сужает область применения функции, поскольку возвращаемую строку не можно будет передать далее для обработки другим функциям.

Функция может вызываться до ее объявления, за исключением тех случаев, если объявление функции осуществляется в зависимости от условия внутри фигурных скобок. В этом случае попытка вызова функции, объявленной условно, раньше объявления приводит к генерации ошибки: "Fatal error: Uncaught Error: Call to undefined function".

Параметры и аргументы функции


Благодаря использования параметров функции можно значительно увеличить гибкость функции:
<?php
function getSum($a, $b)
{
$sum = $a + $b;
return $sum;
}
echo getSum(1, 2); // 3
Переменные $a и $b, которые задаются в круглых скобках при объявлении, называются параметрами функции. При вызове функции вместо них могут быть подставлены переменные с другими названиями или просто значения, которые называются аргументами функции. В качестве аргументов могут выступать выражения и даже другие функции.

Типы параметров и возвращаемого значения


Также допускается при объявлении функции указывать типы параметров. Если необходимо задать тип возвращаемого значения он указывается через двоеточие непосредственно перед телом функции:
<?php
function getSum(int $a, int $b) : int
{
return $a + $b;
}
echo getSum(1, 2); // 3
echo getSum(1.5, 2.5); // 3

Передача параметров по значению и ссылке


По умолчанию значения параметров функции изменяются только внутри функции, и эти изменения не влияют на значения переменных за пределами функции.
<?php
function getSum($var) // аргумент передается по значению
{
$var = $var + 5;
return $var;
}
$new_var = 10;
echo getSum($new_var); // 15
echo $new_var; // 10
Для того чтобы переменные, переданные функции, сохраняли свое значение при выходе из нее, применяется передача параметров по ссылке. Для этого перед именем переменной необходимо поместить амперсанд (&):
function get_sum(&$var)
Объекты и массивы передаются в функцию по ссылке, поэтому применительно к таким параметрам можно не применять символ амперсанда (&).
<?php
function getSum(&$var) // аргумент передается по значению
{
$var = $var + 5;
return $var;
}
$new_var = 10;
echo getSum($new_var); // 15
echo $new_var; // 15

Необязательные параметры


Если параметрам присвоить значение по умолчанию, тогда данные параметры являются необязательными.
<?php
function getSum($a = 1, $b = 2)
{
$sum = $a + $b;
return $sum;
}
echo getSum(); // 3
echo getSum(2); // 4
echo getSum(2, 3); // 5
Из примера видно, что даже если функции getSum() не передаются аргументы, она успешно производит вычисления с участием параметров по умолчанию. Если функция содержит множество обязательных и необязательных параметров, то все обязательные параметры следует располагать до необязательных, иначе будет выведена ошибка: "Fatal error: Uncaught ArgumentCountError: Too few arguments to function".

Переменное количество параметров


Для того чтобы создать функцию, которая принимает переменное количество аргументов, перед последним параметром следует указать многоточие. Внутри функции такой параметр рассматривается как массив, содержащий все дополнительные параметры:
<?php
function echoList(...$items)
{
foreach ($items as $value) {
echo $value; // выводим элемент
}
}
echoList('red', 'green', 'yellow'); // red green yellow
До версии 5.6 РНР не поддерживал описываемый механизм обработки переменного количества параметров. Вместо этого использовались функции Func_num_args, Func_get_arg и Func_get_args.

Оператор ... может использоваться не только перед аргументами функций, но и при вызове с массивом. Это позволяет осуществить "развертывание" массива:
<?php
function tooManyArgs($a, $b, $c)
{
echo "Первый параметр: $a";
echo "Второй параметр: $b";
echo "Третий параметр: $c";
}
$items = ['red', 'yellow', 'green'];
tooManyArgs(...$items);
Как видно с примера, можно поместить значения параметров в массив $items и передать его функции, предварив оператором ..., который развернет элементы массива в соответствующие параметры:
Первый параметр: red
Второй параметр: yellow
Третий параметр: green

Глобальные переменные


Переменные в функциях имеют локальную область видимости. Это означает, что даже если локальная (внутри функции) и внешняя (в не функции) переменные имеют одинаковые имена, то изменение локальной переменной никак не повлияет на внешнюю переменную. Локальную переменную можно сделать внешней, если перед ее именем указать ключевое слово global. В этом случае изменения как внутри функции, так и вне ее будут влиять на переменную, а сама переменная будет называться глобальной. Если локальная переменная объявлена как global, то к ней возможен доступ из любой части программы:
<?php
function getSum()
{
global $a;
$a = 1; // изменяем глобальную переменную
return $a;
}
$a = 5;
echo $a; // выводит 5
echo getSum(); // выводит 1(глобальная переменная изменена)
echo $a; // выводит 1

Статические переменные


Поскольку локальные переменные имеют своей областью видимости функцию, то время жизни локальной переменной определяется временем выполнения функции, в которой она объявлена. Это означает, что в разных функциях совершенно независимо друг от друга могут использоваться переменные с одинаковыми именами. Локальная переменная при каждом вызове функции инициализируется заново, поэтому функция-счетчик, пример которой показан в примере, всегда будет возвращать значение 1:
<?php
function counter()
{
$counter = 0;
return ++$counter;
}
Для того чтобы локальная переменная сохраняла свое предыдущее значение при новых вызовах функции, ее можно объявить статической при помощи ключевого слова static:
<?php
function counter()
{
static $counter = 0;
return ++$counter;
}
В примере, переменная $counter устанавливается в ноль при первом вызове функции, и при последующих вызовах функция будет знать, каким было значение переменной при предыдущих вызовах.

Временем жизни статических и глобальных переменных является время выполнения сценария. То есть если пользователь перезагружает страницу, что приводит к новому выполнению сценария, переменная $counter инициализируется заново.

Возврат массива функцией


Если передать конструкции return массив, то функция возвратит массив в качестве значения. Более того, такой массив может создаваться динамически при помощи конструкции array() или []. К этому приему прибегают всякий раз, когда функция должна вернуть несколько значений, а передача значений по ссылке не допускается. Продемонстрируем пример, в котором функция принимает в качестве значения размер файла в байтах и возвращает массив, первый элемент которого содержит размер в байтах, второй - в килобайтах, третий - в мегабайтах, а четвертый - в гигабайтах.
<?php
function formatSize($bytes)
{
$kbytes = $bytes / 1024;
$mbytes = $kbytes / 1024;
$gbytes = $mbytes / 1024;
return [$bytes, $kbytes, $mbytes, $gbytes];
}
list($bytes, $kbytes, $mbytes, $gbytes) = formatSize(45678921);
Если массив имеет постоянное небольшое количество элементов, тогда оперировать им в скрипте не всегда удобно. Поэтому часто при вызове функции элементы массива сразу же сопоставляются переменным при помощи конструкции List, что продемонстрировано в предыдущем примере.

Рекурсивные функции


Рекурсия - это вызов функции самой себя. Приведем пример рекурсивной функции:
<?php
function callself($counter)
{
if ($counter > 0) {
echo $counter--;
callself($counter);
}
else return;
}
callself(5);
Результатом работы функции будет последовательность цифр: 54321. Функция вызывает саму себя до тех пор, пока ее параметр $counter положителен и не равен нулю. Поскольку рекурсивные функции относятся к трудным по восприятию конструкциям языка, их по возможности стараются избегать. Опасность использования неотлаженных рекурсивных функций заключается в возможности их зависание, то есть перехода в режим бесконечной рекурсии.

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

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

Динамическое имя функции


По аналогии с переменными, имя функции может быть динамическим и храниться в строковой переменной - передача такой переменной оператором круглых скобок (с параметрами, если они требуются) приводит к вызову функции:
<?php
function str()
{
return 'Hello, World!';
}
$var = 'str';
echo $var(); // Hello, World!

Анонимные функции


Анонимные функции - это функции без имени:
<?php
$echoList = function (...$str)
{
foreach ($str as $value) {
echo $value;
}
};
// Вызов функции
$echoList('red', 'yellow', 'green'); // red yellow green

Замыкания


Замыкание - это функция, которая запоминает состояние окружения в момент своего создания. Даже если состояние затем изменяется, замыкание содержит первоначальное состояние. Для активизации необходимо использовать ключевое слово use, а за ним в скобках можно указать переменные, которые должны войти в замыкание:
<?php
$message = 'First';
$check = function(array $errors) use ($message)
{
if (isset($errors) && count($errors) > 0) {
echo $message;
foreach($errors as $error) {
echo $error;
}
}
};
$check([]); // First
$erorrs[] = 'Second';
$check($erorrs);
$message = 'Third';
$erorrs = ['Fourth', 'Fifth', 'Sixth'];
$check($erorrs);
Глава примере создается анонимная функция-замыкание, которая помещается в переменную $check, при помощи ключевого слова use замыкание захватывает переменную $message, которую использует в своей работе. Попытка изменить зна­чение переменной позже не приводит к результату. Замыкание "помнит" состояние переменной в момент своего создания. Результатом выполнения скрипта будут сле­дующие строки:
First
Second
First
Fourth
Fifth
Sixth
Основное назначение замыканий - замена глобальных переменных. В отличие от глобальных переменных, вы можете передать внутрь функции значение, но уже не сможете изменить переменную, переданную через механизм замыкания. Самое главное - никакие изменения глобальной переменной в других частях программы не смогут повлиять на значение, переданное через замыкание.

Добавить комментарий

Имя:
Текст комментария: