Область действия функции. Передача функции. Возврат функции

Возможно, вы обратили внимание, что при необходимости использования переменных внутри требуемого или включенного файла мы просто объявляем их в сценарии перед оператором require() или include(), но при использовании функции мы явно передаем эти переменные в функцию. Частично это связано с тем, что не существует никакого механизма для явной передачи переменных в требуемый или включенный файл, а частично с тем, что область действия переменных для функций определяется иначе.

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

Приведенные далее примеры помогут разобраться с данными выше определениями.

Следующий код не создает никакого вывода. В нем объявляется переменная $var внутри функции fh(). Поскольку эта функция объявляется внутри функции, она имеет область действия функции и существует от места ее объявления до конца функции. При новом обращении к $var вне функции, создается новая переменная $var. Эта новая переменная имеет глобальную область действия и будет видима до конца файла. К сожалению, если единственный оператор, используемый с этой новой переменной $var — echo, она никогда не будет иметь значения.

function fn()
{
$var = "значение";
}
fn ();
echo $var ;

В окне веб-браузера это будет выглядеть ТАК.

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

function fn()
{
echo "внутри функции, \$var = ".$var."<br>";
$var = "значение 2";
echo "внутри функции, \$var = ".$var."<br>";
}
$var = "значение 1";
fn();
echo "вне функции, \$var = ".$var."<br>";

В окне веб-браузера это будет выглядеть ТАК.

Функции не выполняются до тех пор, пока они не будут вызваны, поэтому первым выполняемым оператором является $var = "значение 1"; Он создает переменную $var, имеющую глобальную область действия и содержимое "значение 1". Следующий выполняемый оператор — обращение к функции fh(). Строки внутри оператора выполняются по очереди. Первая строка в функции обращается к переменной $var. Когда эта строка выполняется, она не может видеть предшествующую созданную нами переменную $var, поэтому она создает новую переменную, имеющую область функции, и повторяет ее в выводе. В результате создается первая строка вывода.

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

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

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

function fn ()
{
global $var;
$var = "значение";
echo "внутри функции, \$var = ".$var."<br>";
}
fn () ;
echo "вне функции, \$var = ".$var."<br>";

В окне веб-браузера это будет выглядеть ТАК.

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

Обратите внимание, что переменная определена в области, начиная с того места, где выполняется строка global $var;. Функцию можно было бы объявить выше или ниже того места, где она вызывается. (Обратите внимание, что область действия функции значительно отличается от области действия переменной!). Место объявления функции не существенно — важно лишь то, где мы вызываем функцию и, сле довательно, выполняем содержащийся внутри нее код.

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

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

Передача функции по ссылке и передача по значению

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

function increment ($value, $amount = 1)
{
$value = $value + $amount;
}
$value = 10;
increment ($value);
echo $value;

В окне веб-браузера это будет выглядеть ТАК.

Как видим содержимое $value не изменилось.

Такой результат есть следствие правил, регламентирующих область действия. Этот код создает переменную $value, которая содержит значение 10. Затем программа вызывает функцию increment(). Переменная $value создается в функции при ее вызове. К значению добавляется 1, поэтому внутри функции значение $value равно 11 до тех пор, пока выполнение функции не завершается и не осуществляется возврат к вызвавшему ее коду. В этом коде переменной $value является другая переменная, определенная в глобальной области, и поэтому она остается неизменной.

Один из способов решения этой проблемы — объявление переменной $value в функции в качестве глобальной, но это означает, что для использования этой функции переменную, значение которой требуется увеличить, потребовалось бы назвать $value. Более рациональным подходом было бы использование передачи по ссылке.

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

Более рациональный подход — использование передачи по ссылке. В этом случае при передаче параметра, вместо того чтобы создавать новое значение, функция принимает ссылку на исходную переменную. Эта ссылка имеет имя переменной, начинающееся со знака доллара ($), и может использоваться совершенно так же, как любая другая переменная. Различие состоит в том, что вместо того, чтобы иметь собственное значение, она просто ссылается на исходную переменную. Любые изменения, применяемые к ссылке, влияют также и на оригинал.

Передача используемого параметра по ссылке указывается путем помещения символа амперсанда (&) перед его именем в определении функции. Никакие изменения в вызове функции не требуются.

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

function increment (&$value, $amount = 1)
{
$value = $value + $amount;
}
$a = 10;
echo $a. '<br>';
increment ($a);
echo $a.'<br>';

В окне веб-браузера это будет выглядеть ТАК.

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

Возврат из функции

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

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

function test_return()
{
echo 'Этот опереатор будет выполнен';
return;
echo 'Этот оператор никогда не будет выполнен';
}
test_return();

В окне веб-браузера это будет выглядеть ТАК.

Очевидно, это не очень полезный способ использования оператора return. Обычно возврат из функции будет требоваться только при выполнении определенного условия.

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

function larger($x, $y)
{
if (!isset($x)||!isset($y))
{
echo 'Эта функция требует указания двух чисел';
return;
}
if ($x >= $y)
echo $x;
else
echo $y;
echo '<br>';
}
larger($x, $y);

В окне веб-браузера это будет выглядеть ТАК.

Встроенная функция isset() сообщает, была ли создана переменная и было ли ей присвоено значение. Этот код должен генерировать сообщение об ошибке и выполнять возврат, если любой из параметров не имеет установленного значения. Эта проверка выполняется с помощью выражения !isset(), означающего "НЕ isset()", и следователь но, оператор if можно прочесть как "если значение х не установлено или значение у не установлено". Функция будет выполнять возврат, если любое из этих условий истинно.

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

Выводом следующего кода:

function larger($x, $y)
{
if (!isset($x)||!isset($y))
{
echo 'Эта функция требует указания двух чисел';
return;
}
if ($x >= $y)
echo $x;
else
echo $y;
echo '<br>';
}
$a = 1;
$b = 2.5;
$c = 1.8;
larger($a, $b);
larger($c, $f);
larger($b, $a);
larger($x, $y);

В окне веб-браузера это будет выглядеть ТАК.

назадвверхвперед
Rambler's Top100