Що таке "змінна область"?
Змінні мають обмежений "діапазон" або "місця, з яких вони доступні". Тільки тому, що ви $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!
Для include
коду d застосовуються ті самі правила, що і для будь-якого іншого коду: тільки function
s окрема область застосування. Для сфери застосування ви можете подумати про включення таких файлів, як копія та вставлення коду:
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?!?!!
Немає жодних ознак того, що ця функція має будь-які побічні ефекти , але вона є. Це дуже легко стає заплутаним безладом, оскільки деякі функції продовжують змінювати та вимагати деякого глобального стану. Ви хочете, щоб функції були без стану , діючи лише на їх входах і повертаючи заданий вихід, скільки б разів ви їх не викликали.
Вам слід уникати використання глобальної сфери якомога більше; напевно, вам не слід «витягувати» змінні з глобальної сфери в локальну область.