ООП   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 - визуальные среды

Знаете ли Вы, что cогласно релятивистской мифологии "гравитационное линзирование - это физическое явление, связанное с отклонением лучей света в поле тяжести. Гравитационные линзы обясняют образование кратных изображений одного и того же астрономического объекта (квазаров, галактик), когда на луч зрения от источника к наблюдателю попадает другая галактика или скопление галактик (собственно линза). В некоторых изображениях происходит усиление яркости оригинального источника." (Релятивисты приводят примеры искажения изображений галактик в качестве подтверждения ОТО - воздействия гравитации на свет)
При этом они забывают, что поле действия эффекта ОТО - это малые углы вблизи поверхности звезд, где на самом деле этот эффект не наблюдается (затменные двойные). Разница в шкалах явлений реального искажения изображений галактик и мифического отклонения вблизи звезд - 1011 раз. Приведу аналогию. Можно говорить о воздействии поверхностного натяжения на форму капель, но нельзя серьезно говорить о силе поверхностного натяжения, как о причине океанских приливов.
Эфирная физика находит ответ на наблюдаемое явление искажения изображений галактик. Это результат нагрева эфира вблизи галактик, изменения его плотности и, следовательно, изменения скорости света на галактических расстояниях вследствие преломления света в эфире различной плотности. Подтверждением термической природы искажения изображений галактик является прямая связь этого искажения с радиоизлучением пространства, то есть эфира в этом месте, смещение спектра CMB (космическое микроволновое излучение) в данном направлении в высокочастотную область. Подробнее читайте в FAQ по эфирной физике.

НОВОСТИ ФОРУМАФорум Рыцари теории эфира
Рыцари теории эфира
 27.02.2020 - 05:11: ЭКОНОМИКА И ФИНАНСЫ - Economy and Finances -> ПРОБЛЕМА КРИМИНАЛИЗАЦИИ ЭКОНОМИКИ - Карим_Хайдаров.
27.02.2020 - 05:09: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Ю.Ю. Болдырева - Карим_Хайдаров.
27.02.2020 - 05:08: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Андрея Пешехонова - Карим_Хайдаров.
26.02.2020 - 06:25: ЭКОНОМИКА И ФИНАНСЫ - Economy and Finances -> КОЛЛАПС МИРОВОЙ ФИНАНСОВОЙ СИСТЕМЫ - Карим_Хайдаров.
23.02.2020 - 19:17: ВОЙНА, ПОЛИТИКА И НАУКА - War, Politics and Science -> Проблема государственного терроризма - Карим_Хайдаров.
23.02.2020 - 19:14: ПЕРСОНАЛИИ - Personalias -> WHO IS WHO - КТО ЕСТЬ КТО - Карим_Хайдаров.
19.02.2020 - 18:24: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Андрея Фурсова - Карим_Хайдаров.
17.02.2020 - 19:50: ЭКСПЕРИМЕНТАЛЬНАЯ ФИЗИКА - Experimental Physics -> Эксперименты Сёрла и его последователей с магнитами - Карим_Хайдаров.
17.02.2020 - 19:49: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Андрея Тиртхи - Карим_Хайдаров.
17.02.2020 - 19:09: ЭКСПЕРИМЕНТАЛЬНАЯ ФИЗИКА - Experimental Physics -> Вихревые эффекты и вихревые теплогенераторы - Карим_Хайдаров.
17.02.2020 - 19:06: ЭКСПЕРИМЕНТАЛЬНАЯ ФИЗИКА - Experimental Physics -> Эксперименты Андрея Петровича Хрищановича - Карим_Хайдаров.
17.02.2020 - 18:48: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> КОМПЬЮТЕРНО-СЕТЕВАЯ БЕЗОПАСНОСТЬ ДЛЯ ВСЕХ - Карим_Хайдаров.
Bourabai Research Institution home page

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