ООП   PHP   web   4GL - визуальные среды

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

Продолжаем изучать PHP и сегодня давайте поговорим о функциях в PHP. Сам PHP имеет очень много встроенных функций. Их очень много, порядка нескольких тысяч. С помощью них решаются, практически, 99% всех поставленных задач. Однако, для того, чтобы понять как устроены функции PHP и вообще понять их суть, нам необходимо научиться самим писать собственные функции. Вообще уметь писать собственные функции нужно не только для того, что понять как работают встроенные, а еще и для того, чтобы наш код, который мы пишем, мог выполняться не один раз. Что я имею ввиду?

Допустим у нас есть самый простой и банальный код, которые складывает числа:

<?php
$num1 = 2;
$num2 = 2;
echo $num1 + $num2;
?>

Здесь все очень просто, этот код отработает в программе там, где мы его напишем. Однако, бывают ситуации и довольно часто, что нам нужно, чтобы этот код отработал несколько раз. К примеру, у нас есть программа, которая состоит из 100 строк кода. Я хочу, чтобы код, который суммирует числа отработал три раза — в начале программы, в середине и в конце. Все вроде бы просто — я три раза пишу этот код в трех разных частях программы. А что если этот код, складывающий два числа, будет состоять не из трех строк а из 33 и при этом мне нужно каждый раз новые числа складывать. Получается, что моя программа увеличивается в размерах, плюс я дублирую один и тот же код, а мне бы этого не хотелось, да и не делает так ни кто.

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

То есть функция в PHP — это кусок кода, который выполняется только тогда, когда его попросят.

У функции есть описание и вызов. Как же описывается функция?

Она описывается очень просто: ключевое слово function, затем имя функции (имена функции регистронезависимые), далее круглые и фигурные скобки.

Вот функция, которая суммирует числа:

<?php
function sum(){
	echo 2+2;
}
?>

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

<?php
// Создаем функцию
function sum(){
	echo 2+2;
}
// Вызываем функцию целых три раза
sum();
sum();
sum();
?>

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

В PHP нет понятия перегрузки функции. То есть мы не можем объявить функцию два раза:

<?php
function sum(){}
function sum(){}
// Так будет ошибка!
?>

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

Для этого существует проверка на наличие функций.

С помощью функции function_exists(имя_функции) мы можем проверить существует ли такая функция, которую мы пишем, или нет. Если такая функция существует, возвращается true, если не существует, возвращается false:

<?php
function sum(){
	echo 2+2;
}
if(!function_exists('sum')){
	function sum(){
		echo 2+2;
	}
}else{
	echo "Такая функция уже есть!";
}
// Выведется, что такая функция уже есть!
?>

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

<?php
function sum($num1, $num2){
	echo $num1 + $num2;
}
sum(5,5);
// Выведется 10
?>

Я могу передать параметры в виде переменных:

<?php
$one = 5;
$two = 5;
function sum($num1, $num2){
	echo $num1 + $num2;
}
sum($one, $two);
// Выведется 10
?>

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

<?php
$one = 5;
$two = 5;
function sum($num1, $num2){
	echo $num1 + $num2;
}
sum(здесь не передаем параметры);
// Выведется ошибка!
?>

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

Пример: я хочу с помощью функции вывести фразы Hello Mike, Hello John, Hello Zack:

<?php
function hello($name, $h){
	echo "<h$h>Hello, $name!</h$h>";
}
// Далее мы вызываем функцию три раза с разными параметрами
hello('Mike', 1);
hello('Jonh', 2);
hello('Zack', 3);
?>

У нас выводятся три приветствия с разными уровнями заголовков от h1 до h3.

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

Например:

<?php
function hello($name = 'Mike', $h = 1){
	echo "<h$h>Hello, $name!</h$h>";
}
hello(); // Функция без параметров, тогда они подставляются по умолчанию
hello('Jonh', 2);
hello('Zack', 3);
?>

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

Обратите внимание на одну тонкость, это очень важно:

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

Следующий код будет не корректен:

<?php
function hello($name = 'Mike', $h){
	echo "<h$h>Hello, $name!</h$h>";
}
// Код не корректен
?>

Здесь при вызове функции я уже не могу пропустить первый параметр, а он у нас не обязательный, то есть, я не могу записать вызов функции так:

<?php
hello( , 1); // Ошибка
?>

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

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

<?php
function hello($name, $h){
	echo "<h$h>Hello, $name!</h$h>";
}
$str = 'hello'; // Значение в переменной - строка совпадает с именем функции
$str('Mike', 1); // Выводим функцию через переменную
?>

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

Помните в статье цикл while в PHP мы с вами делали таблицу умножения. Давайте теперь попробуем код таблицы умножения сделать в виде функции PHP:

<?php
function getTable($cols = 10 , $rows = 10, $color = 'yello'){
	echo "<table border='1' align='center'>";
	for($tr = 1; $tr <= $rows; $tr++){
		echo "<tr>";
		for($td = 1; $td <= $cols; $td++){
		if($tr == 1 or $td == 1){
	            echo "<th style='background: $color'>".$tr * $td."</th>";
	        }else{
	            echo "<td>".$tr * $td."</td>";
	        }
	    }
	    echo "</tr>";
	}
	echo "</table>";
}
// Выводим три таблицы с разными параметрами и четвертая без параметров
getTable(3,3,'red');
getTable(4,4, 'blue');
getTable(5,5, 'green');
getTable();
?> 

Давайте разбираться дальше. Посмотрите на этот код и скажите, что выведется в строке номер 9:

<?php
function hello($name){
	echo "Hello, $name!";
	$name = 'Vasya';
}
hello('Zack');
$name = 'Mike';
hello($name);
echo $name; // Что здесь выведется
?>

Правильный ответ Mike. Почему? Да потому что переменная, которая находится внутри тела функции и переменная, которая за ее пределами — это разные переменные.

В программировании есть такое понятие, как «области видимости» — глобальная и локальная. Локальная — эта та переменная, которая находится внутри функции PHP и она не доступна из вне.

Мы можем объявить переменную внутри функции, но вызвать ее или обратиться к ней не из функции — не можем.

Глобальная область видимости — это те переменные, которые объявляются вне функций PHP и они доступны из любой части программного кода.

Но проблема в том, что нам все таки нужно как-то обратиться к локальной переменной внутри функции. Что делать? Есть вариант:

Объявить переменную внутри функции с помощью ключевого слова global.

<?php
function hello($name){
	echo "Hello, $name!";
	global $name;
	$name = 'Vasya';
}
hello('Zack');
$name = 'Mike';
hello($name);
echo $name; // Здесь уже будет Vasya
?>

Однако, у global есть некоторые недостатки. Когда мы объявляем переменную с помощью global, мы лишаемся вот этой локальности. Потом, функции могут быть достаточно длинными, хотя это не правильно. Если у вас функция вылезает за пределы экрана, то, есть повод задуматься, что что-то не так. Ну да ладно, однако, если у вас такая функция, то объявив вначале переменную глобальной, то внизу этой функции мы не узнаем глобальная ли эта переменная или нет, ну забыли мы или кто-то другой пролистал вашу функцию и не увидел или также забыл, что вначале она объявлялась глобальной. Из-за этого могут возникнуть проблемы. Поэтому можно, например, объявлять переменные глобальными там, где они используются в функции, а не в начале, то есть я, например решил в середине функции поработать с глобальными переменными и я сразу же в середине объявляю ее глобальной.

Есть еще один вариант объявления переменных глобальными. Но прежде, чем разобрать этот вариант, нужно немного понять как устроен PHP. Смотрите, когда мы объявляем переменную PHP и присваиваем ей значение, мы делаем так: $age = 25. Что при этом делает PHP у себя внутри? У PHP внутри есть массив GLOBALS. Так вот, когда мы присваиваем переменной значение, PHP выделяет в массиве GLOBALS ячейку памяти под названием, совпадающей с названием нашей переменной: $GLOBALS['age'] = 25. Теперь мы в функции можем сделать так:

 <?php
function hello($name){
	echo "Hello, $name!";
	$GLOBALS['name'] = 'Vasya';
}
hello('Zack');
$name = 'Mike';
hello($name);
echo $name; // Здесь уже будет Vasya
?>

Давайте теперь поговорим вот о чем! Когда мы создаем функции, они в принципе должны что-то возвращать. Например, мы создали какую-нибудь функцию, она отработала и должна возвратить результат своей работы. До сего момента мы сами писали в теле функции, например, вывод какого-то результата. Однако, бывает нужно, чтобы функция сама вернула результат, а мы уже потом решили, что с ним делать. Смотрите, что я имею ввиду: мы создаем функцию, например, getNumberSum($numb1, $numb2), которая производит арифметические действия с числами, к примеру складывает их. Внутри этой функции мы производим вычисления. Но я не знаю, хочу ли я, вывести результат вычисления сразу в браузер или использовать этот результат в другом месте.

<?php
function getNumberSum($numb1, $numb2){
	$result = $numb1 + $numb2;
}
?>

В этом случае я могу просто вернуть результат, а дальше уже думать, что с ним делать. Возвращается он с помощью оператора return:

<?php
function getNumberSum($numb1, $numb2){
	$result = $numb1 + $numb2;
	return $result;
}
?>

Теперь я присвою результат отработанной функции переменной $res = getNumberSum(2,3) и потом выведу эту переменную:

<?php
function getNumberSum($numb1, $numb2){
	$result = $numb1 + $numb2;
	return $result;
}
$res = getNumberSum(2,3);
echo $res;
?>

Я могу сделать еще проще: просто вывести в браузер то, что вернула мне функция:

<?php
function getNumberSum($numb1, $numb2){
	return $numb1 + $numb2;
}
echo getNumberSum(2,3);
?>

Смотрите, если у меня после return будет идти еще какой-то код, то он никогда не выполнится, так как return работает еще и как break:

<?php
function getNumberSum($numb1, $numb2){
	return $number1 + $number2;
	/*
	Далее идет какой-то код 
	*/
	/*
	Но он никогда не выполнится
	*/
	
}
echo getNumberSum(2,3);
?>

Помните, мы с вами писали код меню в статье цикл FOREACH в PHP. Давайте теперь это меню опишем с помощью функции PHP.

Наша функция будет принимать помимо параметра меню ($menu) еще один параметр под названием $vertical, по умолчанию он будет true, то есть меню будет отрисовываться либо вертикально (true), либо горизонтально (false).

Вот решение нашей задачи:

<?php
//Массив с меню вынесем за пределы функции
$menu = array(
	"Home" => 'index.php',
	"About" => 'about.php',
	"Contact" => 'contact.php',
	"Search" => 'search.php'
);
//Создаем функцию
function menu($menu, $vertical = true){
	$style='';//Стиль для горизонтального меню, если его нет, значит нет
	if(!$vertical)//Проверяем второй парметр, если он false, применяем стиль
		$style=' style="display: inline; margin-right: 15px"';
	echo '<ul style="list-style-type: none">';
	foreach($menu as $link=>$href){
	echo "<li$style><a href='$href'>$link</a></li>";//Здесь переменная со стилем $style для динамического изменения меню
	}
	echo '</ul>';
}
menu($menu, false);//Выводим наше меню, если второй параметр false, рисуется горизонтальное меню, если его убрать, рисуется вертикальное меню
?>

Евгений Владимирович Андреев

ООП   PHP   web   4GL - визуальные среды

Знаете ли Вы, что в 1974 - 1980 годах профессор Стефан Маринов из г. Грац, Австрия, проделал серию экспериментов, в которых показал, что Земля движется по отношению к некоторой космической системе отсчета со скоростью 360±30 км/с, которая явно имеет какой-то абсолютный статус. Естественно, ему не давали нигде выступать и он вынужден был начать выпуск своего научного журнала "Deutsche Physik", где объяснял открытое им явление. Подробнее читайте в FAQ по эфирной физике.

НОВОСТИ ФОРУМАФорум Рыцари теории эфира
Рыцари теории эфира
 14.10.2019 - 19:26: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Вячеслава Осиевского - Карим_Хайдаров.
14.10.2019 - 03:09: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Марины Мелиховой - Карим_Хайдаров.
13.10.2019 - 18:09: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Светланы Вислобоковой - Карим_Хайдаров.
13.10.2019 - 08:05: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Декларация Академической Свободы - Карим_Хайдаров.
13.10.2019 - 08:03: ЭКОЛОГИЯ - Ecology -> Биохимия мозга от проф. С.В. Савельева и не только - Карим_Хайдаров.
12.10.2019 - 07:03: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Константина Сёмина - Карим_Хайдаров.
11.10.2019 - 08:59: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от О.Н. Четвериковой - Карим_Хайдаров.
11.10.2019 - 06:24: ВОЙНА, ПОЛИТИКА И НАУКА - War, Politics and Science -> Проблема государственного терроризма - Карим_Хайдаров.
11.10.2019 - 03:57: ВОЙНА, ПОЛИТИКА И НАУКА - War, Politics and Science -> ЗА НАМИ БЛЮДЯТ - Карим_Хайдаров.
11.10.2019 - 03:33: ЭКОЛОГИЯ - Ecology -> ЭКОЛОГИЯ ДЛЯ ВСЕХ - Карим_Хайдаров.
11.10.2019 - 03:22: ЭКОЛОГИЯ - Ecology -> Глобальное потепление - миф или... миф? - Карим_Хайдаров.
09.10.2019 - 19:01: ТЕОРЕТИЗИРОВАНИЕ И МАТЕМАТИЧЕСКОЕ МОДЕЛИРОВАНИЕ - Theorizing and Mathematical Design -> ФУТУРОЛОГИЯ - прогнозы на будущее - Карим_Хайдаров.
Bourabai Research Institution home page

Bourabai Research - Технологии XXI века Bourabai Research Institution