ресурс для начинающих веб-разработчиков
комплексные веб-услуги по созданию сайтов

Справочный материал по основным языкам программирования и верстки сайтов.

Готовая методика создания простых и сложных динамичных сайтов, с использованием PHP и MySQL.

Использование веб-редактора Adobe Dreamweaver в разработке сайтов.

Использование графических редакторов Adobe Flash, Adobe Photoshop, Adobe Fireworks в подготовке веб-графики.

Разработка веб-сайтов под "ключ".

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

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

Область действия функции

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

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

  • Переменные, которые объявлены внутри функции, действуют в области от оператора, в котором они объявлены до закрывающей скобки в конце функции. Эта область называется областью функции, а такие переменные — локальными переменными.
  • Переменные, которые объявлены вне функции, действуют в области от оператора, в котором они объявлены до конца файла, но не внутри функций. Эта область называется глобальной областью, а такие переменные — глобальными переменными.
  • Специальные суперглобальные переменные видны как внутри функции, так и за ее пределами.
  • Использование операторов require() и include() не влияет на область действия переменных. Если оператор используется внутри функции, применяется область функции. Если он используется не внутри функции, применяется глобальная область.
  • Ключевое слово global может использоваться для указания вручную того, что переменная, которая определена или используется внутри функции, будет иметь глобальную область действия.
  • Переменные могут быть вручную удалены при помощи функции unset($имя_переменной). Если переменная удалена, она больше не находится в области действия.

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

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

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);