Тело функции

}

Рис. 3.97. Синтаксис функций .

 

Имя функции должно подчиняться условиям, приведенным для идентификаторов. После имени функции следуют обязательные круглые скобки, в которые заключается необязательный список входных параметров ($параметр1, $параметр2, ...., $параметрn). Вследствие относительно либеральных принципов определения переменных в PHP указывать тип входных параметров не нужно. Хотя такой подход имеет свои преимущества, следует помнить, что механизм PHP не проверяет аргументы на соответствие тем типам, которые должны обрабатываться функцией. Случайные ошибки в использовании входных параметров могут привести к неожиданным последствиям (чтобы убедиться в том, что параметр относится к нужному типу, можно проверить его стандартной функцией gettype( )). После закрывающей круглой скобки следуют фигурные скобки, в которые заключается программный код, ассоциируемый с именем функции.

 

Рассмотрим простой пример использования функции. Предположим, вы хотите создать функцию для вывода лицензионной информации на web-странице:

 

function display_copyright()

{

print "Copyright © 2009 PHP-Powered Recipes. All Rights Reserved.";

}

Рис. 3.98. Простейшая функция .

 

Если ваш web-сайт состоит из нескольких страниц, достаточно вызвать эту функцию в конце каждой страницы -- и вам не придется заново переписывать один и тот же текст. А когда наступит 2010 год, одно простое изменение текста, выводимого этой функцией, приведет к автоматическому обновлению всех страниц. Если бы не преимущества функционального программирования, вам пришлось бы вручную редактировать все страницы, на которых выводится лицензионная информация.

 

Рассмотрим разновидность функции display_copyright(), которой при вызове передается параметр. Предположим, вы отвечаете за администрирование нескольких web-сайтов, каждому из которых присвоено отдельное имя. На каждом сайте имеется собственный административный сценарий с несколькими переменными, относящимися к этому сайту; к их числу принадлежит переменная $site_name с именем сайта.

В этом случае функцию display_copyright() можно записать следующим образом:

 

function display_copyright($site_name)

{

print "Copyright © 2009 $site_name. All Rights Reserved.";

}

Рис. 3.99. Простейшая функция с параметром .

 

Переменная $site_name, значение которой присваивается за пределами display_copy-right(), передается функции в качестве параметра. Переданное значение можно использовать и модифицировать в любом месте функции, однако любые изменения будут действовать лишь внутри этой функции. Впрочем, специальные ключевые слова позволяют сделать так, чтобы изменения параметров распространялись и за пределы display_copyright(). Эти ключевые слова были представлены в лекции, в общем обзоре области видимости переменных и ее отношения к функциям.

Задание 1. Вложенные функции. Lab8_0_0.php

Функции можно вызывать внутри других функций -- по аналогии с тем, как одна управляющая конструкция (if, while, for и т. д.) может находиться внутри другой. Такая возможность удобна в любых программах, и в больших, и в малых, поскольку она увеличивает степень модульности приложения и упрощает сопровождение программы.

 

В примере, описанном выше, можно полностью избавиться от необходимости модификации даты. Для этого достаточно включить в display_copyright() вызов стандартной функции PHP date( ):

 

function display_copyright($site_name)

{

print "Copyright &copy ". date("Y"). "$site_name. All Rights Reserved.";

}

 

Рис. 3.100. Простейшая функция с параметром и без констант.

 

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

Ниже на рис. 3.101 приведен пример описания и вызова фунцкии в файле Lab8_0_0.php. На рис. 3.102 показан результат вывода на экран работы функции display_copyright.

 

Рис. 3.101. Простейшая функция с параметром и без констант.

 

Рис. 3.102. Результат работы функции display_copyright.

Примечание. Далее, для удобства, на рисунках будет приводиться только PHP код (информация между тегами и ).

 

 

Задание 2. Объявление функций внутри других функций. Lab8_0.php

 

Также допускается объявление функций внутри других функций. Тем не менее, вложенное объявление еще не делает функцию «защищенной», то есть не ограничивает возможность ее вызова той функцией, в которой она была объявлена. Более того, вложенная функция не наследует параметров родительской функции; параметры должны передаваться ей точно так же, как и любой другой функции.

Пример вложенного объявления приведен в листинге рис. 3.103.

 

 

Рис. 3.103. Использование вложенных функций.

 

Сценарий выводит следующий результат:

Рис. 3.104. Результат Lab8_0.php.

 

Обратите внимание: функцию display_copyright( ) можно вызвать и за пределами display_footer( ). Концепция защищенных функций в PHP не поддерживается. Так, например, если строку с номером 31 на рис 3.103 раскоментарить, то получим следующий результат (рис. 3.105).

 

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

 

Рис. 3.105. Результат Lab8_0.php после модификации.

 

 

Задание 3. Возврат значений функцией. Lab8_1.php

 

По завершении работы функции часто бывает полезно вернуть некоторое значение, для чего результат вызова функции обычно присваивается некоторой переменной. Функции могут возвращать значения любых типов, в том числе массивы и списки. Пример приведен в листинге 3.106, где функция calculate_cost( ) вычисляет налог с заданной суммы и возвращает общую сумму вместе с налогом.

Рис. 3.106. Листинг Lab8_1.php.

 

Краткое описание алгоритма.

Перед вызовом функции задаются значения переменных: $price (цена товара) и $tax (налоговая ставка).

Объявляется функция calculate_cost( ). При вызове функция получает два параметра: налоговую ставку и цену товара. Она вычисляет цену с учетом налога и возвращает ее командой return.

В теле программы вызывается calculate_cost() и значение возвращенное функцией, присваивается переменной $total_cost.

Далее выводятся соответствующие сообщения (рис. 3.107).

 

Рис. 3.107. Результат Lab8_1.php.

 

Функции, не возвращающие значений, также называются процедурами.

 

Задание 4. Возврат нескольких значений функцией. Lab8_2.php

 

Существует и другой способ использования возвращаемых значений, при котором вызов функции включается прямо в условную/циклическую команду. В следующей программе (листинг 3.108) сумма счета пользователя сравнивается с предельным размером кредита.

Алгоритм выглядит так:

Объявить функцию check_limit( ), которая при вызове получает два параметра. Первый параметр, $total_cost, определяет общую сумму счета, накопленную пользователем до настоящего момента. Второй параметр, $credit_limit, определяет максимальную сумму, которую может потратить пользователь. Объявление и состав функции на рис. 3.108 представлено строками 13-22.

Если накопленная сумма счета превышает предельный размер кредита, функция возвращает ложное значение (0).

Если условие команды if оказывается ложным, работа функции еще не завершена. В этом случае общая сумма не превышает предельного размера кредита, поэтому функция должна вернуть логическую истину.

Вызвать функцию check_limit( ) в условии команды if. Проверить, какое значение было возвращено при вызове -- истинное или ложное. В зависимости от результата проверки выполняется то или иное действие.

 

Если при вызове check_limit( ) было получено значение TRUE, мы предлагаем пользователю продолжить закупку. В противном случае пользователь информируется о превышении кредита.

 

Листинг программы сравнения текущей суммы счета пользователя с предельным размером кредита приведен на рис. 3.108, а результат (при указанных исходных данных) на рис. 3.109.

 

Рис. 3.108. Результат Lab8_2.php.

 

При выполнении листинга 3.108 будет выведено сообщение об ошибке, поскольку значение $cost превышает $limit.

 

Рис. 3.109. Результат Lab8_2.php.

 

Задание 5. Возвращение функцией нескольких величин. Lab8_3.php

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

Краткий алгоритм:

Объявить функцию best_years( ), вызываемую с одним параметром. Параметр $label определяет сорт вина, для которого пользователь хотел бы узнать три рекомендуемых года.

Объявить два массива, $Tokay и $zinandali. В каждом массиве хранится три рекомендуемых года для соответствующего сорта вина.

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

Вывести сообщение с информацией о рекомендуемых годах.

 

Листинг 3.110. Возвращение функцией нескольких величин

Рис. 3.110. Исходный код PHP в Lab8_3.php.

 

Программа выводит следующий результат:

Рис. 3.111. Результат Lab8_3.php.

Задание 6. Рекурсивные функции . Lab8_4.php

Ситуация, при которой функция многократно вызывает сама себя, пока не будет выполнено некоторое условие, открывает замечательные возможности. При правильном использовании рекурсивные функции уменьшают объем программы и делают ее более выразительной. Рекурсивные функции особенно часто используются при выполнении повторяющихся действий -- например, при поиске в файлах/массивах и построении графических изображений (например, фракталов). Классическим примером рекурсивных функций, встречающимся во многих курсах программирования, является суммирование чисел от 1 до N. Программа, приведенная в листинге 3.112, суммирует все целые числа от 1 до 10.

 

Листинг 3.115. Использование рекурсивной функции для суммирования последовательных целых чисел

Рис. 3.112. Исходный код PHP в Lab8_4.php.

 

В результате выполнения листинга 3.112 будет выведен следующий результат:

Рис. 3.113. Результат Lab8_4.php.

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

 

Задание 7. Функции-переменные. Lab8_5.php

Одной из интересных возможностей PHP являются функции-переменные (variable functions), то есть динамические вызовы функций, имена которых определяются во время выполнения программы. Они значительно сокращают объем и сложность программного кода, а также часто снимают необходимость в условных командах if.

 

Вызов функции-переменной представляет собой имя переменной, за которым следует пара круглых скобок. В круглых скобках могут перечисляться параметры (однако присутствие параметров не обязательно).

 

Следующая программа (листинг 3.114) демонстрирует эту непривычную, но полезную возможность. Допустим, программа выводит разную информацию в зависимости от языка, выбранного пользователем. В нашем примере для простоты используются приветственные сообщения для англо- и русскоязычных пользователей.

Алгоритм:

Создать сообщение для русского языка в функции с именем rushian.

Создать сообщение для английского языка в функции с именем english.

Передать информацию о выбранном языке в сценарий, присвоив значение переменной $language.

 

Переменная $language используется для выполнения функции-переменной (в приведенном примере -- russian ()).

Листинг 3.117. Выбор функции в зависимости от пользовательского ввода

Рис. 3.114. Листинг Lab8_5.php.

 

Листинг 3.114 демонстрирует интересную концепцию функций-переменных и наглядно показывает, что функции-переменные способствуют уменьшению объема программного кода. Если бы не эта возможность, функцию пришлось бы выбирать командой if или switch; это привело бы к заметному увеличению объема программного кода и риску появления дополнительных ошибок при кодировании.

 

Рис. 3.115. Результат Lab8_5.php.

 

Задание 8. Построение библиотек функций. Lab8_6_0.php.

 

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

include(имя файла с расширением );

include_once(имя файла с расширением );

require(имя файла с расширением );

require_once(имя файла с расширением ).

Функция include( ) включает содержимое файла в сценарий. Функция include_once( ) делает то же, что и include( ), за одним исключением: прежде чем включать файл в программу, она проверяет, не был ли он включен ранее. Если файл уже был включен, вызов include_once( ) игнорируется, а если нет — происходит стандартное включение файла.

Функция require( ) похожа на include( ) — она тоже включает шаблон в тот файл, в котором находится вызов require( ).

Между функциями require( ) и include( ) существует одно важное различие. Файл, определяемый параметром require( ), включается в сценарий независимо от местонахождения require( ) в сценарии. Например, при вызове requiге( ) в блоке if при ложном условии файл все равно будет включен в сценарий!

 

Весь код РНР во включаемом файле обязательно заключается в теги РНР.

 

Чтобы пояснить механизм использования функций require() и include( ) рассмотрим простейший сценарий реализующий переход по ссылке (рис. 3.116).

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">

<title>Lab8_6 Библиотеки функций</title></head>

<?PHP

print "<b>Простейшее меню на ссылке. Lab8_6.php</b> <br>";

?>

<body bgcolor=pink>

<?PHP

$site_title = "Название сайта";

$contact_email = "Ord@yandex.ru";

$contact_name = "VVS";

print "Вход на сайт- $site_title. <br> Контакт <a href =

\"mai1to:$contact_email\">$contact_name</a>.";

?>

</body>

</html>

Рис. 3.116. Листинг Lab8_6.php.

 

Программа элементарна и ее вывод показан на рис. 3. 117.

Рис. 3.117. Содержимое браузера для Lab8_6.php.

 

Чтобы уяснить принцип работы require( ) и include( ) представим содержимое файла показагого на рис. 3.116 в виде двух файлов (Lab8_6_0. php -рис. 3.118 и Lab8_6_1. php - рис. 3.119)

Рис. 3.118. Содержимое Lab8_6_0.php.

 

Как показано на рис. 3.118 листинг программы содержит включающий файл в который вынесено содержимое следующих строк (рис. 3.119) из файла Lab8_6.php.

 

Рис. 3.119. Содержимое для Lab8_6_1.php.

 

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

Имя расширения для включаемого файла может быть любым.

 

Отметим, что если строку раскоментарить,

а строку

закоментарить, то реультат будет такой же, как показан на рис. 3.121.

 

Рис. 3.120. Экран браузера для Lab8_6_0.php.

 

Результат также не изменится, если первой строкой в листинге (рис. 3.118) будет указано

 

Задание 9. Построение шаблона сайта. Lab8_7_0.php.