Ответ
В PHP существует несколько областей видимости переменных, которые определяют, где переменная доступна для использования. Вот основные из них с практическими примерами:
1. Глобальная область видимости Переменные, объявленные вне функций, методов или классов.
<?php
// Глобальная область видимости
$globalVar = "Я глобальная переменная";
$counter = 0;
function testGlobal() {
// Внутри функции $globalVar НЕ доступна
// echo $globalVar; // Вызовет Notice: Undefined variable
// Способ 1: Использование global
global $globalVar, $counter;
echo $globalVar; // Теперь доступна
$counter++; // Можем изменять
// Способ 2: Использование $GLOBALS суперглобального массива
echo $GLOBALS['globalVar'];
$GLOBALS['counter']++;
}
testGlobal();
echo $counter; // Выведет: 2 (было увеличено дважды)
2. Локальная область видимости (внутри функций) Переменные, объявленные внутри функции, доступны только в этой функции.
function calculateTotal($price, $quantity) {
// $price и $quantity - параметры функции, локальные для этой функции
$taxRate = 0.20; // Локальная переменная
$subtotal = $price * $quantity;
$tax = $subtotal * $taxRate;
return $subtotal + $tax;
}
$total = calculateTotal(100, 2);
// echo $taxRate; // Ошибка! $taxRate не существует вне функции
// echo $subtotal; // Ошибка! $subtotal не существует вне функции
3. Статические переменные Сохраняют свое значение между вызовами функции.
function getNextId() {
static $id = 0; // Инициализируется только при первом вызове
$id++;
return $id;
}
echo getNextId(); // 1
echo getNextId(); // 2
echo getNextId(); // 3
// Полезно для кеширования тяжелых вычислений
function heavyCalculation($input) {
static $cache = [];
if (isset($cache[$input])) {
return $cache[$input];
}
// Тяжелые вычисления...
$result = expensiveComputation($input);
$cache[$input] = $result;
return $result;
}
4. Область видимости в классах (свойства)
class User {
// Public - доступно отовсюду
public $publicProperty = "Доступно везде";
// Protected - доступно внутри класса и наследников
protected $protectedProperty = "Доступно в классе и наследниках";
// Private - доступно только внутри этого класса
private $privateProperty = "Доступно только в этом классе";
public function getPrivateProperty() {
return $this->privateProperty; // Доступно внутри класса
}
}
class Admin extends User {
public function getProtectedProperty() {
return $this->protectedProperty; // Доступно в наследнике
}
public function tryGetPrivate() {
// return $this->privateProperty; // Ошибка! Не доступно в наследнике
}
}
$user = new User();
echo $user->publicProperty; // OK
// echo $user->protectedProperty; // Ошибка!
// echo $user->privateProperty; // Ошибка!
echo $user->getPrivateProperty(); // OK - через публичный метод
5. Суперглобальные массивы Особый тип переменных, доступных везде в скрипте:
// $_GET, $_POST, $_REQUEST - данные от пользователя
// $_SESSION - данные сессии
// $_COOKIE - куки
// $_SERVER - информация о сервере
// $_ENV - переменные окружения
// $_FILES - загруженные файлы
function processForm() {
// Суперглобальные доступны везде без объявления global
$name = $_POST['name'] ?? 'Гость';
$ip = $_SERVER['REMOTE_ADDR'];
// Важно: всегда валидировать и санитизировать данные из суперглобальных!
$cleanName = htmlspecialchars($name, ENT_QUOTES, 'UTF-8');
return "Привет, $cleanName с IP $ip";
}
6. Замыкания (closures) и use
$multiplier = 10;
// use передает переменную из внешней области видимости
$closure = function($number) use ($multiplier) {
return $number * $multiplier;
};
echo $closure(5); // 50
// По значению (по умолчанию)
$counter = 0;
$increment = function() use ($counter) {
// $counter копируется, изменения не влияют на оригинал
return ++$counter;
};
echo $increment(); // 1
echo $increment(); // 2
echo $counter; // 0 - оригинал не изменился
// По ссылке
$counter = 0;
$incrementRef = function() use (&$counter) {
return ++$counter;
};
echo $incrementRef(); // 1
echo $incrementRef(); // 2
echo $counter; // 2 - оригинал изменился
Практические рекомендации:
- Избегайте глобальных переменных - они усложняют тестирование и понимание кода
- Используйте параметры функций вместо global
- Применяйте статические переменные для кеширования и счетчиков
- Соблюдайте инкапсуляцию в классах (private/protected где возможно)
- Всегда валидируйте суперглобальные переменные
Понимание областей видимости критически важно для написания чистого, поддерживаемого и безопасного PHP-кода.