Ссылка: Что такое переменная scope, какие переменные доступны откуда и какие ошибки "неопределенной переменной"?




Примечание: это ссылочный вопрос для работы с переменной областью в PHP. Пожалуйста, закройте любой из многих вопросов, соответствующих этому шаблону, как дубликат этого.




что такое "переменная область" в PHP? Являются переменными от одного .php файл доступен в другом? Почему я иногда получаю "неопределенной переменной" ошибки?

653   3  

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

  1. для хранения значений между последовательными вызовами функции.
  2. для хранения значений между рекурсивными вызовами, когда нет способа (или нет цели), чтобы передавать их в качестве параметров.
  3. для кэширования значения, которое обычно лучше получить один раз. Для пример, результат чтения неизменяемого файла на сервер.

хитрости

статическая переменная существует только в локальной области видимости функции. Этого не может быть доступ вне функции, в которой он был определен. Так что вы можете убедитесь, что он сохранит свое значение неизменным до следующего вызова эта функция.

статическая переменная может быть определена только как скаляр или как скаляр выражение (начиная с 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

    Ничего не найдено.