Уроки № 3 - Знакомство с функциями
Теперь, когда вы уже знакомы с переменными, операциями над ними, познакомились с управляющими структурами языка, можно поговорить и о функциях.
Бывают такие ситуации, что какую-то последовательность инструкций вы повторяете много раз. И эта последовательность выполняет в конечном итоге что-то вполне завершенное.
Функция это кучка действий. Она принимает аргументы, делает с ними некие операции и возвращает результат. К примеру Приготовить пиццу это функция принимающая параметры - тесто, яйца, сыр, кетчуп, анчоусы, плиту, и возвращает Пиццу.
Возвращаемое значение у функций может быть любого типа данных.
Еще одним преимуществом функций, является упрощение чтения кода программы.
Синтактсис
Имя функции может состоять из латинских буков, цифр и знаков подчеркивания. Начинаться с цифры оно не должно. Всё точно так же как с названиями переменных.
Возможно вы заметили, что уже с первого урока мы путаем вас понятиями
параметр и аргумент.
Аргументами называются неопределенные входящие данные.
Параметрами же являются известные данные.
Т.е. когда мы описываем функцию, в скобках аргументы, когда вызываем - параметры. Но застопориваться на этом, думаю, не обязательно.
В функции которая готовит пиццу - аргументом будет "количество требуемых блюд"
а параметром будет цифра 5.
Во всяком случае во всех случаях речь идёт о данных передаваемых функции.
Рассмотрим создание самодельной функции на примере.
Задача функции найти самый большой элемент массива.
PHP:
скопировать код в буфер обмена
<?PHP
function arr_max($arr) // Определяем функцию arr_max принимающую один аргумент
{
// Входящие данные: Массив
// Исходящие данные: значение элемента в массиве.
// Устанавливаем значение нулевого элемента как максимального
$max = $arr[0];
for ($i = 1; isset($arr[$i]); $i++) // для каждого элемента массива if ($arr[$i] > $max) // проверяем что больше. Текущее значение или максимум
$max = $arr[$i]; // Если максимум больше, то меняем максимум на новый
$arr[1] = 95; // Поменяем значение первого элемента массива. Не задумывайтесь почему. Чуть позже увидите.
// функция возвращает результат.
// Результат в данном случае самое большое число в массиве
return $max;
}
// Закончилось определение функции. Дальше продолжение скрипта.
$ar1 = array(4, 6, 12, 9, '5', 23
); $ar2 = 'dabcjfutZfgh';
echo arr_max($ar1)."<br>\n"; // Выведет 23
echo '$ar1[1]'.$ar1[1]; // выведет 6 (а не 95, помните ту загадочную строку функции?). Получается значение не изменилось
// Напомним: в одинарных кавычках значения переменных не подставляются
// подумайте над результатами такого вызова:
echo arr_max($ar2);
?>
Область видимости
Как же так получается что операция присваивания $arr[1] = 95
не изменила значение переменной вне функции?
Существует такое понятие - Область видимости. Понять это понятие легко и понятно =)
Функция представляет из себя своего рода маленькую подпрограмму.
У этой подпрограммы есть свои переменные, а переменные из главной программы она просто не видит.
Так как в эту программку одним из параметров поступил массив $arr[1]
это значит что функция вполне его видела и могла с ним работать.
Но на самом деле в функцию передаётся на переменная, а её точная копия. Ее значение.
Поэтому когда наша подпрограмма завершает свое выполнение - все её переменные
(копии наших) удаляются.
Передача параметров по ссылке
Напомню тебе немного первый урок, в котором я объяснял как хранит данные в памяти компьютер, и что $variable на самом деле хранит вовсе не значение а идентификатор ячейки в памяти, в которой как и находится наше значение.
Как ты заметил в примере выше, все переменные используемые в функциях являются локальными, то-есть создаются используются и удаляются в самой функции, а за её пределами не доступны.
Для того, чтобы передать в функцию не значение переменной, а саму переменную которую функция сможет изменить и за её пределами мы сможем ею пользоваться - существует особый способ передачи параметров - По ссылке. Выглядит вызов функции с параметрами по ссылке с добавлением символа & вот так: myFunction(&$myvar);
Когда в вызове функции переходит передача переменной по ссылке происходит передача идентификатора ячейки, а не значения. Когда ты вызываешь функцию func($a) интерпретатор в первую очередь достает из памяти значение переменной $a и передает это значение в функцию. После этого в самой функции создается новая переменная которой присваивается это значение.
Когда функция вызывается с параметром по ссылке func(&$a) интерпретатор передает в функцию не значение переменной, а идентификатор ячейки в памяти
При вызове функции с параметрами обычным способом все изменения происходят в другой, новой ячейке памяти и за пределами функции работа продолжается со старой ячейкой. А при передаче по ссылке все изменения происходят в той же ячейке и поэтому изменения видны и из вне самой функции.