Глобальные переменные и суперглобальные массивы в PHP
Глобальные переменные и суперглобальные массивы в PHP
PHP предоставляет разработчикам мощный инструментарий для взаимодействия с внешним окружением, пользовательскими данными и внутренним состоянием скрипта. Одной из ключевых особенностей языка являются глобальные переменные и суперглобальные массивы — специальные структуры данных, доступные в любом месте скрипта без необходимости явного объявления или передачи через параметры функций.
Эти механизмы позволяют получать информацию о запросе пользователя, настройках сервера, переменных окружения, загруженных файлах, сессиях и других аспектах выполнения веб-приложения. Понимание их назначения, работы и правил использования критически важно как для начинающих, так и для опытных разработчиков.
Что такое глобальные переменные в PHP
Глобальная переменная — это переменная, объявленная вне тела функции или метода и доступная в любой части скрипта, за исключением локальных областей видимости (например, внутри функций), если явно не указано иное.
В PHP по умолчанию переменные, созданные в основном теле скрипта, имеют глобальную область видимости. Однако внутри функций они недоступны, пока не будет использован ключевое слово global или обращение через массив $GLOBALS.
Пример:
$color = "зелёный";
function showColor() {
global $color;
echo $color; // выведет "зелёный"
}
showColor();
Альтернативный способ — использование $GLOBALS:
$color = "синий";
function showColorAlt() {
echo $GLOBALS['color']; // выведет "синий"
}
showColorAlt();
Хотя такие пользовательские глобальные переменные возможны, их активное использование считается плохой практикой, поскольку нарушает принципы инкапсуляции и затрудняет отладку, тестирование и поддержку кода. Вместо этого PHP предлагает использовать суперглобальные массивы, которые стандартизированы и предназначены именно для безопасного и предсказуемого взаимодействия со средой выполнения.
Что такое суперглобальные массивы
Суперглобальные массивы — это встроенные в PHP ассоциативные массивы, автоматически заполняемые данными из различных источников: HTTP-запроса, серверного окружения, сессии, файловой системы и других. Они доступны в любом контексте — внутри функций, классов, пространств имён — без объявления через global.
PHP определяет следующие суперглобальные массивы:
$_SERVER$_GET$_POST$_FILES$_COOKIE$_SESSION$_REQUEST$_ENV$GLOBALS
Кроме того, при запуске скрипта из командной строки доступны специальные переменные:
$argc$argv
Рассмотрим каждый из них подробно.
$_SERVER — информация о сервере и запросе
Массив $_SERVER содержит данные, предоставленные веб-сервером и относящиеся к текущему HTTP-запросу или среде выполнения скрипта.
Основные элементы $_SERVER:
$_SERVER['HTTP_HOST']— доменное имя или IP-адрес хоста, к которому обратился клиент.$_SERVER['REQUEST_METHOD']— метод HTTP-запроса (GET,POST,PUT,DELETEи т.д.).$_SERVER['REQUEST_URI']— URI запрошенного ресурса (без домена).$_SERVER['QUERY_STRING']— строка запроса после знака?.$_SERVER['SCRIPT_NAME']— путь к исполняемому PHP-файлу относительно корня сайта.$_SERVER['REMOTE_ADDR']— IP-адрес клиента.$_SERVER['HTTP_USER_AGENT']— строка, идентифицирующая браузер или клиентское приложение.$_SERVER['HTTPS']— присутствует и имеет значение'on', если соединение защищено через HTTPS.$_SERVER['DOCUMENT_ROOT']— абсолютный путь к корневой директории сайта на сервере.$_SERVER['SERVER_SOFTWARE']— название и версия веб-сервера (например, Apache/2.4.41).
Пример использования:
echo "Вы используете браузер: " . $_SERVER['HTTP_USER_AGENT'];
echo "Ваш IP: " . $_SERVER['REMOTE_ADDR'];
if (!empty($_SERVER['HTTPS'])) {
echo "Соединение защищено.";
}
⚠️ Предупреждение
Данные из$_SERVERмогут быть подделаны клиентом (особенно заголовки, начинающиеся сHTTP_). Их нельзя использовать без валидации в критически важных операциях, таких как авторизация или логика безопасности.
$_GET — данные из URL-строки
Массив $_GET содержит параметры, переданные в URL после знака вопроса (?) в виде пар ключ=значение, разделённых символом &.
Пример URL:
https://example.com/page.php?name=Иван&age=30
В этом случае:
echo $_GET['name']; // "Иван"
echo $_GET['age']; // "30"
Особенности:
- Все значения в
$_GETявляются строками. - Если параметр не задан, обращение к нему вызовет ошибку уровня
Notice. Рекомендуется проверять существование ключа черезisset()илиarray_key_exists(). - Для защиты от XSS и других атак необходимо экранировать вывод через
htmlspecialchars().
Безопасное чтение:
$name = isset($_GET['name']) ? htmlspecialchars($_GET['name'], ENT_QUOTES, 'UTF-8') : 'Гость';
echo "Привет, $name!";
$_POST — данные из тела HTTP-запроса
Массив $_POST содержит данные, отправленные клиентом методом POST, обычно через HTML-формы с атрибутом method="post".
Пример формы:
<form method="post" action="process.php">
<input type="text" name="email">
<input type="submit">
</form>
В process.php:
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$email = $_POST['email'] ?? '';
// Валидация и обработка
}
Особенности:
- Как и
$_GET, все значения — строки. - Не отображаются в адресной строке, что делает
POSTболее подходящим для передачи конфиденциальных данных (хотя это не замена шифрованию!). - Максимальный размер данных ограничен настройками сервера (
post_max_sizeвphp.ini).
$_FILES — загруженные файлы
При отправке формы с атрибутом enctype="multipart/form-data" и полем <input type="file">, данные о загруженных файлах попадают в массив $_FILES.
Структура $_FILES['имя_поля']:
name— оригинальное имя файла на клиенте.type— MIME-тип (может быть подделан!).size— размер в байтах.tmp_name— временный путь на сервере, куда файл загружен.error— код ошибки (0 = успешно).
Пример обработки:
if ($_FILES['avatar']['error'] === UPLOAD_ERR_OK) {
$tmpName = $_FILES['avatar']['tmp_name'];
$target = __DIR__ . '/uploads/' . basename($_FILES['avatar']['name']);
if (move_uploaded_file($tmpName, $target)) {
echo "Файл загружен.";
}
}
⛔ Осторожно
Никогда не доверяйте$_FILES['name']напрямую. Всегда генерируйте безопасное имя файла и проверяйте тип по содержимому (например, черезfinfo_file), а не по расширению.
$_COOKIE — данные cookie
Массив $_COOKIE содержит cookies, отправленные браузером вместе с запросом. Cookies — это небольшие фрагменты данных, сохранённые на стороне клиента и автоматически передаваемые при каждом запросе к домену.
Устанавливаются через функцию setcookie():
setcookie('user_id', '123', time() + 3600, '/', '', true, true);
После этого в последующих запросах:
echo $_COOKIE['user_id'] ?? 'не установлен';
Безопасность:
- Используйте флаги
HttpOnlyиSecure. - Не храните в cookie чувствительные данные (пароли, токены без шифрования).
- Всегда проверяйте целостность и подлинность данных.
$_SESSION — данные сессии
Сессия — механизм хранения данных на сервере, связанных с конкретным пользователем. Идентификатор сессии обычно передаётся через cookie (PHPSESSID) или URL.
Перед использованием сессии необходимо вызвать session_start():
session_start();
$_SESSION['user_id'] = 456;
В последующих запросах:
session_start();
echo $_SESSION['user_id'] ?? 'не авторизован';
Особенности:
- Данные хранятся на сервере (в файлах, Redis, базе и т.д.), что делает их безопаснее cookies.
- Сессии завершаются при закрытии браузера (если не настроено иное) или по таймауту.
- Уязвимы к атакам hijacking и fixation — требуют защиты через регенерацию ID и HTTPS.
$_REQUEST — объединённый массив входных данных
Массив $_REQUEST содержит данные из $_GET, $_POST и $_COOKIE (в зависимости от настройки request_order или variables_order в php.ini).
По умолчанию порядок: GP (сначала GET, потом POST), но может включать и C (cookies).
Проблемы:
- Неопределённость источника данных.
- Повышает риск коллизий имён (например,
?id=1и форма сid=2). - Считается устаревшим и небезопасным подходом.
📌 Внимание
Использование$_REQUESTне рекомендуется. Всегда явно указывайте источник:$_GET,$_POSTили$_COOKIE.
$_ENV — переменные окружения
Массив $_ENV содержит переменные среды, установленные в операционной системе или веб-сервере.
Примеры:
$_ENV['HOME']— домашняя директория пользователя (в CLI).$_ENV['DATABASE_URL']— строка подключения к БД (часто используется в продакшене).
Однако поведение зависит от настройки variables_order. Во многих конфигурациях $_ENV остаётся пустым, и для получения переменных окружения следует использовать функцию getenv() или $_SERVER.
Рекомендация:
Для надёжного чтения переменных окружения используйте:
$databaseUrl = getenv('DATABASE_URL') ?: $_ENV['DATABASE_URL'] ?? null;
Или, лучше, библиотеки вроде vlucas/phpdotenv для управления .env-файлами.
$GLOBALS — доступ ко всем глобальным переменным
Массив $GLOBALS содержит ссылки на все глобальные переменные, существующие в скрипте. Ключи — имена переменных, значения — их содержимое.
Пример:
$counter = 100;
function increment() {
$GLOBALS['counter']++;
}
increment();
echo $counter; // 101
Хотя технически возможно, использование $GLOBALS усложняет анализ кода и нарушает принципы чистой архитектуры. Его применение ограничено редкими случаями, когда требуется динамический доступ к глобальному состоянию.
$argc и $argv — аргументы командной строки
При запуске PHP-скрипта из терминала (CLI-режим), переменные $argc и $argv предоставляют доступ к аргументам командной строки.
$argc— количество аргументов (включая имя скрипта).$argv— массив аргументов, где$argv[0]— путь к скрипту.
Пример вызова:
php script.php --mode=dev --verbose
Внутри script.php:
echo "Аргументов: " . $argc . "\n";
print_r($argv);
// Выведет:
// Array
// (
// [0] => /path/to/script.php
// [1] => --mode=dev
// [2] => --verbose
// )
Для удобной обработки аргументов рекомендуется использовать библиотеки, такие как symfony/console.
Правила и особенности работы с суперглобальными массивами
Суперглобальные массивы в PHP обладают рядом важных особенностей, которые необходимо учитывать при разработке:
Автоматическая доступность
Все суперглобальные массивы автоматически существуют в любом контексте выполнения — глобальном, локальном, внутри класса или пространства имён. Их не нужно объявлять с помощью global или передавать как аргументы.
Нельзя использовать как переменные функции
Суперглобальные массивы нельзя передавать по ссылке в качестве параметров функций в старых версиях PHP (до 5.4), а также нельзя использовать в конструкциях вроде foreach ($GLOBALS as &$value), так как это вызывает фатальную ошибку. Это связано с тем, что $GLOBALS является псевдонимом для всех глобальных переменных, и изменение его содержимого может привести к непредсказуемому поведению.
Неизменяемость структуры (в некоторых случаях)
Хотя значения внутри суперглобальных массивов можно изменять, их нельзя полностью перезаписать новым массивом без последствий. Например, присвоение $_POST = [] технически возможно, но нарушает ожидаемое поведение скрипта и затрудняет отладку.
Безопасность и фильтрация
PHP предоставляет расширение filter, которое позволяет безопасно работать с данными из суперглобальных массивов:
$email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
Этот подход предпочтительнее прямого обращения к $_GET['id'], так как он включает встроенную валидацию и санитизацию.
Рекомендации по использованию
Избегайте прямого использования $_REQUEST
Массив $_REQUEST объединяет данные из нескольких источников, что затрудняет определение происхождения данных и увеличивает риск коллизий. Всегда явно указывайте источник: $_GET, $_POST или $_COOKIE.
Валидируйте и саниитизируйте все входные данные
Никогда не доверяйте данным, поступающим из суперглобальных массивов. Даже если форма отправляется вашим собственным сайтом, злоумышленник может подделать запрос. Применяйте:
- Проверку типа (
is_int(),filter_var()). - Ограничение длины.
- Экранирование при выводе (
htmlspecialchars()). - Валидацию формата (регулярные выражения, специализированные функции).
Не храните чувствительные данные в $_COOKIE
Cookies передаются с каждым запросом и могут быть перехвачены. Для хранения идентификаторов сессии используйте $_SESSION, а в cookie — только зашифрованный или хэшированный токен, не раскрывающий внутреннюю структуру приложения.
Используйте session_regenerate_id() после авторизации
Это предотвращает атаки фиксации сессии (session fixation). После успешного входа пользователя вызывайте:
session_start();
// ... проверка логина и пароля ...
$_SESSION['user_id'] = $userId;
session_regenerate_id(true); // true — удаляет старую сессию
Ограничьте использование $argc и $argv в веб-приложениях
Эти переменные актуальны только при запуске скрипта из командной строки. В веб-контексте они недоступны или пусты. Используйте их только в CLI-скриптах (например, cron-задачах, консольных утилитах).
Совместимость и изменения в разных версиях PHP
- До PHP 5.0.0 суперглобальные массивы не были доступны внутри функций без объявления через
global. - Начиная с PHP 5.0.0 все суперглобальные массивы стали действительно «суперглобальными».
- В PHP 7.1 добавлена поддержка типизированных свойств, но это не влияет на суперглобальные массивы, так как они всегда остаются массивами.
- В PHP 8.0+ улучшена обработка ошибок при работе с файлами, но структура
$_FILESосталась неизменной.
Альтернативы и современные подходы
В профессиональной разработке на PHP редко используют суперглобальные массивы напрямую. Вместо этого применяют:
-
HTTP-фреймворки (Symfony HttpFoundation, Laravel Request), которые инкапсулируют запрос и предоставляют объектно-ориентированный интерфейс:
$request->query->get('id'); // вместо $_GET['id']
$request->request->get('email'); // вместо $_POST['email']
$request->cookies->get('theme'); // вместо $_COOKIE['theme'] -
PSR-7 — стандартный интерфейс для HTTP-сообщений, который абстрагирует работу с запросами и ответами.
-
Middleware-архитектура, где каждый слой обрабатывает запрос, не имея прямого доступа к глобальному состоянию.
Такие подходы повышают тестируемость, читаемость и безопасность кода.