7 Пользовательские функции в PHP

В языке PHP имеется множество встроенных функций, которые решают очень полезные задачи. Однако если при разработке Web-сайта понадобилась функция, которая отсутствует в языке РНР, можно воспользоваться пользовательскими функциями, то есть можно создавать собственные функции и заставлять их решать любые задачи [4].

7.1 Определение и вызов функций

Создание пользовательской функции начинается с написания ключевого слова function с последующим указанием имени функции, по которому она будет вызываться. Если требуется, чтобы функция принимала какие-либо аргументы, то их необходимо перечислить в круглых скобках после имени функции. После этого необходимо помес-тить в фигурные скобки код (тело) функции, который выполняется при ее вызове [4].

Синтаксис:

function functionname (parameters)

{

//тело функции

},

где functionname - имя функции,

parameters - передаваемые параметры.

Нужно отметить, что процесс выполнения содержимого тела функции в PHP-сценарии называется вызовом функции. При этом если необходимо, чтобы функция отправляла данные обратно в PHP-код, можно использовать оператор return. Сам по себе оператор return не отображает значение, он лишь передает результат из функции.

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

Например, в представленном ниже коде

function bonus($total_sales, $bonus_factor) // определение функции

{

$bonus = $total_sales * $bonus_factor; // выполнение функции

return $bonus; // возвращение значения функции

}

$total_sales = 10000;

$bonus_factor = 0.15; //присваивание значений переменным

echo (bonus($total_sales, $bonus_factor)); // вызов функции

функции с именем bonus были переданы в качестве параметров две переменные “$total_sales” и “$bonus_factor”, которым были присвоены соответствующие значения.

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

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

HTML-код программы расчета стоимости путевок представлен ниже.

<HTML>

    <HEAD>

    <TITLE>Пример использования пользовательской функции

    </TITLE>

    </HEAD>

    <BODY>

        <B>Заказ путевок в отели Турции.</B>

        <BR><BR>

        <?php

            function calculator ($price, $city_modifier, $star_modifier)

            { return $price = $price * $city_modifier * $star_modifier; }

            if (isset($_POST['posted'] ))

            { $price = 500;

            $star_modifier = 3;

            $city_modifier = 1;

            $destgrade = $_POST['destination'].$_POST['grade'];

            switch($destgrade)

            {case "Kimerthree":

            $city_modifier = 2;

            $str_res = "3-звёздочном отеле города Кемер:";

            break;

            case "Kimerfour":

            $city_modifier = 2;

            $star_modifier = 4;

            $str_res = "4-звёздочном отеле города Кемер:";

            break;

            case "Kimerfive":

            $city_modifier = 2;

            $star_modifier = 5;

            $str_res = "5-звёздочном отеле города Кемер:";

            break;

            case "Antaliathree":

            $city_modifier = 3.5;

            $str_res = "3-звёздочном отеле города Анталия:";

            break;

            case "Antaliafour":

            $city_modifier = 3.5;

            $star_modifier = 4;

            $str_res = "4-звёздочном отеле города Анталия:";

            break;

            case "Antaliafive":

            $city_modifier = 3.5;

            $star_modifier = 5;

            $str_res = "5-звёздочном отеле города Анталия:";

            break;

            case "Alaniathree":

            $str_res = "3-звёздочном отеле города Алания:";

            break;

            case "Alaniafour":

            $star_modifier = 4;

            $str_res = "4-звёздочном отеле города Алания:";

            break;

            case "Alaniafive":

            $star_modifier = 5;

            $str_res = "5-звёздочном отеле города Алания:";

            break;

            default;

            $city_modifier = 0;

            echo ("Пожалуйста, вернитесь и начните сначала");

            break; }

            if ($city_modifier <> 0)

            {echo "Недельная стоимость проживания в " . $str_res . " - " . "$" . calculator($price, $city_modifier, $star_modifier); } }

        ?>

        <FORM method="POST" action="holiday.php">

        <INPUT type="hidden" name="posted" value="true">

        <HR align="left" width="300" color="gray">

        В каком городе Вы хотели бы провести отпуск? <BR><BR>

        <INPUT name="destination" type="radio" value="Kimer" checked>

        Кемер <BR>

        <INPUT name="destination" type="radio" value="Antalia">

        Анталия <BR>

        <INPUT name="destination" type="radio" value="Alania">

        Алания<BR><BR>

        В отеле какого класса Вы хотели бы остановиться? <BR><BR>

        <INPUT name="grade" type="radio" value="three" checked>

        Три звездочки<BR>

        <INPUT name="grade" type="radio" value="four">

        Четыре звездочки<BR>

        <INPUT name="grade" type="radio" value="five" >

        Пять звездочек<BR><BR>

        <INPUT type="submit" value="Отправить заказ">

        </FORM>

    </BODY>

</HTML>

Результат работы данного кода представлен на рисунке 7.1.


Рисунок 7.1 – Расчет стоимости проживания в отелях Турции

Как видно на рисунке 7.1, в данном примере, после загрузки Web-страницы, пользователю предоставляется форма заказа путевки в отели Турции. На странице представлены города, а также классы отелей, которые пользователь может выбрать с помощью переключателей. После нажатия кнопки “Отправить заказ”, пользователю предоставляется рассчитанная стоимость недельного проживания в выбранном городе, с указанным классом обслуживания.

В данном примере пользователем был выбран город Анталия и пятизвездочный отель. В результате расчета ему предоставилась сумма путевки, равная $8750.

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

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

При этом нужно также отметить, что стоимость путевки, полученная в результате работы пользовательской функции (рисунок 7.1) абсолютно аналогична стоимости путевки, полученной с помощью функции switch (рисунок 3.26) при расчете недельного отдыха в отелях Турции. Это подтверждает правильность написания пользовательской функции.

7.2 Функции переключения

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

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

HTML-код программы функции переключения представлен ниже.

<HTML>

    <HEAD>

    <TITLE>Пример использования функции переключения</TITLE>

    </HEAD>

    <BODY>

        <?php

            function read_counter($file_name)

            {

            $fp = fopen($file_name, "r");

            if(!$fp)

            echo "Невозможно открыть файл $counter_file.";

            $counter = (int) fread($fp, 20);

            fclose($fp);

            return $counter;

            }

            function save_counter($file_name, $counter)

            {

            $fp = fopen($file_name, "w");

            fwrite($fp, $counter);

            fclose($fp);

            }

            function display_counter($hit_counter)

            {

            switch ($hit_counter)

            {

            case $hit_counter <10:

            echo "<B>Количество посещений данной страницы небольшое!</B>";

            break;

            case $hit_counter <100:

            echo "<b>Количество посещений данной страницы среднее!</B>";

            break;

            case $hit_counter >1000:

            echo "<b>Количество посещений данной страницы большое!</b>";

            break; }

            }

            $counter_file = "count.txt";

            $hit_counter = read_counter($counter_file);

            $hit_counter++;

            display_counter($hit_counter);

            save_counter($counter_file, $hit_counter);

        ?>

    </BODY>

</HTML>

Пример реализации данного кода представлен на рисунке 7.2.


Рисунок 7.2 – Подсчет количества посещений страницы

Таким образом, как видно на рисунке 7.2, в данном примере с помощью функции переключения подсчитывалось количество посещений текущей Web-страницы. В результате было определено, что число посещений этой страницы небольшое.

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

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

7.3 Использование локальных и глобальных переменных

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

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

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

Фактически использование ключевого слова global перед именем переменной внутри функции создает ссылку на суперглобальный массив.

Ниже представлен пример работы с локальными и глобальными переменными.

<HTML>

    <HEAD>

    <TITLE>Пример использования локальных и глобальных

    переменных </TITLE>

    </HEAD>

    <BODY>

        <?php

            $global_message = "Глобальное сообщение";

            echo "Значение переменной за пределами пользовательской функции: " . $global_message . "<BR>";

            function addto_message()

            { $global_message = "Локальное сообщение";

            echo "Значение переменной в пределах пользовательской функции: " . $global_message . "<BR>";}

            addto_message(); echo "Значение переменной за пределами пользовательской функции: " . $global_message;

        ?>

    </BODY>

</HTML>

Реализация данного кода представлена на рисунке 7.3.


Рисунок 7.3 – Пример использования локальной и глобальной переменных в пользовательской функции

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

7.4 Создание статических переменных в функциях

В языке PHP также можно реализовать создание статических переменных. Такие переменные используются внутри функции с предшест-вующим ключевым словом “static”. Это слово позволяет переменной существовать после того, как функция завершила свою работу. Статическая переменная существует только в локальной области видимости функции. При этом переменная и ее последнее значение будут доступны и при следующем вызове данной функции.

Ниже представлен пример работы статистической переменной.

<HTML>

    <HEAD>

    <TITLE>Пример использования статической переменной</TITLE>

    </HEAD>

    <BODY>

        <?php

            function counter()

            {

            static $count;

            $count++;

            echo "<B>Значение переменной:</B> " . $count . "<BR>";

            }

            counter();

            counter();

            counter();

            counter();

            counter();

        ?>

    </BODY>

</HTML>

Реализация данного кода представлена на рисунке 7.4.


Рисунок 7.4 – Изменение значения статической переменной

Таким образом, как видно на рисунке 7.4, в данном примере создана пользовательская функция, в которой была объявлена статическая переменная. После этого при каждом вызове данной функции, в пределах выполнения одного PHP-сценария, значение переменной будет увеличиваться на единицу. В данном примере значение переменной было выведено пять раз.

7.5 Вложенность функций

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

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

Ниже представлен пример возникновения ошибок при работе с вложенными функциями.

<HTML>

    <HEAD>

    <TITLE>Пример использования вложенности функций </TITLE>

    </HEAD>

    <BODY>

        <?php

            function parent($first, $second)

            {

            function child($a, $b)

            { return $a * $b; }

            echo "$first * $second = ".child($first, $second)."<br >";

            }

            echo "<B>Первый вызов вложенной функции выполнится корректно и выведет на экран сообщение: </B> ";

            parent(2, 3);

            echo "<br><B>Второй вызов вложенной функции выдаст критическую ошибку</B><br>";

            parent(5, 5);

        ?>

    </BODY>

</HTML>

Реализация данного кода представлена на рисунке 7.5.


Рисунок.7.5 – Расчет произведения с помощью вызова вложенной функции

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

7.6 Рекурсия

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

Ниже приведен пример работы рекурсивной функции.

<HTML>

    <HEAD>

    <TITLE>Пример использования рекурсивного вызова функции

    </TITLE>

    </HEAD>

    <BODY>

        <?php

            if ($_POST['posted'])

            {

            $num = $_POST['num'];

            function recursion($num)

            {if ($num <= 1)

            {return 1;}

            else

            { return $num * recursion($num-1); }

            }

            echo "Факториал " .$num. " равен " .(recursion ($num)).”.”; }

        ?>

        <FORM method="POST" action="example.php">

        <input type="hidden" name="posted" value="true">

        Найти факториал числа:

        <input name="num" type="text">

        <BR>

        <input type="submit" value="Рассчитать факториал">

        </FORM>

    </BODY>

</HTML>

Реализация данного примера представлена на рисунке 7.6.


Рисунок 7.6 – Нахождение факториала

Таким образом, как видно на рисунке 7.6, в данном примере при загрузке Web-страницы на экране появляется однострочное текстовое поле, в которое пользователю необходимо ввести число, для которого требуется рассчитать факториал. После этого необходимо нажать кнопку “Рассчитать факториал”.

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