Значения по умолчанию

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

<?php
	//Функция, которая возвращает квадрат числа:
	function square($var)
	{
		$result = $var*$var;
		return $result;  //вернем значение переменной $result.
	}

	echo square(3); //выведет на экран '9'
?>

Сделаем так, чтобы в случае, если мы вызываем ее с пустыми круглыми скобками, она подставляла в переменную $var число 5:

<?php
	/*
		Функция, которая возвращает квадрат числа, 
		можно вызывать как с параметром, так и без!
	*/
	function square($var = 5) //по умолчанию параметр функции имеет значение 5
	{
		$result = $var*$var;
		return $result; //вернем значение переменной $result
	}

	echo square(); //мы не передали функции параметр и она выведет на экран 25 (5 в квадрате)
	echo square(3); //по-прежнему выводит 9!
?>

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

Можно задать для функции несколько параметров и части из них (или даже всем) назначить значение по умолчанию:

<?php
	/*
		Следующая функция принимает параметрами 3 слова и выводит их на экран
		(для тех, кто плохо владеет английским - word переводится как 'слово'):
	*/
	function words($word1, $word2, $word3)
	{
		echo $word1;
		echo $word2;
		echo $word3;
	}

	//Выведем с ее помощью фразу 'Привет, мир!':
	words('Привет, ', 'мир', '!');

	//Сделаем так, чтобы второй параметр по умолчанию был 'мир', а третий - '!':
	function words($word1, $word2 = 'мир', $word3 = '!')
	{
		echo $word1;
		echo $word2;
		echo $word3;
	}

	//И теперь вывести фразу 'Привет, мир!' с ее помощью будет проще:
	words('Привет, ');

	//Однако, такая конструкция тоже будет работать:
	words('Привет, ', 'мир', '!');

	//Выведем с помощью функции фразу 'Привет, Дима!':
	words('Привет, ', 'Дима'); //мы не передали третий параметр и по умолчанию возьмется '!'

	/*
		Опускать параметры можно только справа налево!!!
		В нашем случае - мы не можем опустить второй параметр, задав при этом третий!
	*/
?>

Область видимости

Изнутри наружу

В программировании существует такое понятие как область видимости переменной. Что оно обозначает? Оно обозначает те места кода, в которых переменная имеет то значение, которое мы ей присвоили. Возможно звучит не слишком понятно, поэтому посмотрите пример:

Определим внутри функции переменную $local. Выведем ее значение с помощью функции var_dump:

<?php
	function func()
	{
		$local = 'Тест!';
		var_dump($local); //выведет 'Тест!'
	}

	var_dump($local); 
	/*
		Выведет 'null'! 
		Это значит, что переменная $local видна только внутри функции!
	*/
?>

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

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

Снаружи вовнутрь

Та переменная, которую мы определили снаружи функции, не видна внутри функции. Смотрите пример:

<?php
	/*
		Определим ПЕРЕД функцией переменную $test,
		а затем попробуем вывести ее значение внутри функции:
	*/
	$test = 'Тест!';
	function func()
	{
		var_dump($test); //выведет 'null', так как внешняя переменная не видна внутри функции!
	}
	func(); //вызовем нашу функцию, чтобы проверить то, что она выводит
?>

Глобальные переменные

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

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

Для того, чтобы его понять, модифицируем предыдущий пример:

<?php
	/*
		Определим ПЕРЕД функцией переменную $test,
		а затем попробуем вывести ее значение внутри функции:
	*/
	$test = 'Тест!';
	function func()
	{
		/*
			Укажем PHP то, что мы хотим взять глобальную переменную $test
			с помощью инструкции global:
		*/
		global $test; 
		var_dump($test); //выведет 'Тест!', так как теперь внешняя переменная видна внутри функции!
	}
	func(); //вызовем нашу функцию, чтобы проверить то, что она выводит
?>

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

Совет: если необходимо сделать глобальными сразу несколько переменных, их можно написать через запятую после слова global: global $a, $b, $c;

Не стоит злоупотреблять глобальными переменными. Используйте их там, где это действительно необходимо.

Если изменить глобальную переменную в функции - то она поменяется и за пределами этой функции.

Static переменные

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

<?php
	//Создадим простую функцию:
	function func()
	{
		/*
			Изначально $a не определена и PHP может ругаться на это, 
			но после выполнения операции ++, в нее запишется единица.
		*/
		$a++; 
		echo $a;
	}
	func(); //выведется 1
	func(); //опять выведется 1
	func(); //и опять...
	/*
		Это говорит о том, что каждый раз при новом вызове функции 
		переменная $a имеет значение null!
	*/
?>

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

Чтобы объявить такую переменную, перед ней следует написать инструкцию static. Модифицируем наш пример:

<?php
	//Создадим простую функцию:
	function func()
	{
		/*
			Укажем PHP, что мы хотим, чтобы $a была статической переменной:
		*/
		static $a;

		$a++;
		echo $a;
	}

	func(); //выведется 1
	func(); //выведется 2!
	func(); //выведется 3!!

	/*
		Это говорит о том, что каждый раз при новом вызове функции
		к переменной $a прибавляется единица.
	*/
?>

Тонкий момент с параметрами

Тонкий момент с параметрами смотрите на следующем примере:

<?php
	//Функция, которая возвращает квадрат числа:
	function kvadrat($var)
	{
		return $var*$var;
	}

	$test = 2; //глобальная переменная $test, присваиваем ей значение 2

	echo kvadrat($test); //вызовем нашу функцию, передав ей параметром переменную $test

	/*
		Функция выведет 4.
	*/
?>

Тонкий момент такой: первым параметром мы передали ей переменную $test (имеет значение 2), но при определении функции мы ввели на это место переменную $var: function kvadrat($var).

Внутри функции не появится никакой локальной переменной $test. А будет локальная переменная $var, которая будет иметь то значение, которое имела переменная $test. То есть 2.

Рекурсия

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

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

Для этого мы будем использовать функцию array_pop, которая забирает из массива последний элемент (массив при этом уменьшается). Затем будем проверять, осталось ли что в массиве с помощью empty.

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

<?php
	$arr = [1, 2, 3, 4, 5];

	last($arr);

	function last($arr)
	{
		echo array_pop($arr).'<br>'; //выводим последний элемент массива
    
		if(!empty($arr)) {
			last($arr); //это рекурсия
		}
	}
?>

Дан многомерный массив произвольного уровня вложенности. Выведите всего его элементы на экран.

...