Променлив обхват
Обхватът на променливата е средата, в която е дефинирана. В повечето случаи всички PHP променливи имат еднакъв обхват. Този единичен обхват също така обхваща включени и необходими файлове. Например:
Тук променливата $a ще бъде налична във включения скрипт b.inc. Въпреки това, в дефинираните от потребителя функции се въвежда обхват на локална функция. Всяка променлива, използвана във функция, по подразбиране е ограничена до локалния обхват на функцията. Например:
Този скрипт няма да генерира никакви изходни данни, защото операторът echo сочи към локалната версия на $a и не му е присвоена стойност в този обхват. Може би сте забелязали, че това е малко по-различно от езика C, тъй като глобалните променливи в C са автоматично достъпни за функции, освен ако не са били презаписани от локална дефиниция. Това може да причини някои проблеми, защото хората могат неволно да променят глобална променлива. В PHP, ако трябва да се използва глобална променлива във функция, тя трябва да бъде декларирана като глобална в нея.
Първо пример с използване на global:
Пример 12-1. Използване на глобален
функция Sum () глобално $a, $b;
Sum(); ехо $b; ?>
Горният скрипт ще изведе "3". След дефиниране на $a и $b като глобални във функцията, всички препратки към някоя от тези променливи ще сочат към тяхната глобална версия. Няма ограничение за броя на глобалните променливи, които могат да бъдат обработени от функция.
Вторият начин за достъп до променливи с глобален обхват е да използвате специалния масив $GLOBALS, дефиниран от PHP. Предишният пример може да се пренапише така:
Пример 12-2. Използване на $GLOBALS вместо global
функция Sum () $GLOBALS [ "b" ] = $GLOBALS [ "a" ] + $GLOBALS [ "b" ]; >
Sum(); ехо $b; ?>
$GLOBALS е асоциативен масив, чийто ключ е името и чиято стойност е съдържанието на глобалната променлива. Обърнете внимание, че $GLOBALS съществува във всеки обхват, това е така, защото този масив е суперглобален. Следва пример, демонстриращ възможностите на суперглобалите:
Пример 12-3. Суперглобали и обхват
функция test_global () // Повечето предварително дефинирани променливи не са // "super" и изискват 'global' да бъде посочено, за да бъде достъпно в локалния обхват на функцията //. глобален $HTTP_POST_VARS; |
ехо $HTTP_POST_VARS [ 'име'];
// Суперглобалните са налични във всеки // обхват и не изискват 'глобален'. // Суперглобалните са налични от PHP 4.1.0 echo $_POST [ 'име']; > ?>
Друга важна характеристика на обхвата на променливата е статичната променлива. Статичната променлива съществува само в локалния обхват на функцията, но не губи стойността си, когато изпълнението на програмата излезе от този обхват. Разгледайте следния пример:
Пример 12-4. Демонстриране на необходимостта от статични променливи
функция Test() $a = 0 ; ехо $a ; $a++; > ?> |
Тази функция е напълно безполезна, защото всеки път, когато бъде извикана, задава $a на 0 и отпечатва "0". Увеличаването на променливата $a ++ тук не играе роля, тъй като променливата $a изчезва, когато функцията излезе. да пиша полезнофункция за отчитане, която няма да загуби текущата стойност на брояча, променливата $a се декларира като статична:
Пример 12-5. Пример за използване на статични променливи
функция Test() static $a = 0; ехо $a ; $a++; > ?> |
Сега, всеки път, когато се извика функцията Test(), тя ще изведе стойността на $a и ще я увеличи.
Статичните променливи също позволяват да се работи с рекурсивни функции. Рекурсивна функция е функция, която извиква сама себе си. Когато пишете рекурсивна функция, трябва да внимавате, защото е възможно да направите рекурсията безкрайна. Трябва да се уверите, че има адекватен начин за прекратяване на рекурсията. Следната проста функция брои до 10 рекурсивно, като използва статичната променлива $count, за да определи кога да спре:
Пример 12-6. Статични променливи и рекурсивни функции
$count++; echo $count ; ако ( $count 10 ) Test(); > $count --; > ?>
Забележка: Статичните променливи могат да бъдат декларирани, както е показано в предишния пример. Опитът да се присвоят стойности на тези променливи, които са резултат от изрази, ще доведе до грешка при обработката.
Пример 12-7. Декларация на статични променливи
функция foo() static $int = 0; // вярно статичен $int = 1 + 2 ; // невалиден (защото е израз) static $int = sqrt ( 121 ); // невалиден (защото също е израз) |
$int++; echo $int ; > ?>
функция test_global_noref() глобален $obj; $obj = нов stdclass ; >
test_global_ref(); var_dump($obj); test_global_noref(); var_dump($obj); ?>
Изпълнението на този пример ще генерира следния изход:
Статичният израз се държи по подобен начин. Връзките не се съхраняват статично:
echo "Статичен обект: "; var_dump($obj); if (!isset( $obj )) // Задаване на препратка към статична променлива $obj = &new stdclass ; > $obj -> собственост++; върни $obj ; >
echo "Статичен обект: "; var_dump($obj); if (!isset( $obj )) // Присвояване на обекта на статична променлива $obj = new stdclass ; > $obj -> собственост++; върни $obj ; >
$obj1 = get_instance_ref(); $still_obj1 = get_instance_ref (); ехо "\n" ; $obj2 = get_instance_noref(); $still_obj2 = get_instance_noref(); ?>
Изпълнението на този пример ще генерира следния изход:
Статичен обект: NULL Статичен обект: NULL Статичен обект: NULL Статичен обект: object(stdClass)(1) < ["свойство"]=>int(1) >
Този пример демонстрира, че при присвояване на препратка към статична променлива, тя не се запомня втори път, когато извикате &get_instance_ref().