9.3. Область видимости (scope) в PHP
В РНР при использования переменных существуют отличия от C/C++. Дело в том, что переменная, определенная глобально, т. е. не в самой функции, а до ее реализации, не может быть использована в функции при условии, что она не определена как global (глобальная) переменная. Например:
<?php
$а = 1; /* глобальное определение переменной */
$b = 4;
Function sum () {
echo $b;
echo $a; /* ссылка на локальную переменную */
}
sum();
?>
После попытки выполнить этот пример, получим следующие ошибки:
1.Warning: Undefined variable: b in z:homelocalhostwwwtest.php on line 11
2.Warning: Undefined variable: a in z:homelocalhostwwwtest.php on line 12
Тут сказано о том, что переменные, которые используются в функции sum(), явно не определены. Здесь видны отличия РНР от C/C++. Чтобы в будущем не совершать такого рода ошибок, необходимо определять переменные в функциях перед их применением. Например:
<?php
$а=3 ;
$b=4;
Function sum() {
global $a,$b,$d;
$d=$a+$b;
}
sum();
echo $d;
echo $a;
echo $b;
?>
Результат выполнения программы представлен на рис. 9.1.
Рис. Р. Результат выполнения скрипта
Обратите внимание на строку global $а, $b, $d. В РНР для того чтобы использовать ранее определенные переменные, необходимо в самой функции их также определять как global. При этом значения, которые получили переменные в самой функции, в последующем использовании могут быть изменены. Например, если добавить в вышеописанную нами функцию строку $а++;, то результат выполнения программы будет следящий: $а=4, $b=4, $d=7. В дальнейшем нам придется оперировать с измененным значением
Существует еще один способ определения и последующего взаимодействия переменных в необходимой функции. Например:
$а = 1;
$b = 2;
Function Sum () {
$GLOBALS["b"] = $GLOBALS["а"] + $GLOBALS[ "b" ];
}
sum();
echo $b;
В данном случае является ассоциативным массивом.
ВНИМАНИЕ
Само имя массива должно быть постоянным, оно зависит даже от регистра.
Результат программы будет следующим. Браузер выведет сумму значений переменных $а и $b, программа произведет запись в переменную $b, значение которой станет отличной от первоначального задания.
Обратите внимание на то, что в РНР можно использовать статические переменные. Для наглядности приведем несколько примеров и опишем их.
Пример 9.1. Обычные переменные
<?php
Function nonestatic()
{
$а=0;
echo $а;
$а++;
}
nonestatic();
nonestatic{);
nonestatic();
?>
Результат выполнения программы представлен на рис. 9.2.
Рис. 9.2. Результат выполнения скрипта
Прежде чем мы опишем результат работы этой функции, скажем пару слов про операцию $а++. Она, как и в языке C++, позволяет прибавлять к значению переменной по единице. Если функция nonestatic() была вызвана 3 раза, то, соответственно, переменная примет значение, равное 3 (если, конечно, она была определена как $а=0). На основании такой операции постараемся объяснить принципы работы функции, в которой применяются переменные, определенные как статические (static). В данном случае переменная в функции не определена как статическая,
а ей просто присвоено значение, равное 0. В результате при выполнении программы получим, что значения переменной $а изменяться не будут. После выполнения функции echo $а; на экран будет выведено значение, равное 0, и так три раза подряд, т. е. «000». Вот что значит не использовать переменную как статическую.
Пример 9.2. Статические переменные
<?php
Function statics () {
static $а=0;
echo $а;
$а++;
}
statics();
statics();
statics();
?>
Результатом выполнения этого скрипта будет «012». Можно сделать вывод, что переменная $а после того, как ее обозначили статической, начала менять свои значения и при этом их сохранять. Это может значительно помочь при программировании циклов и рекурсий (явление, когда функция вызывает сама себя), факториалов и других математических функций.
Пример 9.3. Пример рекурсии
<?php
Function test () {
static $count = 0;
static $a=1;
$count++;
$a=$a*$count;
echo $count;
echo $a;
if ($count < 5) {
test();
} echo $a;
}
?>
Данный скрипт вычисляет факториал 5!. Выполнение этой программы основано на рекурсии, т. е. возможности вызова функцией самой себя.
ВНИМАНИЕ
При написании таких программ нужно всегда помнить: чтобы значения переменных сохранялись, при их изменении необходимо объявлять их как статические.
Опишем пример 9.3. В строке Function test() { задали функцию, ее имя и открыли фигурную скобкудля программирования внутренней части функции. Строки static $count = 0; static $а=1; необходимы для того, чтобы задать переменные с определенными значениями и при этом показать, что эти переменные будут статическими. Значения для переменных $count = 0 и $а=1 выбраны не случайно. Чтобы программа работала правильно, в нашем случае необходимо, чтобы переменная $count на начальном этапе была равна нулю, так как именно к ней будет прибавляться по единице, и ее значение будет проверяться на количество проделанных прибавлений в операторе условия if (см. п. 13.7). Равенство переменной $а=1 также взято не случайно. После оператора $count++; используется выражение $a=$a*$count;. Именно на его основании и происходит вычисление факториала. Если бы переменная была равна нулю, то и последующие значения также были бы равны нулю, что недопустимо. Далее идет оператор условия if, который проверяет, меньше переменная $count пяти или нет. Если меньше, происходит рекурсия, т. е. вызов функцией самой себя, и все идет заново. Если же набранное число превышает указанное значение в операторе условия if, то выполнение функции завершается. При этом в самом конце происходит выполнение операции $count--;, что приводит к возврату значения переменной к нулю. Результат был выведен раньше, поэтому выполнение программы завершается и результаты, полученные в ходе работы, выводятся на экран.