Ответ
В отличие от JavaScript, в PHP нет классического hoisting'а (поднятия) объявлений переменных. Переменная в PHP не существует до момента её явного объявления в коде.
Ключевое правило: Обращение к переменной до её инициализации вызовет предупреждение или ошибку.
// Пример 1: Ошибка доступа к необъявленной переменной
echo $undefinedVar; // Notice: Undefined variable: undefinedVar
$undefinedVar = 10;
// Пример 2: Переменная существует только после объявления внутри области видимости
function test() {
// echo $localVar; // Если раскомментировать, будет Notice
$localVar = "I exist now";
echo $localVar; // Корректно: "I exist now"
}
Особые случаи, которые иногда путают с поднятием:
-
Глобальные переменные и ключевое слово
global:$globalVar = "outside"; function testGlobal() { // echo $globalVar; // Notice! $globalVar здесь не определена global $globalVar; // Ссылка на глобальную переменную создается здесь echo $globalVar; // Корректно: "outside" } testGlobal();Ключевое слово
globalне "поднимает" переменную, а создаёт ссылку на уже существующую глобальную переменную в момент выполнения строки сglobal. -
Статические переменные внутри функций:
function counter() { static $count = 0; // Инициализация происходит ТОЛЬКО при первом вызове функции $count++; echo $count; } counter(); // 1 counter(); // 2Переменная
$countсохраняет своё значение между вызовами функции, но это не hoisting. Область видимости статической переменной ограничена функцией. -
Поднятие функций и классов:
// В PHP функции и классы, объявленные обычным образом, "поднимаются". foo(); // Работает, выведет "Hello!" function foo() { echo "Hello!"; } // Однако анонимные функции (замыкания), присвоенные переменным, не поднимаются. // bar(); // Fatal error, если раскомментировать $bar = function() { echo "Anonymous"; }; $bar(); // Корректно
Вывод:
- Для переменных: Hoisting отсутствует. Всегда объявляйте и инициализируйте переменные перед использованием.
- Для функций/классов: Традиционные объявления (через
functionиclass) поднимаются и могут быть вызваны до их места объявления в файле. - Область видимости в PHP в основном определяется функциями и классами, а не блоками
{}, как в JavaScript (за исключением анонимных функций/замыканий).
Ответ 18+ 🔞
Давай разберём эту дичь с PHP и его "поднятием", а то народ путается, как будто на дворе 2002-й год и все только про JavaScript слышали.
Смотри, в PHP с переменными — полный пиздец, если пытаться вести себя как в JS. Тут никакого классического hoisting'а нет, и точка. Переменная появляется ровно в тот момент, когда ты её написал, а не где-то в облаках. Попробуешь обратиться раньше — получишь по шапке.
// Пример 1: Попытка выебать систему
echo $undefinedVar; // Тебе вежливо скажут: Notice: Undefined variable: undefinedVar. То есть нихуя нет.
$undefinedVar = 10; // А вот теперь есть, но поздно.
Вот главное правило, которое надо вбить себе в башку: переменная не существует, пока ты её не создал в коде. Всё, приехали.
А теперь про те моменты, где народ начинает ебаться с логикой и думать, что что-то "всплывает":
-
Глобальные переменные и это ёбаное слово
global:$globalVar = "снаружи"; function testGlobal() { // echo $globalVar; // Разкомментируешь — получишь Notice! Внутри функции этой хуйни пока нет. global $globalVar; // Вот эта строчка — не поднятие, а просто создание ссылки на ту самую внешнюю переменную. Прямо здесь и сейчас. echo $globalVar; // Теперь работает: "снаружи" } testGlobal();Никакой магии.
global— это просто указатель, который ты выставляешь в нужном месте. -
Статические переменные в функциях — хитрая жопа:
function counter() { static $count = 0; // Инициализация срабатывает ТОЛЬКО при первом заходе в функцию. Это не поднятие, а особенность работы `static`. $count++; echo $count; } counter(); // 1 counter(); // 2Переменная
$countживёт между вызовами, но её область видимости — только внутри функции. Это не hoisting, это просто статика, ёпта. -
А вот с функциями и классами — да, тут реальный подъём:
// Обычные функции — да, их можно вызывать хоть сверху, хоть снизу. foo(); // Сработает на ура, выведет "Hello!" function foo() { echo "Hello!"; } // Но если ты функцию в переменную запихал (анонимку), то всё, пиши пропало. Её нет, пока не дошёл до строки с присваиванием. // bar(); // Fatal error, полный атас, если попробуешь. $bar = function() { echo "Anonymous"; }; $bar(); // А вот теперь окей.
Итог, чтобы не было удивления пиздец:
- Переменные: Забудь про hoisting. Сначала объявил, потом использовал. Иначе будешь ловить Notice'ы, как дурак.
- Функции/Классы: Обычные объявления (
function,class) — да, они поднимаются, можно вызывать раньше. - Область видимости в PHP в основном крутится вокруг функций и классов, а не вокруг любых скобок
{}. Хотя с замыканиями уже можно пошалить.
Короче, не выёбывайся, пиши код последовательно, и будет тебе счастье.