Ссылка: Что такое переменная scope, какие переменные доступны откуда и какие ошибки "неопределенной переменной"?
Примечание: это ссылочный вопрос для работы с переменной областью в PHP. Пожалуйста, закройте любой из многих вопросов, соответствующих этому шаблону, как дубликат этого.
что такое "переменная область" в PHP? Являются переменными от одного .php файл доступен в другом? Почему я иногда получаю "неопределенной переменной" ошибки?
3 ответов:
что такое "переменная"?
переменные имеют ограниченную "область действия"или" места, из которых они доступны". Просто потому, что ты написал
$foo = 'bar';после где-то в вашем приложении не означает, что вы можете ссылаться на$fooС везде еще внутри приложения. Переменная$fooимеет определенную область, в которой он действителен, и только код в той же области имеет доступ к переменной.как определяется область действия в PHP?
очень просто: PHP имеет область действия функции. Это единственный вид разделителя областей, который существует в PHP. Переменные внутри функции доступны только внутри этой функции. Переменные вне функций доступны в любом месте вне функций, но не внутри любой функции. Это означает, что в PHP есть одна специальная область:глобальные объем. Любая переменная, объявленная вне любой функции, находится в пределах этого глобального масштаб.
пример:
<?php $foo = 'bar'; function myFunc() { $baz = 42; }
$fooнаходится в глобальные область,$bazнаходится в местные объем внутриmyFunc. Только код внутриmyFuncимеет доступ к$baz. Только код за пределамиmyFuncимеет доступ к$foo. Не имеет доступа к другому:<?php $foo = 'bar'; function myFunc() { $baz = 42; echo $foo; // doesn't work echo $baz; // works } echo $foo; // works echo $baz; // doesn't workобъем и включенные файлы
границы файлов do не отдельная область применения:
a.php
<?php $foo = 'bar';b.php
<?php include 'a.php'; echo $foo; // works!те же правила применяются к
includeкод d как применяется к любому другому коду: толькоfunctionотдельные сферы деятельности. Для целей области вы можете подумать о включении таких файлов, как копирование и вставка кода:c.php
<?php function myFunc() { include 'a.php'; echo $foo; // works } myFunc(); echo $foo; // doesn't work!в приведенном выше примере
a.phpбыло включено внутриmyFunc, каких-либо переменных внутриa.phpтолько область действия локальной функции. Просто потому, что они появляется чтобы быть в глобальной областиa.phpне обязательно означает, что они есть, это на самом деле зависит от того, в каком контексте этот код включен/выполнен.как насчет функций внутри функций и классов?
новаяfunctionобъявление вводит новую область, это так просто.(анонимных) функций внутри функции
function foo() { $foo = 'bar'; $bar = function () { // no access to $foo $baz = 'baz'; }; // no access to $baz }классы
$foo = 'foo'; class Bar { public function baz() { // no access to $foo $baz = 'baz'; } } // no access to $bazдля чего нужен объем?
решение проблем с областью видимости может показаться раздражающим, но ограниченная переменная область имеет важное значение для написания сложных приложений! если каждая переменная, которую вы объявляете, будет доступна отовсюду внутри вашего приложения, вы будете шагать по всем своим переменным без реального способа отслеживать, что что меняет. Есть только так много разумных имен, которые вы можете дать своим переменные, вы, вероятно, хотите использовать переменную "
$name" в нескольких местах. Если бы вы могли иметь это уникальное имя переменной только один раз в своем приложении, вам пришлось бы прибегнуть к действительно сложным схемам именования, чтобы убедиться, что ваши переменные уникальны и что вы не меняете неправильную переменную из неправильного фрагмента кода.обратите внимание:
function foo() { echo $bar; }если бы не было области видимости, что бы делала вышеуказанная функция? Где же
$barоткуда? В каком состоянии она находится? Он даже инициализирован? Вы должны проверять каждый раз? Это не ремонтопригодно. Что нас и подводит...пересечение границ области
правильный путь: передача переменных внутрь и наружу
function foo($bar) { echo $bar; return 42; }переменная
$barявно входит в эту область в качестве аргумента функции. Просто глядя на эту функцию, становится ясно, откуда берутся значения, с которыми она работает. Это тогда явно возвращает значение. У абонента есть уверенность, чтобы знайте, с какими переменными будет работать функция и откуда берутся ее возвращаемые значения:$baz = 'baz'; $blarg = foo($baz);расширение области переменных в анонимные функции
$foo = 'bar'; $baz = function () use ($foo) { echo $foo; }; $baz();анонимная функция явно включает в себя
$fooот его окружающего объема. Обратите внимание, что это не то же самое как глобальные объем.неправильно:
globalкак было сказано ранее, глобальная область несколько особенная, и функции могут явно импорт переменных из него:
$foo = 'bar'; function baz() { global $foo; echo $foo; $foo = 'baz'; }эта функция использует и изменяет глобальную переменную
$foo. не делай этого!(если вы действительно действительно действительно знаете, что вы делаете, и даже тогда: не надо!)все вызывающий эту функцию видит это:
baz(); // outputs "bar" unset($foo); baz(); // no output, WTF?! baz(); // outputs "baz", WTF?!?!!нет никаких признаков того, что эта функция имеет какие-либо побочные эффекты, но это не так. Это очень легко становится запутанным беспорядком, как некоторые функции продолжают изменять и требование какое-то глобальное состояние. Вы хотите, чтобы функции без гражданства, действуя только на их входы и возвращая определенный выход, сколько бы раз вы их ни называли.
вы должны избегать использования глобальной области как можно больше; скорее всего, вы не должны "вытаскивать" переменные из глобальной области в локальную область.
хотя переменные, определенные внутри области действия функции, не могут быть доступны извне, это не означает, что вы не можете использовать их значения после завершения этой функции. PHP имеет хорошо известный
staticключевое слово, которое широко используется в объектно-ориентированном PHP для определения статических методов и свойств, но следует иметь в виду, чтоstaticможет также использоваться внутри функций для определения статических переменных.что это статическое переменная'?
статическая переменная отличается от обычной переменной, определенной в области действия функции, если она не теряет значение, когда выполнение программы покидает эту область. Рассмотрим следующий пример использования статических переменных:
function countSheep($num) { static $counter = 0; $counter += $num; echo "$counter sheep jumped over fence"; } countSheep(1); countSheep(2); countSheep(3);результат:
1 sheep jumped over fence 3 sheep jumped over fence 6 sheep jumped over fenceесли бы мы определили
$counterбезstaticтогда каждый раз эхом значение будет таким же, как$numпараметр, передаваемый функции. Используяstaticпозволяет построить этот простой счетчик без дополнительных обходных путей.статические переменные use-cases
- для хранения значений между последовательными вызовами функции.
- для хранения значений между рекурсивными вызовами, когда нет способа (или нет цели), чтобы передавать их в качестве параметров.
- для кэширования значения, которое обычно лучше получить один раз. Для пример, результат чтения неизменяемого файла на сервер.
хитрости
статическая переменная существует только в локальной области видимости функции. Этого не может быть доступ вне функции, в которой он был определен. Так что вы можете убедитесь, что он сохранит свое значение неизменным до следующего вызова эта функция.
статическая переменная может быть определена только как скаляр или как скаляр выражение (начиная с PHP 5.6). Присвоение ему других значений неизбежно приводит к провалу при по крайней мере, на данный момент эта статья была написана. Тем не менее, вы можете сделать это только на следующей строке кода:
function countSheep($num) { static $counter = 0; $counter += sqrt($num);//imagine we need to take root of our sheep each time echo "$counter sheep jumped over fence"; }результат:
2 sheep jumped over fence 5 sheep jumped over fence 9 sheep jumped over fenceстатическая функция является своего рода "общим" между методами объектов тот же класс. Это легко понять, просмотрев следующий пример:
class SomeClass { public function foo() { static $x = 0; echo ++$x; } } $object1 = new SomeClass; $object2 = new SomeClass; $object1->foo(); // 1 $object2->foo(); // 2 oops, $object2 uses the same static $x as $object1 $object1->foo(); // 3 now $object1 increments $x $object2->foo(); // 4 and now his twin brotherэто работает только с объектами одного класса. Если объекты из разных классов (даже расширяя друг друга) поведение статических vars будет как и ожидалось.
является ли статическая переменная единственным способом сохранения значений между вызовами функции?
другой способ сохранить значения между вызовами функций - использовать замыкания. Закрытие было введено в PHP 5.3. В двух словах они позволяют ограничить доступ к некоторому набору переменных в пределах области действия функции другой анонимной функцией, которая будет единственным способом доступа к ним. Находясь в переменных закрытия может имитировать (более или менее успешно) ООП такие понятия, как "константы класса" (если они были переданы в замыкании по значению) или "частные свойства" (если они были переданы по ссылке) в структурированном программировании.
последний фактически позволяет использовать замыкания вместо статических переменных. Что использовать всегда зависит от разработчика, но следует отметить, что статические переменные определенно полезны при работе с рекурсиями и заслуживают внимания разработчиков.
область действия переменной-это контекст, в котором он определен. По большей части все переменные PHP имеют только одну область. Этот одна область охватывает включены и необходимые файлы, а также. Например:
на<?php $a = 1; include 'b.inc'; ?>$aпеременная будет доступна в комплектеb.incсценарий. Однако в рамках пользовательских функций вводится локальная область действия функции. Любая переменная, используемая внутри функции, по умолчанию ограничена областью действия локальной функции. Для пример:<?php $a = 1; /* global scope */ function test() { echo $a; /* reference to local scope variable */ } test(); ?>этот сценарий не будет производить никаких выходных данных, потому что оператор echo ссылается на локальную версию переменной $a, и ей не было присвоено значение в этой области. Вы можете заметить, что это немного отличается от языка C в том, что глобальные переменные в C автоматически доступны функции, если не переопределены местным определением. Это может вызвать некоторые проблемы в том, что люди могут случайно изменить глобальную переменную. в PHP глобальные переменные должны быть объявлены глобальными внутри функции, если они будут использоваться в этой функции.
Comments