Суперглобальные массивы в PHP: $_GET, $_POST, $_SERVER и другие — понятное руководство...

Суперглобальные массивы в PHP: $_GET, $_POST, $_SERVER и другие — понятное руководство с примерами

Суперглобальные массивы в PHP: $_GET, $_POST, $_SERVER и другие — понятное руководство с примерами

Суперглобальные массивы в PHP — это предопределённые переменные, доступные в любой области видимости без global. Через них вы получаете входные данные из адресной строки, форм, заголовков, файлов, куки, сессий и окружения сервера. Понимание их различий — базовый навык каждого PHP‑разработчика.

Кратко: что такое суперглобалы

  • Это массивы с особым статусом: доступны везде, в том числе внутри функций и методов.
  • Хранят данные из запроса и окружения: $_GET, $_POST, $_SERVER, $_COOKIE, $_SESSION, $_FILES, $_ENV, $_REQUEST.
  • Вы можете читать и писать в них, но помните: запись не меняет «источник» (например, браузер или веб‑сервер).
  • $_GET и $_POST: когда что использовать

    $_GET содержит параметры строки запроса (после ? в URL). Идеально для фильтров, пагинации, поиска. $_POST передаёт данные тела запроса (обычно формы) и подходит для действий, меняющих состояние: создание, обновление, удаление.

    <!-- form.html -->
    <form action="/handle.php" method="post">
      <label>Имя: <input type="text" name="name" required></label>
      <label>Возраст: <input type="number" name="age" min="1" max="120" required></label>
      <button type="submit">Отправить</button>
    </form>
    
    <?php
    // handle.php
    $method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
    if ($method !== 'POST') {
        http_response_code(405);
        exit('Method Not Allowed');
    }
    
    $name = trim($_POST['name'] ?? '');
    $age  = (int)($_POST['age'] ?? 0);
    
    if ($name === '' || $age <= 0) {
        exit('Некорректные данные');
    }
    
    // Безопасный вывод во избежание XSS
    function e(string $s): string { return htmlspecialchars($s, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); }
    
    echo 'Привет, ' . e($name) . '! Тебе ' . e((string)$age) . ' лет.';
    

    Советы:

  • Не доверяйте входу: проверяйте типы, длины и диапазоны значений.
  • Для переключателей используйте $_GET (например, ?page=2), для действий — $_POST.
  • Всегда экранируйте вывод через htmlspecialchars.
  • Почему лучше избегать $_REQUEST

    $_REQUEST смешивает данные из $_GET, $_POST и $_COOKIE (зависит от php.ini). Это удобно, но опасно: возникает неоднозначность источника и непредсказуемость. Явно выбирайте $_GET или $_POST — код станет понятнее и безопаснее.

    <?php
    // Плохо: источник неочевиден
    $q = $_REQUEST['q'] ?? '';
    
    // Хорошо: явно указываем источник
    $q = trim($_GET['q'] ?? '');
    

    $_SERVER: данные окружения запроса

    $_SERVER хранит заголовки и переменные сервера. Полезные ключи:

  • REQUEST_METHOD — метод запроса.
  • REQUEST_URI — путь и строка запроса.
  • HTTP_HOST — домен.
  • HTTPS — признак HTTPS (не всегда надёжен за прокси).
  • HTTP_USER_AGENT — клиент (браузер).
  • REMOTE_ADDR — IP клиента (за прокси может быть не тот).
  • <?php
    function server(string $key, $default = null) {
        return $_SERVER[$key] ?? $default;
    }
    
    $method = server('REQUEST_METHOD', 'GET');
    $uri    = server('REQUEST_URI', '/');
    $host   = server('HTTP_HOST', 'localhost');
    $https  = !empty(server('HTTPS')) && server('HTTPS') !== 'off';
    $scheme = $https ? 'https' : 'http';
    $baseUrl = $scheme . '://' . $host;
    
    echo "Метод: {$method}, URI: {$uri}, База: {$baseUrl}";
    

    В продакшене учитывайте прокси: реальные IP/схему лучше определять через корректно настроенный веб‑сервер или доверенные заголовки (X-Forwarded-For, X-Forwarded-Proto) с учётом списка доверенных прокси.

    $_COOKIE и $_SESSION: кратко о состоянии

    $_COOKIE — данные, которые браузер отправляет на каждый запрос к домену. $_SESSION — серверное хранилище данных пользователя между запросами (требует session_start()).

    <?php
    // Куки (устанавливаются ДО вывода контента)
    setcookie('theme', 'dark', [
        'expires'  => time() + 86400 * 30,
        'path'     => '/',
        'secure'   => true,   // только по HTTPS
        'httponly' => true,   // недоступно JS
        'samesite' => 'Lax',
    ]);
    $theme = $_COOKIE['theme'] ?? 'light';
    
    // Сессии
    session_start();
    $_SESSION['flash'] = 'Данные сохранены!';
    echo $_SESSION['flash'] ?? '';
    unset($_SESSION['flash']);
    

    Сессии и куки — обширная тема. Здесь показаны базовые приёмы и безопасные флаги для cookie.

    $_FILES и $_ENV: загрузки и переменные окружения

    $_FILES содержит метаданные загруженных файлов: name, type, size, tmp_name, error. Для реальной загрузки файлов обязательно проверяйте тип/размер и используйте move_uploaded_file() (это отдельная тема).

    $_ENV хранит переменные окружения процесса PHP. Удобно читать секреты и конфиги без захардкоживания:

    <?php
    $dbHost = $_ENV['DB_HOST'] ?? '127.0.0.1';
    $dbName = $_ENV['DB_NAME'] ?? 'app';
    // Часто переменные окружения загружают через .env (например, vlucas/phpdotenv)
    

    Мини‑утилиты: безопасно читаем ввод

    Сделаем небольшие помощники для чтения данных с приведением типов и значений по умолчанию.

    <?php
    function input_get(string $key, $default = null) {
        return $_GET[$key] ?? $default;
    }
    function input_post(string $key, $default = null) {
        return $_POST[$key] ?? $default;
    }
    function input_bool($value): bool {
        if (is_bool($value)) return $value;
        $value = strtolower(trim((string)$value));
        return in_array($value, ['1','true','on','yes'], true);
    }
    function input_int($value, int $default = 0): int {
        if ($value === null || $value === '') return $default;
        return (int)$value;
    }
    function e(string $s): string { return htmlspecialchars($s, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); }
    
    $page = input_int(input_get('page'), 1);
    $q    = trim((string)input_get('q', ''));
    $onlyInStock = input_bool(input_get('in_stock'));
    
    echo 'Страница: ' . e((string)$page) . ', Поиск: ' . e($q) . ', В наличии: ' . ($onlyInStock ? 'да' : 'нет');
    

    Простой пример роутинга на $_SERVER и $_GET

    Научимся разбирать путь и параметр действия. Это не фреймворк, а учебный пример для понимания, как работают суперглобалы в связке.

    <?php
    $uri = parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH) ?: '/';
    $method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
    
    if ($uri === '/' && $method === 'GET') {
        echo 'Главная';
    } elseif ($uri === '/search' && $method === 'GET') {
        $q = trim($_GET['q'] ?? '');
        echo 'Результаты поиска по: ' . e($q);
    } elseif ($uri === '/save' && $method === 'POST') {
        $name = trim($_POST['name'] ?? '');
        echo $name !== '' ? 'Сохранено: ' . e($name) : 'Имя пустое';
    } else {
        http_response_code(404);
        echo 'Страница не найдена';
    }
    

    Мини‑пример защиты от CSRF для POST‑формы

    CSRF‑токен хранится в сессии и передаётся в форме. На сервере сравниваем значение перед выполнением действия.

    <?php
    // form.php
    session_start();
    if (empty($_SESSION['csrf'])) {
        $_SESSION['csrf'] = bin2hex(random_bytes(32));
    }
    $token = $_SESSION['csrf'];
    ?>
    <form action="/post.php" method="post">
      <input type="hidden" name="csrf" value="<?= htmlspecialchars($token, ENT_QUOTES, 'UTF-8') ?>">
      <input type="text" name="title" required>
      <button type="submit">Сохранить</button>
    </form>
    
    <?php
    // post.php
    session_start();
    if (!hash_equals($_SESSION['csrf'] ?? '', $_POST['csrf'] ?? '')) {
        http_response_code(419);
        exit('CSRF token mismatch');
    }
    $title = trim($_POST['title'] ?? '');
    echo $title ? 'OK: ' . htmlspecialchars($title, ENT_QUOTES, 'UTF-8') : 'Пустой заголовок';
    

    Типичные ошибки и лучшие практики

  • Не используйте $_REQUEST — выбирайте конкретный источник.
  • Всегда экранируйте вывод пользовательских данных (htmlspecialchars).
  • Сравнивайте метод запроса через $_SERVER['REQUEST_METHOD'] и отвечайте 405 при несоответствии.
  • Не полагайтесь на REMOTE_ADDR без учёта прокси; настраивайте доверенные заголовки на уровне сервера.
  • Храните секреты в окружении ($_ENV) или менеджерах секретов, не в коде.
  • Для форм с побочными эффектами используйте CSRF‑защиту и метод POST.
  • Что дальше изучать

    Освоив суперглобалы, переходите к шаблонам, роутингу, валидации, базам данных и архитектуре приложений. Хотите практики и системного подхода? Рекомендую пошаговый курс с реальными проектами —
    Пройти курс «PHP и MySQL с Нуля до Гуру 3.0».

    Теперь вы уверенно отличаете источники данных и безопасно их обрабатываете — это фундамент для любого PHP‑приложения, от микроскриптов до полноценных веб‑сервисов.

    Источник

    НЕТ КОММЕНТАРИЕВ

    Оставить комментарий