Массив $GLOBALS
В принципе, есть и второй способ добраться до глобальных переменных. Это— использование встроенного в язык массива $GLOBALS. Последний представляет собой хэш, ключи которого есть имена глобальных переменных, а значения — их величины.
Этот массив доступен из любого места в программе — в том числе и из тела функции, и его не нужно никак дополнительно объявлять. Итак, приведенный выше пример можно переписать более лаконично:
// Âîçâðàùàåò íàçâàíèå ìåñÿöà ïî åãî íîìåðó. Íóìåðàöèÿ íà÷èíàåòñÿ ñ 1! function GetMonthName($n) { return $GLOBALS["Monthes"][$n]; }
Кстати, тут мы опять сталкиваемся с тем, что не только переменные, но даже и массивы могут иметь совершенно любую структуру, какой бы сложной она ни была. Например, предположим, что у нас в программе есть ассоциативный массив $A, элементы которого — двумерные массивы чисел. Тогда доступ к какой-нибудь ячейке этого массива с использованием $GLOBALS мог бы выглядеть так:
$GLOBALS["A"][First"][10][20];
То есть получился четырехмерный массив!
Насчет $GLOBALS следует добавить еще несколько полезных сведений. Во-первых, как я уже говорил, этот массив изначально является глобальным для любой функции, а также для самой программы. Так, вполне допустимо его использовать не только в теле функции, но также и в любом другом месте. Во-вторых, с этим массивом допустимы не все операции, разрешенные с обычными массивами. А именно, мы не можем:
r присвоить этот массив какой-либо переменной целиком, используя оператор =;
r как следствие, передать его функции "по значению" — можно передавать только по ссылке.
Однако остальные операции допустимы. Мы можем при желании, например, по одному перебрать у него все элементы и, скажем, вывести их значения на экран. И, наконец, третье: добавление нового элемента в $GLOBALS равнозначно созданию новой глобальной переменной (конечно, предваренной символом $ в начале имени, ведь в самом массиве ключи — это имена переменных без
символа доллара), а выполнение операции Unset() для него равносильно уничтожению соответствующей переменной.
А теперь я скажу нечто весьма интересное все о том же массиве $GLOBALS. Как вы думаете, какой элемент (то есть, глобальная переменная) всегда в нем присутствует? Это — элемент GLOBALS, "которая"
также является массивом, и в "которой"
также есть элемент GLOBALS... Так что же было первей — курица или яйцо (только не надо мне говорить, что первым был петух)?
А собственно, почему бы и нет? С чего это мы все привыкли, что в большом содержится малое, а не, скажем, наоборот? Почему множество не может содержать себя же в качестве элемента? Очень даже может, и $GLOBALS — тому наглядный пример.
В PHP версии 3 такая ситуация была чистой воды шаманством. Однако с появлением в четвертой версии PHP ссылок все вернулось на круги своя. На самом-то деле элемент с ключом GLOBALS
является не обычным массивом, а лишь ссылкой на $GLOBALS. Вот поэтому все и работает так, как было описано.
Вооружившись механизмом создания ссылок, мы можем теперь наглядно продемонстрировать, как работает инструкция global, а также заметить один ее интересный нюанс. Как мы знаем, global $a говорит о том, что переменная $a является глобальной, т. е., является синонимом глобальной $a. Синоним в терминах PHP — это ссылка. Выходит, что global создает ссылку? Да, никак не иначе. А вот как это воспринимается транслятором:
function Test()
{ global $a;
$a=10;
}
Приведенное описание функции Test() полностью эквивалентно следующему описанию:
function Test()
{ $a=&$GLOBALS[’a’];
$a=10;
}
Из второго фрагмента видно, что оператор Unset($a)
в теле функции не уничтожит глобальную переменную $a, а лишь "отвяжет" от нее ссылку $a. Точно то же самое происходит и в первом случае. Вот пример:
$a=100;
function Test()
{ global $a;
Unset($a);
}
Test();
echo $a; // выводит 100, т. е. настоящая $a не была удалена в Test()!
Эта особенность инструкции global появилась только в PHP версии 4, т. е. когда начали поддерживаться ссылки! Если вы запустите приведенный только что пример на PHP версии 3, то при исполнении echo увидите предупреждение: $a не определена. Помните это при переносе старых сценариев на новый PHP версии 4.
Как же нам удалить глобальную $a
из функции? Существует только один способ: использовать для этой цели $GLOBALS['a']. Вот как это делается:
function Test() { unset($GLOBALS['a']); }
$a=100;
Test();
echo $a; // Ошибка! Переменная $a не определена!