Область видимости: обращение к глобальным данным через global
Глобальная область видимости и ключевое слово global
Основной способ доступа к глобальной переменной внутри функции
Внутри функции можно объявить переменную как global. После этого все обращения к ней будут относиться к глобальной области видимости, а не к локальной.
<?php
$counter = 0;
function increment() {
global $counter;
$counter++;
}
increment();
echo $counter; // 1
?>
Php function global (глобальная область видимости и ключевое слово global в php)
1
Объявление global $counter создаёт ссылку на глобальную переменную. Все изменения внутри функции отражаются на оригинале.
Типичная ошибка – забыть объявить global. В этом случае внутри функции создаётся локальная переменная с тем же именем, и глобальная остаётся без изменений.
Как получить доступ к глобальной переменной без использования global?
Можно напрямую обратиться к суперглобальному массиву $GLOBALS. Он содержит все глобальные переменные, где ключ – имя переменной.
<?php
$name = 'Alice';
function greet() {
echo 'Hello, ' . $GLOBALS['name'];
}
greet(); // Hello, Alice
?>
Hello, Alice
Код становится менее читаемым, особенно при частом использовании. Кроме того, $GLOBALS можно случайно перезаписать, что приведёт к трудноуловимым ошибкам.
Как передать глобальную переменную в анонимную функцию (замыкание)?
В анонимных функциях ключевое слово global тоже работает, но чаще применяют конструкцию use. Чтобы изменения внутри замыкания отражались на глобальной переменной, необходимо передавать её по ссылке (use (&$var)).
<?php
$count = 10;
$closure = function($step) use (&$count) {
$count += $step;
};
$closure(5);
echo $count; // 15
?>
15
Если забыть амперсанд (&), переменная будет передана по значению, и изменения останутся локальными для замыкания. Внешняя переменная не изменится.
Как использовать глобальную переменную внутри callback-функции (callable)?
Когда callback передаётся в виде строки или массива (например, 'function_name'), внутри этой функции можно объявить global. Для анонимного коллбэка также подходит use.
<?php
$multiplier = 2;
$numbers = [1, 2, 3];
$result = array_map(function($n) {
global $multiplier;
return $n * $multiplier;
}, $numbers);
print_r($result);
?>
Array ( [0] => 2 [1] => 4 [2] => 6 )
При использовании global внутри callback-функции нужно быть уверенным, что переменная действительно существует в глобальной области. Иначе получите ошибку Undefined variable или будет создана новая глобальная переменная со значением null.
Как избежать случайного изменения глобальных переменных в функциях?
Лучшая практика – вовсе не использовать global без крайней необходимости. Глобальные переменные затрудняют тестирование и отладку. Вместо этого данные следует передавать через аргументы функции.
<?php
$config = ['db_host' => 'localhost'];
// Плохо: функция зависит от глобальной переменной
function connectBad() {
global $config;
// ...
}
// Хорошо: передаём конфигурацию как аргумент
function connectGood($config) {
// ...
}
connectGood($config);
?>
Если функция изменяет глобальную переменную без явного указания global, присваивание создаёт локальную переменную. Это часто вводит в заблуждение: разработчик думает, что меняет глобальное значение, но оно остаётся прежним.
Как передать глобальную переменную по ссылке в обычную функцию без global?
Можно определить функцию с параметром, передаваемым по ссылке (&$param). Тогда вызвав её с глобальной переменной, изменения отразятся на оригинале. Однако это не делает переменную глобальной внутри функции – просто работает ссылка.
<?php
$value = 100;
function addTen(&$num) {
$num += 10;
}
addTen($value);
echo $value; // 110
?>
110
При таком подходе функция явно ожидает ссылку, и код становится более предсказуемым. Ошибка возникает, если передать не переменную, а выражение (например, константу) – PHP выдаст ошибку Only variables should be passed by reference.
Какие цели и случаи использования глобальных переменных?
Глобальные переменные могут быть оправданы для конфигурационных данных (например, настройки подключения к БД), счётчиков посещений, реестров объектов. Однако в современном PHP-коде предпочитают внедрение зависимостей (dependency injection) и контейнеры. global сохраняется в legacy-проектах и при быстром прототипировании.
Расширенные примеры с глобальными переменными и global
Пример 1. Рекурсия с global – подсчёт глубины вызовов
<?php
$depth = 0;
function recurse($n) {
global $depth;
$depth++;
if ($n > 0) {
recurse($n - 1);
}
}
recurse(3);
echo $depth; // 4 (вызов с 3,2,1,0 – итого 4)
?>
4
Пример 2. Использование global вместе с анонимной функцией, переданной как callback в usort
<?php
$order = 'desc';
$data = [3, 1, 4, 2];
usort($data, function($a, $b) {
global $order;
if ($order === 'desc') {
return $b - $a;
}
return $a - $b;
});
print_r($data);
?>
Array ( [0] => 4 [1] => 3 [2] => 2 [3] => 1 )
Пример 3. Изменение глобальной переменной из замыкания с передачей по ссылке (use &)
<?php
$globalVar = 'original';
$modifier = function() use (&$globalVar) {
$globalVar = 'modified';
};
$modifier();
echo $globalVar; // modified
?>
modified
Пример 4. Ошибка: попытка изменить глобальную переменную без global или use
<?php
$x = 100;
function bad() {
$x = 200; // создаётся локальная $x
}
bad();
echo $x; // 100 – глобальная не изменилась
?>
100
Пример 5. Использование $GLOBALS для чтения и записи (динамическое имя переменной)
<?php
$greeting = 'Hello';
function setMessage($newValue) {
$GLOBALS['greeting'] = $newValue;
}
setMessage('Привет');
echo $GLOBALS['greeting']; // Привет
?>
Привет
Пример 6. global в функции, определённой внутри другой функции (вложенные функции)
<?php
$count = 0;
function outer() {
function inner() {
global $count;
$count++;
}
}
outer();
inner();
echo $count; // 1
?>
1
Пример 7. Комбинация global и static – подсчёт вызовов с сохранением состояния между вызовами
<?php
$externalCounter = 0;
function counter() {
static $localCounter = 0;
global $externalCounter;
$localCounter++;
$externalCounter++;
return [$localCounter, $externalCounter];
}
print_r(counter());
print_r(counter());
?>
Array ( [0] => 1 [1] => 1 ) Array ( [0] => 2 [1] => 2 )
Пример 8. Передача глобальной переменной в callable в виде строки (имени функции)
<?php
$greeting = 'Hi';
function greetUser($name) {
global $greeting;
echo "$greeting, $name!";
}
$callback = 'greetUser';
$callback('John'); // Hi, John!
?>
Hi, John!