Инструкция global в PHP — это способ дать функции доступ к переменной, которая объявлена вне ее, в глобальной области видимости. По умолчанию функция такую переменную не видит: любое имя внутри функции считается локальным. Тот же доступ дает суперглобальный массив $GLOBALS.
Содержание
Ниже разберу, чем локальная область видимости отличается от глобальной, как связать функцию с внешней переменной через global и через $GLOBALS, чем эти два способа отличаются, что изменилось в $GLOBALS начиная с PHP 8.1 и почему глобальными переменными лучше не злоупотреблять. Примеры даны для PHP 8.x.
Область видимости: локальная и глобальная
Область видимости — это часть программы, где переменная существует и доступна по имени. В PHP их две основные.
Локальная область — тело функции. Переменная, которой присвоили значение внутри функции, живет только там и исчезает после выхода из функции.
Глобальная область — код вне функций, на верхнем уровне скрипта. Переменные, объявленные здесь, доступны в остальном коде верхнего уровня.
Ключевая особенность PHP: в отличие от многих языков, функция НЕ видит глобальные переменные автоматически. Внутри функции имя $x — это всегда локальная переменная, даже если снаружи есть глобальная $x с тем же именем. Связи между ними по умолчанию нет.
Покажу это на примере. Имя совпадает, но переменные разные:
<?php
$x = 555;
function test() {
$x = 888; // это локальная переменная функции
echo $x, "\n";
}
test(); // печатает локальную 888
echo $x, "\n"; // печатает глобальную 555
Вывод:
888
555
Сначала вызывается test() и печатает свою локальную $x (888). Затем echo на верхнем уровне печатает глобальную $x (555). Присваивание внутри функции не тронуло внешнюю переменную — это две независимые ячейки с одинаковым именем.
Проблема: функция не меняет внешнюю переменную
Из-за такого разделения наивная попытка изменить глобальную переменную из функции не работает. Функция создает свою локальную копию имени и правит ее.
Неверный код (расчет на то, что функция увидит внешний $total):
<?php
$total = 100;
function addBonus() {
$total = $total + 50; // справа - локальная неинициализированная переменная
echo $total, "\n";
}
addBonus();
echo $total, "\n";
Фактический вывод в PHP 8.x:
PHP Warning: Undefined variable $total in ... on line 5
50
100
Что произошло: внутри функции $total в правой части — это новая локальная переменная, которой еще не присвоили значение. PHP 8 выдает предупреждение Undefined variable и подставляет null, а null в арифметике равен 0. Поэтому локальная $total стала 0 + 50 = 50, а глобальная так и осталась 100. Именно для этого случая и нужна инструкция global.
Инструкция global
global внутри функции объявляет, что перечисленные имена ссылаются на глобальные переменные, а не на локальные. После этого функция читает и меняет именно внешние значения.
Исправим предыдущий пример:
<?php
$total = 100;
function addBonus() {
global $total; // связываем имя с глобальной переменной
$total = $total + 50;
echo $total, "\n";
}
addBonus(); // 150
echo $total, "\n"; // 150
Вывод:
150
150
Теперь обе строки печатают 150: функция изменила ту же переменную, что видна снаружи. Через запятую можно объявить сразу несколько имен — global $x, $y; — ограничений на их число нет.
Классический пример со сложением двух глобальных переменных:
<?php
$x = 5;
$y = 10;
function sum() {
global $x, $y;
$y = $x + $y;
}
sum();
echo $y, "\n"; // 15
Вывод:
15
Важно понимать механику: global $x; не копирует значение, а создает в функции ссылку на глобальную переменную. Строка эквивалентна записи $x = &$GLOBALS['x'];. Поэтому запись в такую переменную меняет глобальную, а unset($x) внутри функции разорвет только локальную ссылку — сама глобальная переменная сохранится.
Массив $GLOBALS
Второй способ добраться до глобальной области — суперглобальный массив $GLOBALS. Это ассоциативный массив, где ключ — имя глобальной переменной (без знака $), а значение — ее содержимое. Тот же пример через $GLOBALS:
<?php
$x = 5;
$y = 10;
function sum() {
$GLOBALS['y'] = $GLOBALS['x'] + $GLOBALS['y'];
}
sum();
echo $y, "\n"; // 15
Вывод:
15
Результат тот же — 15, но объявлять global не понадобилось. Слово суперглобальный означает, что массив доступен в любой области видимости автоматически: и на верхнем уровне, и внутри любой функции, без предварительного объявления. К этому же семейству относятся $_GET, $_POST, $_SESSION, $_SERVER и другие — их тоже не нужно объявлять через global.
Одно уточнение по версиям. Начиная с PHP 8.1 массив $GLOBALS стал доступен только для чтения как единое целое: нельзя перезаписать его целиком ($GLOBALS = [...]) или передать по ссылке. Но запись в отдельный элемент — $GLOBALS['y'] = ... — по-прежнему работает и меняет глобальную переменную, как в примере выше. Так что на код доступа к конкретным переменным это изменение не влияет.
global или $GLOBALS: что выбрать
Оба способа решают одну задачу, отличия — в деталях.
| Признак | Инструкция global | Массив $GLOBALS |
|---|---|---|
| Как обращаться | по обычному имени $x после global $x; |
по ключу $GLOBALS['x'] |
| Нужно объявлять | да, в начале функции | нет, доступен сразу |
| Что создает | ссылку на глобальную переменную | прямой доступ к элементу массива |
| Имя ключа динамически | нет, имя фиксировано в коде | да, ключом может быть переменная $GLOBALS[$name] |
| Видно в любой области | только внутри функции после объявления | в любой области, суперглобален |
На практике global читается привычнее, когда переменных немного и их имена известны заранее. $GLOBALS удобнее, если имя переменной вычисляется на лету или нужно обратиться к глобальной области из глубоко вложенного контекста без объявлений.
Почему глобальными переменными лучше не злоупотреблять
Доступ к глобальным переменным из функций — рабочий механизм, но он же считается признаком неаккуратного кода. Функция, которая читает и пишет глобальные переменные, зависит от внешнего состояния неявно: по ее сигнатуре не видно, что она использует и что меняет. Такой код труднее тестировать и отлаживать, а случайное совпадение имен приводит к тому, что одна функция незаметно портит данные другой.
Более предсказуемая альтернатива — передавать данные явно, через аргументы и возвращаемое значение:
<?php
function addBonus(int $total, int $bonus): int
{
return $total + $bonus; // ничего снаружи не меняем
}
$total = 100;
$total = addBonus($total, 50);
echo $total, "\n"; // 150
Вывод:
150
Здесь функция не зависит от глобального состояния: что получает и что отдает — видно по сигнатуре. Для констант приложения используют const или define(), а для общего состояния в больших проектах — объекты и внедрение зависимостей. global и $GLOBALS остаются удобными в коротких скриптах и при работе со старым кодом, но в новом коде их стоит применять осознанно, а не по привычке.
Выводы
- По умолчанию функция в PHP не видит глобальные переменные: любое имя внутри нее локально.
- Инструкция
global $x;связывает локальное имя с глобальной переменной; фактически это ссылка, эквивалент$x = &$GLOBALS['x'];. - Суперглобальный массив
$GLOBALS['x']дает тот же доступ без объявления и работает в любой области видимости. - С PHP 8.1 нельзя перезаписать
$GLOBALSцеликом, но запись в отдельные элементы работает по-прежнему. - Глобальные переменные связывают код неявными зависимостями; где можно, данные лучше передавать через аргументы и возвращаемые значения.
Где применяется и что учить дальше
Понимание областей видимости — база для любого кода на PHP: от простого скрипта обработки формы до фреймворка, где состояние передают через объекты и контейнер зависимостей. Ошибки с global-переменными — частая причина трудноуловимых багов, поэтому механику стоит разобрать до автоматизма, а затем осознанно предпочитать явную передачу данных.
Освойте тему на практике
Если хочется освоить PHP системно — от областей видимости и ООП до архитектуры реальных приложений, — посмотрите курс Разработчик PHP. Оценить формат и уровень до старта помогают бесплатные открытые уроки Otus — живые занятия с преподавателями.
FAQ
Чем global отличается от static внутри функции? global связывает имя с внешней, глобальной переменной. static создает локальную переменную, которая сохраняет свое значение между вызовами функции, но снаружи невидима. Это разные задачи: разделяемое состояние против памяти внутри одной функции.
Что делает global на верхнем уровне скрипта, вне функции? Практически ничего полезного: в глобальной области переменная и так глобальна, объявлять ее через global не нужно. Инструкция имеет смысл только внутри функций и методов.
Нужно ли объявлять global для $_POST, $_GET и других суперглобальных массивов? Нет. Суперглобальные массивы ($_POST, $_GET, $_SERVER, $_SESSION и прочие) доступны в любой области видимости сами по себе, global для них не требуется.



