EasyТеория3 min

HTML формы и суперглобальные массивы

$_GET, $_POST, $_REQUEST, $_FILES, $_SERVER

Суперглобальные массивы

Суперглобальные массивы доступны в любой области видимости без global.

Массив Описание
$_GET Параметры URL (query string)
$_POST Данные из POST-формы
$_REQUEST GET + POST + COOKIE
$_FILES Загруженные файлы
$_SERVER Информация о сервере и запросе
$_ENV Переменные окружения
$_COOKIE Cookies
$_SESSION Данные сессии
$GLOBALS Все глобальные переменные

$_GET и $_POST

<?php
declare(strict_types=1);

// URL: /search?query=php&page=2
echo $_GET['query'] ?? '';  // 'php'
echo $_GET['page'] ?? '1';  // '2'

// POST form data
// <form method="POST">
//   <input name="username" value="Alice">
//   <input name="password" value="secret">
// </form>
echo $_POST['username'] ?? '';
echo $_POST['password'] ?? '';

// $_REQUEST — merges GET, POST, and COOKIE
// Order depends on request_order ini setting (default: "GP")
echo $_REQUEST['query'] ?? '';

// Array inputs
// <form method="POST">
//   <input name="colors[]" value="red">
//   <input name="colors[]" value="blue">
//   <select name="items[fruit]"><option>apple</option></select>
// </form>
$colors = $_POST['colors'] ?? [];  // ['red', 'blue']
$fruit = $_POST['items']['fruit'] ?? '';  // 'apple'

Ловушка экзамена: $_REQUEST содержит данные из GET, POST и COOKIE. Порядок перезаписи определяется директивой request_order (по умолчанию "GP" — GET потом POST). POST перезапишет одноимённые ключи из GET.

$_SERVER

<?php
declare(strict_types=1);

// Common $_SERVER values
echo $_SERVER['REQUEST_METHOD'];    // GET, POST, PUT, DELETE
echo $_SERVER['REQUEST_URI'];       // /page?query=test
echo $_SERVER['QUERY_STRING'];      // query=test
echo $_SERVER['HTTP_HOST'];         // example.com
echo $_SERVER['SERVER_NAME'];       // example.com
echo $_SERVER['SERVER_PORT'];       // 80, 443
echo $_SERVER['REMOTE_ADDR'];       // Client IP
echo $_SERVER['HTTP_USER_AGENT'];   // Browser info
echo $_SERVER['HTTP_REFERER'];      // Previous page (if set)
echo $_SERVER['HTTPS'];             // 'on' if HTTPS
echo $_SERVER['DOCUMENT_ROOT'];     // /var/www/html
echo $_SERVER['SCRIPT_FILENAME'];   // /var/www/html/index.php
echo $_SERVER['PHP_SELF'];          // /index.php
echo $_SERVER['SCRIPT_NAME'];       // /index.php
echo $_SERVER['PATH_INFO'];         // Extra path info

// Detecting AJAX requests
$isAjax = ($_SERVER['HTTP_X_REQUESTED_WITH'] ?? '') === 'XMLHttpRequest';

// Detecting HTTPS
$isHttps = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')
    || ($_SERVER['SERVER_PORT'] ?? 0) == 443;

Запомни: $_SERVER['PHP_SELF'] может содержать пользовательский ввод (path injection)! Не используйте его в атрибуте action без экранирования. $_SERVER['HTTP_REFERER'] может отсутствовать или быть подделан — не полагайтесь на него для безопасности.

$_FILES — загрузка файлов

<?php
declare(strict_types=1);

// HTML: <form method="POST" enctype="multipart/form-data">
//         <input type="file" name="avatar">
//       </form>

// Single file upload
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['avatar'])) {
    $file = $_FILES['avatar'];

    // Structure of $_FILES['avatar']:
    // [
    //     'name'     => 'photo.jpg',      — original filename
    //     'type'     => 'image/jpeg',      — MIME type (from browser, not reliable!)
    //     'tmp_name' => '/tmp/phpXXXXXX',  — temp file on server
    //     'error'    => UPLOAD_ERR_OK,     — error code
    //     'size'     => 123456,            — file size in bytes
    // ]

    // Check for errors
    if ($file['error'] !== UPLOAD_ERR_OK) {
        $errorMessages = [
            UPLOAD_ERR_INI_SIZE => 'Exceeds upload_max_filesize',
            UPLOAD_ERR_FORM_SIZE => 'Exceeds MAX_FILE_SIZE',
            UPLOAD_ERR_PARTIAL => 'File partially uploaded',
            UPLOAD_ERR_NO_FILE => 'No file uploaded',
            UPLOAD_ERR_NO_TMP_DIR => 'Missing temp folder',
            UPLOAD_ERR_CANT_WRITE => 'Failed to write',
            UPLOAD_ERR_EXTENSION => 'Blocked by extension',
        ];
        throw new RuntimeException($errorMessages[$file['error']] ?? 'Unknown error');
    }

    // ALWAYS use move_uploaded_file (security check)
    $destination = '/var/www/uploads/' . bin2hex(random_bytes(16)) . '.jpg';
    if (!move_uploaded_file($file['tmp_name'], $destination)) {
        throw new RuntimeException('Failed to move file');
    }
}

// Multiple files: <input type="file" name="photos[]" multiple>
if (isset($_FILES['photos'])) {
    $count = count($_FILES['photos']['name']);
    for ($i = 0; $i < $count; $i++) {
        if ($_FILES['photos']['error'][$i] === UPLOAD_ERR_OK) {
            $tmpName = $_FILES['photos']['tmp_name'][$i];
            $origName = $_FILES['photos']['name'][$i];
            // Process each file...
        }
    }
}

Ловушка экзамена: Множественная загрузка файлов (name="files[]") создаёт массив с ПЕРЕВЁРНУТОЙ структурой: $_FILES['files']['name'][0], $_FILES['files']['tmp_name'][0] и т.д. Это НЕ $_FILES['files'][0]['name']!

Определение метода запроса

<?php
declare(strict_types=1);

$method = $_SERVER['REQUEST_METHOD'];

match ($method) {
    'GET' => handleGet(),
    'POST' => handlePost(),
    'PUT' => handlePut(),
    'DELETE' => handleDelete(),
    default => http_response_code(405),
};

// For PUT/DELETE, read body from php://input
if ($method === 'PUT') {
    $body = file_get_contents('php://input');
    $data = json_decode($body, true, 512, JSON_THROW_ON_ERROR);
}

Вопросы с экзамена ZCE

Проверь себя

5 из 12

Один из способов форматирования валют в PHP — использование встроенной функции money_format(). Перед использованием необходимо установить локаль для нужной валюты. Каков вывод следующего PHP-скрипта? Название валюты для en_US — USD, символ — $. В одном долларе 100 центов. ```php setlocale(LC_MONETARY, 'en_US'); $amt = 100; echo money_format('%.2n', $amt); ```

Какую из следующих директив можно использовать для включения производительности байт-кеша?

Какие типы элементов формы могут быть исключены из HTTP-запроса?

Поскольку PHP динамически преобразует переменные в разные типы, нужно быть внимательным при сравнении строк. Каков вывод следующего PHP-скрипта? ```php $str1 = '57 channels'; $str2 = '1/2 a pack of cigarettes'; $str3 = '0x10'; if ($str1 == 57) { echo 'a'; } else { echo 'b'; } if ($str2 == 0.5) { echo 'c'; } else if ($str2 == 1) { echo 'd'; } else { echo 'e'; } if ($str3 == 0) { echo 'f'; } else if ($str3 == 16) { echo 'g'; } else if ($str3 == 0x10) { echo 'h'; } ```

Что делает `move_uploaded_file`?