| PHP Ръководство | ||
|---|---|---|
| Предишна страница | Глава 12. Променливи | Следваща страница |
Обхватът (scope) на променлива е контекстът, в който тя е дефинирана. На повечето места променливите в PHP имат само един обхват. Този единствен обхват се разпростира също и във включените и в изискваните файлове. Например:
Тук променливата $a ще бъде налична във включения
скрипт b.inc. В рамките на потребителски-дефинирани
функции, обаче, се въвежда локален обхват. Всяка променлива, използвана
вътре във функция, по подразбиране е ограничена в локалния обхват на функцията.
Например:
<?php
$a = 1; /* глобален обхват */
function Test()
{
echo $a; /* референция към променлива от локалния обхват */
}
Test();
?> |
Този скрипт няма да изведе нищо, защото изразът echo се отнася за
локална версия на променливата $a, а тя няма присвоена
стойност в този обхват. Вероятно забелязвате, че това е малко по-различно
от езика C с това, че в C променливите са налични автоматично във функциите,
освен ако не са отменени от локална дефиниция. Това може да създаде проблеми,
тъй като човек може по невнимание да промени глобална променлива.
В PHP глобалните променливи трябва да бъдат декларирани като глобални вътре в дадена
функция ако ще бъдат използвани в тази функция.
Първо, примерна употреба на global:
Горният скрипт ще изведе "3". Декларирайки
$a и $b като глобални за функцията,
всички референции към променливите ще сочат към глобалната версия.
Няма ограничение в броя на глобалните променливи, които могат да бъдат
манипулирани от функция.
Вторият начин за достъп до променливи от глобалния обхват е да се използва
специалния PHP-дефиниран $GLOBALS масив. Предният пример
може да бъде пренаписан така:
Масивът $GLOBALS е асоциативен масив, в който името на глобалната променлива
е ключът, а съдържанието на тази променлива е стойността на елемента от масива.
Забележете че $GLOBALS е наличен във всеки обхват, това е така, защото
$GLOBALS е суперглобален.
Ето пример, демонстриращ възможностите на суперглобалните:
Друга важна особеност на обхвата на променливите е статичната променлива. Статичната променлива съществува единствено в локалния обхват на функция, но не губи стойността си, когато изпълнението на програмата напусне този обхват. Разгледайте следния пример:
Тази функция е напълно безполезна, тъй като всеки път, когато бива извикана,
тя установява $a в 0 и отпечатва
"0". Изразът $a++ , който инкрементира променливата,
е безсмислен, понеже в момента, в който функцията излезе, променливата
$a изчезва. За да направим полезна брояща функция, която
да не губи представа за текущата сума, променливата $a
е дефинирана като статична:
Сега, всеки път, когато се извика функцията Test(), тя ще отпечата стойността на
$a и ще я инкрементира.
Статичните променливи предоставят също и начин за работа с рекурсивни
функции. Рекурсивна функция е такава, която извиква сама себе си. Трябва
да се внимава при писане на рекурсивна функция, защото е възможно да бъде
принудена да се самоизвиква до безкрайност. Трябва да се уверите, че
имате подходящ начин за спиране на рекурсията. Следната проста функция
брои рекурсивно до 10, използвайки статичната променлива
$count, за да разбере кога да спре:
Забележка: Статичните променливи могат да бъдат декларирани, както в примерите по-горе. Опитът да се присвоят стойности на тези променливи, които са резултат от изрази, ще причини грешка в разбора (parse error).
Zend Engine 1, управляваща PHP 4, осъществява static и global модификаторите за променливи от гледна точка на референции. Например, истинска глобална променлива, внесена в обхвата на функция посредством израза global, в действителност създава референция към глобалната променлива. Това може да доведе до неочаквано поведение, за което се отнася и следващия пример:
<?php
function test_global_ref() {
global $obj;
$obj = &new stdclass;
}
function test_global_noref() {
global $obj;
$obj = new stdclass;
}
test_global_ref();
var_dump($obj);
test_global_noref();
var_dump($obj);
?> |
Изпълнението на този пример ще изведе следното:
NULL
object(stdClass)(0) {
} |
Подобно поведение е в сила и за израза static. Референциите не се пазят статично:
<?php
function &get_instance_ref() {
static $obj;
echo 'Static object: ';
var_dump($obj);
if (!isset($obj)) {
// Присвояване на референция на статичната променлива
$obj = &new stdclass;
}
$obj->property++;
return $obj;
}
function &get_instance_noref() {
static $obj;
echo 'Static object: ';
var_dump($obj);
if (!isset($obj)) {
// Присвояване на обект на статичната променлива
$obj = new stdclass;
}
$obj->property++;
return $obj;
}
$obj1 = get_instance_ref();
$still_obj1 = get_instance_ref();
echo "\n";
$obj2 = get_instance_noref();
$still_obj2 = get_instance_noref();
?> |
Изпълнението на този пример ще изведе следното:
Static object: NULL
Static object: NULL
Static object: NULL
Static object: object(stdClass)(1) {
["property"]=>
int(1)
} |
Този пример показва, че когато присвоявате референция на статична променлива, тя не се помни, когато извикате функцията &get_instance_ref() втори път.
| Предишна страница | Начало | Следваща страница |
| Предефинирани променливи | Начало на раздела | Променливи променливи |