Что такое «переменная область»?
Переменные имеют ограниченную «область видимости» или «места, из которых они доступны». То, что вы $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
Область и включенные файлы
Границы файла не разделяют область видимости:
a.php
<?php
$foo = 'bar';
b.php
<?php
include 'a.php';
echo $foo; // works!
К included-коду применяются те же правила, что и к любому другому коду: только 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?!?!!
Там нет никаких признаков того, что эта функция имеет какие-либо побочные эффекты , но это так. Это очень легко становится запутанным беспорядком, поскольку некоторые функции продолжают изменяться и требуют некоторого глобального состояния. Вы хотите, чтобы функции были без состояния , действовали только на свои входы и возвращали определенный вывод, сколько бы раз вы их ни вызывали.
Вы должны избегать использования глобальной области видимости в максимально возможной степени; Скорее всего, вы не должны «вытягивать» переменные из глобальной области в локальную область.