21. PHP – Superglobals


Superglobals (superzmienne globalne) to specjalne wbudowane tablice w PHP, które są automatycznie dostępne w każdym  zakresie (scope) – w funkcjach, metodach, klasach i skryptach.

Nie musisz ich deklarować ani importować za pomocą słowa kluczowego global.

Poznaliśmy już tablice $_GET, $_POST, $_SESSION i $_COOKIE. 

UWAGA: ZAWSZE waliduj dane – nigdy nie ufaj danym od użytkownika

Lista wszystkich Superglobals w PHP

PHP udostępnia 9 superglobalnych tablic:

SuperglobalZastosowanieKiedy używać
$_GETDane z URL (query string)Parametry URL, linki, wyszukiwanie
$_POSTDane z formularzy POSTFormularze, logowanie, rejestracja
$_REQUESTDane z GET, POST i COOKIERzadko – lepiej używać $_GET lub $_POST
$_FILESPrzesłane plikiUpload plików, zdjęć, dokumentów
$_SESSIONDane sesji użytkownikaPrzechowywanie stanu zalogowania
$_COOKIECookies przeglądarkiZapamiętywanie preferencji użytkownika
$_SERVERInformacje o serwerze i żądaniuAdres IP, user agent, ścieżki
$_ENVZmienne środowiskoweKonfiguracja, dane wrażliwe
$GLOBALSWszystkie zmienne globalneDostęp do zmiennych globalnych

1. $_GET – Dane z URL (Query String)

Dane są przekazywane w adresie URL po znaku ? w formacie klucz=wartość, oddzielone znakiem &.

profil.php?id=5&username=ProGamer&sort=level

Odczytywanie danych z $_GET

<?php
// profil.php

// Sprawdzamy czy parametr istnieje
if (isset($_GET['id'])) {
    $player_id = (int)$_GET['id']; // Rzutowanie na int dla bezpieczeństwa
    echo "ID gracza: {$player_id}<br>";
} else {
    echo "Brak parametru ID w URL<br>";
}

// Operator null coalescing (PHP 7+)
$username = $_GET['username'] ?? 'Nieznany';
$sort = $_GET['sort'] ?? 'id';

echo "Username: {$username}<br>";
echo "Sortowanie: {$sort}<br>";

// Wyświetl wszystkie parametry GET
echo "<pre>";
print_r($_GET);
echo "</pre>";
?>

Wyjście dla URL profil.php?id=5&username=ProGamer&sort=level:

ID gracza: 5
Username: ProGamer
Sortowanie: level

Array
(
    [id] => 5
    [username] => ProGamer
    [sort] => level
)

Przykład 1: Wyszukiwarka z parametrami GET

<?php
mysqli_report(MYSQLI_REPORT_OFF);
$db = @new mysqli('localhost', 'root', '', 'gaming_hub');

if ($db->connect_error) {
    die('Błąd połączenia');
}

$db->set_charset('utf8mb4');

// Pobieramy parametry z URL
if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['q'])) {
    $search_query = trim($_GET['q']);
    $min_level = (int)($_GET['min_level'] ?? 0);
    $rank = $_GET['rank'] ?? '';
    
    if (!empty($search_query)) {
        
        // Budujemy zapytanie dynamicznie
        $sql = "SELECT * FROM players WHERE (username LIKE ? OR email LIKE ?)";
        $params = ["%{$search_query}%", "%{$search_query}%"];
        $types = "ss";
        
        if ($min_level > 0) {
            $sql .= " AND level >= ?";
            $types .= "i";
            $params[] = $min_level;
        }
        
        if (!empty($rank)) {
            $sql .= " AND rank_name = ?";
            $types .= "s";
            $params[] = $rank;
        }
        
        $sql .= " ORDER BY level DESC LIMIT 20";
        
        $stmt = $db->prepare($sql);
        $stmt->bind_param($types, ...$params);
        $stmt->execute();
        $wynik = $stmt->get_result();
        
        $safe_query = htmlspecialchars($search_query);
        echo "<h2>Wyniki wyszukiwania dla: \"{$safe_query}\"</h2>";
        
        if ($wynik->num_rows > 0) {
            echo "<p>Znaleziono: {$wynik->num_rows} graczy</p>";
            
            while ($gracz = $wynik->fetch_assoc()) {
                $username = htmlspecialchars($gracz['username']);
                echo "<div style='background:#f4f4f4; padding:10px; margin:5px 0;'>";
                echo "<strong>{$username}</strong> - Level: {$gracz['level']}, Rank: {$gracz['rank_name']}<br>";
                echo "<a href='profil.php?id={$gracz['id']}'>Zobacz profil</a>";
                echo "</div>";
            }
        } else {
            echo "<p>Nie znaleziono graczy</p>";
        }
        
        $stmt->close();
    }
}

$db->close();
?>

<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <title>Wyszukiwarka graczy</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 800px;
            margin: 50px auto;
            padding: 20px;
        }
        .search-form {
            background: #f4f4f4;
            padding: 20px;
            border-radius: 5px;
            margin-bottom: 30px;
        }
        input, select {
            padding: 10px;
            margin: 5px;
            border: 1px solid #ddd;
            border-radius: 4px;
        }
        button {
            padding: 10px 20px;
            background: #667eea;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }
        button:hover {
            background: #764ba2;
        }
    </style>
</head>
<body>

<h1>Wyszukiwarka graczy</h1>

<form method="GET" class="search-form">
    <input type="text" 
           name="q" 
           placeholder="Wpisz nick lub email" 
           value="<?= htmlspecialchars($_GET['q'] ?? '') ?>"
           required>
    
    <input type="number" 
           name="min_level" 
           placeholder="Min. poziom"
           min="1"
           value="<?= htmlspecialchars($_GET['min_level'] ?? '') ?>">
    
    <select name="rank">
        <option value="">Wszystkie rangi</option>
        <option value="Bronze" <?= ($_GET['rank'] ?? '') == 'Bronze' ? 'selected' : '' ?>>Bronze</option>
        <option value="Silver" <?= ($_GET['rank'] ?? '') == 'Silver' ? 'selected' : '' ?>>Silver</option>
        <option value="Gold" <?= ($_GET['rank'] ?? '') == 'Gold' ? 'selected' : '' ?>>Gold</option>
        <option value="Diamond" <?= ($_GET['rank'] ?? '') == 'Diamond' ? 'selected' : '' ?>>Diamond</option>
    </select>
    
    <button type="submit">Szukaj</button>
</form>

<p><small>Przykłady wyszukiwań:</small></p>
<ul>
    <li><a href="?q=Pro">?q=Pro</a></li>
    <li><a href="?q=Gamer&min_level=20">?q=Gamer&min_level=20</a></li>
    <li><a href="?q=Test&rank=Gold">?q=Test&rank=Gold</a></li>
</ul>

</body>
</html>

Kiedy używać $_GET?

  • Wyszukiwanie i filtrowanie
  • Paginacja (?page=2)
  • Sortowanie (?sort=date&order=desc)
  • Linki do konkretnych zasobów (?id=123)
  • Parametry, które użytkownik może udostępnić (share)

Nie stosujemy do:

  • Haseł i danych wrażliwych (widoczne w URL!)
  • Modyfikacji danych w bazie (INSERT, UPDATE, DELETE)
  • Dużych ilości danych (limit ~2000 znaków)

2. $_POST – Dane z formularzy POST

Dane są wysyłane w ciele żądania HTTP (nie w URL), więc są niewidoczne dla użytkownika.

Odczytywanie danych z $_POST

<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    
    // Sprawdzamy czy pole istnieje
    if (isset($_POST['username'])) {
        $username = trim($_POST['username']);
        echo "Username: {$username}<br>";
    }
    
    // Operator null coalescing
    $email = trim($_POST['email'] ?? '');
    $age = (int)($_POST['age'] ?? 0);
    
    echo "Email: {$email}<br>";
    echo "Wiek: {$age}<br>";
    
    // Wyświetl wszystkie dane POST
    echo "<pre>";
    print_r($_POST);
    echo "</pre>";
}
?>

Formularz rejestracji z walidacją

<?php
session_start();

mysqli_report(MYSQLI_REPORT_OFF);
$db = @new mysqli('localhost', 'root', '', 'gaming_hub');

if ($db->connect_error) {
    die('Błąd połączenia');
}

$db->set_charset('utf8mb4');

$errors = [];

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    
    // Pobieramy wszystkie dane z formularza
    $username = trim($_POST['username'] ?? '');
    $email = trim($_POST['email'] ?? '');
    $password = $_POST['password'] ?? '';
    $password_confirm = $_POST['password_confirm'] ?? '';
    $age = (int)($_POST['age'] ?? 0);
    $terms = isset($_POST['terms']) ? 1 : 0; // Checkbox
    
    // Walidacja
    if (empty($username)) {
        $errors[] = "Username jest wymagany";
    } elseif (strlen($username) < 3) {
        $errors[] = "Username musi mieć min. 3 znaki";
    }
    
    if (empty($email)) {
        $errors[] = "Email jest wymagany";
    } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        $errors[] = "Nieprawidłowy format email";
    }
    
    if (empty($password)) {
        $errors[] = "Hasło jest wymagane";
    } elseif (strlen($password) < 8) {
        $errors[] = "Hasło musi mieć min. 8 znaków";
    }
    
    if ($password !== $password_confirm) {
        $errors[] = "Hasła nie są identyczne";
    }
    
    if ($age < 13) {
        $errors[] = "Musisz mieć co najmniej 13 lat";
    }
    
    if (!$terms) {
        $errors[] = "Musisz zaakceptować regulamin";
    }
    
    // Jeśli brak błędów - zapisujemy
    if (empty($errors)) {
        
        // Sprawdzamy czy username już istnieje
        $stmt = $db->prepare("SELECT id FROM users WHERE username = ?");
        $stmt->bind_param("s", $username);
        $stmt->execute();
        $stmt->store_result();
        
        if ($stmt->num_rows > 0) {
            $errors[] = "Username '{$username}' jest już zajęty";
        }
        $stmt->close();
        
        if (empty($errors)) {
            $password_hash = password_hash($password, PASSWORD_DEFAULT);
            
            $stmt = $db->prepare("INSERT INTO users (username, email, password, age, created_at) VALUES (?, ?, ?, ?, NOW())");
            $stmt->bind_param("sssi", $username, $email, $password_hash, $age);
            
            if ($stmt->execute()) {
                $new_user_id = $stmt->insert_id;
                
                $stmt->close();
                $db->close();
                
                $_SESSION['registration_success'] = "Konto utworzone pomyślnie!";
                
                header("Location: logowanie.php");
                exit;
            } else {
                $errors[] = "Błąd podczas rejestracji";
            }
            
            $stmt->close();
        }
    }
}

$db->close();
?>

<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <title>Rejestracja</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        body {
            font-family: Arial, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            padding: 20px;
        }
        .container {
            background: white;
            padding: 40px;
            border-radius: 10px;
            box-shadow: 0 10px 25px rgba(0,0,0,0.2);
            max-width: 500px;
            width: 100%;
        }
        h1 {
            text-align: center;
            color: #333;
            margin-bottom: 30px;
        }
        .form-group {
            margin-bottom: 20px;
        }
        label {
            display: block;
            margin-bottom: 5px;
            color: #555;
            font-weight: 500;
        }
        input[type="text"],
        input[type="email"],
        input[type="password"],
        input[type="number"] {
            width: 100%;
            padding: 12px;
            border: 1px solid #ddd;
            border-radius: 5px;
            font-size: 14px;
        }
        input:focus {
            outline: none;
            border-color: #667eea;
        }
        .checkbox-group {
            display: flex;
            align-items: center;
            gap: 10px;
        }
        .checkbox-group input[type="checkbox"] {
            width: 20px;
            height: 20px;
            cursor: pointer;
        }
        .checkbox-group label {
            margin: 0;
            cursor: pointer;
        }
        button {
            width: 100%;
            padding: 12px;
            background: #667eea;
            color: white;
            border: none;
            border-radius: 5px;
            font-size: 16px;
            font-weight: bold;
            cursor: pointer;
        }
        button:hover {
            background: #764ba2;
        }
        .error {
            background: #f8d7da;
            color: #721c24;
            padding: 15px;
            border-radius: 5px;
            margin-bottom: 20px;
            border-left: 4px solid #f5c6cb;
        }
        .error ul {
            margin-left: 20px;
        }
    </style>
</head>
<body>

<div class="container">
    <h1>Rejestracja</h1>
    
    <?php if (!empty($errors)): ?>
        <div class="error">
            <strong>Błędy walidacji:</strong>
            <ul>
                <?php foreach ($errors as $error): ?>
                    <li><?= htmlspecialchars($error) ?></li>
                <?php endforeach; ?>
            </ul>
        </div>
    <?php endif; ?>
    
    <form method="POST">
        <div class="form-group">
            <label>Username:</label>
            <input type="text" 
                   name="username" 
                   value="<?= htmlspecialchars($_POST['username'] ?? '') ?>"
                   required>
        </div>
        
        <div class="form-group">
            <label>Email:</label>
            <input type="email" 
                   name="email"
                   value="<?= htmlspecialchars($_POST['email'] ?? '') ?>"
                   required>
        </div>
        
        <div class="form-group">
            <label>Hasło:</label>
            <input type="password" 
                   name="password"
                   required>
        </div>
        
        <div class="form-group">
            <label>Powtórz hasło:</label>
            <input type="password" 
                   name="password_confirm"
                   required>
        </div>
        
        <div class="form-group">
            <label>Wiek:</label>
            <input type="number" 
                   name="age"
                   min="13"
                   max="120"
                   value="<?= htmlspecialchars($_POST['age'] ?? '') ?>"
                   required>
        </div>
        
        <div class="form-group">
            <div class="checkbox-group">
                <input type="checkbox" 
                       name="terms" 
                       id="terms"
                       <?= isset($_POST['terms']) ? 'checked' : '' ?>
                       required>
                <label for="terms">Akceptuję regulamin</label>
            </div>
        </div>
        
        <button type="submit">Zarejestruj się</button>
    </form>
</div>

</body>
</html>

Kiedy używać $_POST?

  • Logowanie i rejestracja
  • Formularze kontaktowe
  • Modyfikacja danych (INSERT, UPDATE, DELETE)
  • Przesyłanie dużych ilości danych
  • Dane wrażliwe (hasła, dane osobowe)

Złe zastosowania:

  • Wyszukiwanie (lepiej GET – możliwość udostępnienia linku)
  • Linki do konkretnych stron (GET jest lepsze)

$_REQUEST – Połączenie GET, POST i COOKIE

$_REQUEST zawiera dane z $_GET$_POST i $_COOKIE.

<?php
// Przykład: odbiera dane zarówno z GET jak i POST
$search = $_REQUEST['search'] ?? '';

echo "Wartość search: {$search}";
?>

UWAGA: $_REQUEST jest niezalecany ze względów bezpieczeństwa. Lepiej użyć konkretnej tablicy ($_GET lub $_POST).

4. $_FILES – Przesyłanie plików

Struktura $_FILES

Gdy użytkownik wysyła plik, PHP automatycznie wypełnia tablicę $_FILES:

$_FILES['nazwa_pola'] = [
    'name' => 'oryginalnanazwa.jpg',      // Nazwa pliku
    'type' => 'image/jpeg',               // Typ MIME
    'tmp_name' => '/tmp/phpXXXXXX',       // Tymczasowa lokalizacja
    'error' => 0,                         // Kod błędu (0 = OK)
    'size' => 245678                      // Rozmiar w bajtach
];

Przykład 3: Upload zdjęcia profilowego

<?php
session_start();

$errors = [];
$success = false;

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['avatar'])) {
    
    $file = $_FILES['avatar'];
    
    // Sprawdzamy czy nie ma błędu uploadu
    if ($file['error'] !== UPLOAD_ERR_OK) {
        $errors[] = "Błąd podczas uploadu pliku (kod: {$file['error']})";
    } else {
        
        // Walidacja rozmiaru (max 2MB)
        $max_size = 2 * 1024 * 1024; // 2MB w bajtach
        if ($file['size'] > $max_size) {
            $errors[] = "Plik jest za duży (max 2MB)";
        }
        
        // Walidacja typu pliku
        $allowed_types = ['image/jpeg', 'image/png', 'image/gif'];
        if (!in_array($file['type'], $allowed_types)) {
            $errors[] = "Nieprawidłowy typ pliku (dozwolone: JPG, PNG, GIF)";
        }
        
        // Dodatkowa walidacja przez rozszerzenie
        $file_extension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
        $allowed_extensions = ['jpg', 'jpeg', 'png', 'gif'];
        if (!in_array($file_extension, $allowed_extensions)) {
            $errors[] = "Nieprawidłowe rozszerzenie pliku";
        }
        
        // Jeśli brak błędów - zapisujemy plik
        if (empty($errors)) {
            
            // Generujemy unikalną nazwę pliku
            $new_filename = uniqid('avatar_', true) . '.' . $file_extension;
            $upload_dir = 'uploads/avatars/';
            
            // Tworzymy katalog jeśli nie istnieje
            if (!is_dir($upload_dir)) {
                mkdir($upload_dir, 0755, true);
            }
            
            $destination = $upload_dir . $new_filename;
            
            // Przenosimy plik z lokalizacji tymczasowej
            if (move_uploaded_file($file['tmp_name'], $destination)) {
                $success = true;
                $uploaded_file_path = $destination;
                
                // Możesz zapisać ścieżkę do bazy danych
                // UPDATE users SET avatar = ? WHERE id = ?
                
            } else {
                $errors[] = "Nie udało się zapisać pliku";
            }
        }
    }
}
?>

<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <title>Upload avatara</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 600px;
            margin: 50px auto;
            padding: 20px;
        }
        .upload-form {
            background: #f4f4f4;
            padding: 30px;
            border-radius: 10px;
        }
        input[type="file"] {
            margin: 20px 0;
            padding: 10px;
            border: 2px dashed #ddd;
            border-radius: 5px;
            width: 100%;
            cursor: pointer;
        }
        button {
            padding: 12px 30px;
            background: #667eea;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            font-size: 16px;
        }
        button:hover {
            background: #764ba2;
        }
        .error {
            background: #f8d7da;
            color: #721c24;
            padding: 15px;
            border-radius: 5px;
            margin-bottom: 20px;
        }
        .success {
            background: #d4edda;
            color: #155724;
            padding: 15px;
            border-radius: 5px;
            margin-bottom: 20px;
        }
        .preview {
            margin-top: 20px;
            text-align: center;
        }
        .preview img {
            max-width: 300px;
            border-radius: 10px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }
    </style>
</head>
<body>

<h1>Upload zdjęcia profilowego</h1>

<?php if (!empty($errors)): ?>
    <div class="error">
        <strong>Błędy:</strong>
        <ul>
            <?php foreach ($errors as $error): ?>
                <li><?= htmlspecialchars($error) ?></li>
            <?php endforeach; ?>
        </ul>
    </div>
<?php endif; ?>

<?php if ($success): ?>
    <div class="success">
        Plik został przesłany pomyślnie!
        <div class="preview">
            <img src="<?= htmlspecialchars($uploaded_file_path) ?>" alt="Avatar">
        </div>
    </div>
<?php endif; ?>

<form method="POST" enctype="multipart/form-data" class="upload-form">
    <p>Wybierz zdjęcie (max 2MB, JPG/PNG/GIF):</p>
    <input type="file" name="avatar" accept="image/*" required>
    
    <button type="submit">Prześlij plik</button>
</form>

<p><small>Informacje o pliku:</small></p>
<?php if (isset($_FILES['avatar'])): ?>
    <pre><?php print_r($_FILES['avatar']); ?></pre>
<?php endif; ?>

</body>
</html>

WAŻNE: Formularz uploadu MUSI mieć enctype="multipart/form-data"!

Kody błędów $_FILES

KodStałaZnaczenie
0UPLOAD_ERR_OKSukces
1UPLOAD_ERR_INI_SIZEPlik większy niż upload_max_filesize w php.ini
2UPLOAD_ERR_FORM_SIZEPlik większy niż MAX_FILE_SIZE w formularzu
3UPLOAD_ERR_PARTIALPlik został przesłany tylko częściowo
4UPLOAD_ERR_NO_FILENie przesłano pliku
6UPLOAD_ERR_NO_TMP_DIRBrak folderu tymczasowego
7UPLOAD_ERR_CANT_WRITENie można zapisać pliku na dysku
8UPLOAD_ERR_EXTENSIONRozszerzenie PHP zablokowało upload

5. $_SESSION – Przechowywanie danych użytkownika

Sesje pozwalają przechowywać dane między różnymi stronami dla konkretnego użytkownika. Informacje dodatkowe w temacie PHP – obsługa cookies i sesje

<?php
// ZAWSZE na początku pliku!
session_start();

// Zapisywanie danych w sesji
$_SESSION['user_id'] = 123;
$_SESSION['username'] = 'ProGamer';
$_SESSION['logged_in'] = true;

// Odczytywanie danych z sesji
$user_id = $_SESSION['user_id'] ?? 0;
$username = $_SESSION['username'] ?? 'Gość';

// Sprawdzanie czy klucz istnieje
if (isset($_SESSION['logged_in'])) {
    echo "Jesteś zalogowany jako: {$username}";
} else {
    echo "Nie jesteś zalogowany";
}

// Usuwanie konkretnego klucza
unset($_SESSION['username']);

// Niszczenie całej sesji
session_destroy();
?>

System logowania z sesją

Plik: logowanie.php

<?php
session_start();

// Jeśli użytkownik już zalogowany - przekieruj
if (isset($_SESSION['logged_in']) && $_SESSION['logged_in'] === true) {
    header("Location: panel.php");
    exit;
}

mysqli_report(MYSQLI_REPORT_OFF);
$db = @new mysqli('localhost', 'root', '', 'gaming_hub');
$db->set_charset('utf8mb4');

$errors = [];

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    
    $username = trim($_POST['username'] ?? '');
    $password = $_POST['password'] ?? '';
    
    if (empty($username)) {
        $errors[] = "Username jest wymagany";
    }
    
    if (empty($password)) {
        $errors[] = "Hasło jest wymagane";
    }
    
    if (empty($errors)) {
        
        $stmt = $db->prepare("SELECT id, username, email, password FROM users WHERE username = ?");
        $stmt->bind_param("s", $username);
        $stmt->execute();
        $wynik = $stmt->get_result();
        $user = $wynik->fetch_assoc();
        $stmt->close();
        
        if ($user && password_verify($password, $user['password'])) {
            
            // Zapisz dane w sesji
            $_SESSION['user_id'] = $user['id'];
            $_SESSION['username'] = $user['username'];
            $_SESSION['email'] = $user['email'];
            $_SESSION['logged_in'] = true;
            $_SESSION['login_time'] = time();
            
            $db->close();
            
            header("Location: panel.php");
            exit;
            
        } else {
            $errors[] = "Nieprawidłowy username lub hasło";
        }
    }
}

$db->close();
?>

<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <title>Logowanie</title>
</head>
<body>

<h1>Logowanie</h1>

<?php if (!empty($errors)): ?>
    <div style="background:#f8d7da; padding:15px; color:#721c24;">
        <ul>
            <?php foreach ($errors as $error): ?>
                <li><?= htmlspecialchars($error) ?></li>
            <?php endforeach; ?>
        </ul>
    </div>
<?php endif; ?>

<form method="POST">
    <label>Username:</label><br>
    <input type="text" name="username" value="<?= htmlspecialchars($_POST['username'] ?? '') ?>" required><br><br>
    
    <label>Hasło:</label><br>
    <input type="password" name="password" required><br><br>
    
    <button type="submit">Zaloguj</button>
</form>

</body>
</html>

Plik: panel.php

<?php
session_start();

// Sprawdź czy użytkownik zalogowany
if (!isset($_SESSION['logged_in']) || $_SESSION['logged_in'] !== true) {
    header("Location: logowanie.php");
    exit;
}

$username = htmlspecialchars($_SESSION['username']);
$user_id = $_SESSION['user_id'];
$login_time = $_SESSION['login_time'];

$time_elapsed = time() - $login_time;
$minutes = floor($time_elapsed / 60);
?>

<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <title>Panel użytkownika</title>
</head>
<body>

<h1>Witaj, <?= $username ?>!</h1>

<p>Twoje ID: <?= $user_id ?></p>
<p>Zalogowany od: <?= $minutes ?> minut</p>

<p><a href="wyloguj.php">Wyloguj się</a></p>

<h2>Dane sesji:</h2>
<pre><?php print_r($_SESSION); ?></pre>

</body>
</html>

Plik: wyloguj.php

<?php
session_start();

// Usuń wszystkie dane sesji
$_SESSION = [];

// Usuń cookie sesyjne
if (isset($_COOKIE[session_name()])) {
    setcookie(session_name(), '', time() - 3600, '/');
}

// Zniszcz sesję
session_destroy();

// Przekieruj do logowania
header("Location: logowanie.php");
exit;
?>

6. $_COOKIE – Przechowywanie danych w przeglądarce

Cookies to małe pliki tekstowe przechowywane w przeglądarce użytkownika. Więcej w temacie PHP – obsługa cookies i sesje

Ustawianie cookies

<?php
// setcookie(nazwa, wartość, wygasa, ścieżka, domena, secure, httponly)

// Prosty cookie na 30 dni
setcookie('username', 'ProGamer', time() + (30 * 24 * 60 * 60));

// Bezpieczny cookie
setcookie('session_token', 'abc123xyz', [
    'expires' => time() + 3600,     // 1 godzina
    'path' => '/',                   // Dostępny w całej domenie
    'domain' => '',                  // Aktualna domena
    'secure' => true,                // Tylko HTTPS
    'httponly' => true,              // Niedostępny dla JavaScript
    'samesite' => 'Strict'           // Ochrona CSRF
]);
?>

UWAGA: setcookie() MUSI być wywołane PRZED jakimkolwiek output (echo, HTML)!

Odczytywanie cookies

<?php
// Sprawdzamy czy cookie istnieje
if (isset($_COOKIE['username'])) {
    $username = htmlspecialchars($_COOKIE['username']);
    echo "Witaj ponownie, {$username}!";
} else {
    echo "Witaj po raz pierwszy!";
}

// Operator null coalescing
$theme = $_COOKIE['theme'] ?? 'light';
echo "Aktywny motyw: {$theme}";
?>

Usuwanie cookies

<?php
// Ustaw datę wygaśnięcia w przeszłości
setcookie('username', '', time() - 3600);

// Lub
setcookie('username', '', 1);
?>

„Zapamiętaj mnie” przy logowaniu

<?php
session_start();

// Sprawdź czy istnieje cookie "remember_me"
if (!isset($_SESSION['logged_in']) && isset($_COOKIE['remember_token'])) {
    
    mysqli_report(MYSQLI_REPORT_OFF);
    $db = @new mysqli('localhost', 'root', '', 'gaming_hub');
    $db->set_charset('utf8mb4');
    
    $token = $_COOKIE['remember_token'];
    
    // Sprawdź token w bazie (w prawdziwej aplikacji przechowuj hash tokenu!)
    $stmt = $db->prepare("SELECT id, username, email FROM users WHERE remember_token = ?");
    $stmt->bind_param("s", $token);
    $stmt->execute();
    $wynik = $stmt->get_result();
    $user = $wynik->fetch_assoc();
    $stmt->close();
    $db->close();
    
    if ($user) {
        // Automatyczne logowanie
        $_SESSION['user_id'] = $user['id'];
        $_SESSION['username'] = $user['username'];
        $_SESSION['email'] = $user['email'];
        $_SESSION['logged_in'] = true;
    }
}

$errors = [];

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    
    mysqli_report(MYSQLI_REPORT_OFF);
    $db = @new mysqli('localhost', 'root', '', 'gaming_hub');
    $db->set_charset('utf8mb4');
    
    $username = trim($_POST['username'] ?? '');
    $password = $_POST['password'] ?? '';
    $remember = isset($_POST['remember']) ? true : false;
    
    // Walidacja i sprawdzanie użytkownika...
    
    $stmt = $db->prepare("SELECT id, username, email, password FROM users WHERE username = ?");
    $stmt->bind_param("s", $username);
    $stmt->execute();
    $wynik = $stmt->get_result();
    $user = $wynik->fetch_assoc();
    $stmt->close();
    
    if ($user && password_verify($password, $user['password'])) {
        
        // Zapisz w sesji
        $_SESSION['user_id'] = $user['id'];
        $_SESSION['username'] = $user['username'];
        $_SESSION['logged_in'] = true;
        
        // Jeśli zaznaczono "Zapamiętaj mnie"
        if ($remember) {
            $token = bin2hex(random_bytes(32)); // Generuj bezpieczny token
            
            // Zapisz token w bazie
            $stmt_token = $db->prepare("UPDATE users SET remember_token = ? WHERE id = ?");
            $stmt_token->bind_param("si", $token, $user['id']);
            $stmt_token->execute();
            $stmt_token->close();
            
            // Ustaw cookie na 30 dni
            setcookie('remember_token', $token, [
                'expires' => time() + (30 * 24 * 60 * 60),
                'path' => '/',
                'secure' => true,
                'httponly' => true,
                'samesite' => 'Strict'
            ]);
        }
        
        $db->close();
        
        header("Location: panel.php");
        exit;
    } else {
        $errors[] = "Nieprawidłowy username lub hasło";
    }
    
    $db->close();
}
?>

<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <title>Logowanie</title>
</head>
<body>

<h1>Logowanie</h1>

<form method="POST">
    <label>Username:</label><br>
    <input type="text" name="username" required><br><br>
    
    <label>Hasło:</label><br>
    <input type="password" name="password" required><br><br>
    
    <label>
        <input type="checkbox" name="remember">
        Zapamiętaj mnie (30 dni)
    </label><br><br>
    
    <button type="submit">Zaloguj</button>
</form>

</body>
</html>

7. $_SERVER – Informacje o serwerze i żądaniu

$_SERVER zawiera informacje o środowisku serwera, nagłówkach HTTP i żądaniu.

<?php
// Metoda HTTP
echo $_SERVER['REQUEST_METHOD']; // GET, POST, PUT, DELETE

// URL i ścieżki
echo $_SERVER['REQUEST_URI'];         // /profil.php?id=5
echo $_SERVER['PHP_SELF'];            // /profil.php
echo $_SERVER['SCRIPT_NAME'];         // /profil.php
echo $_SERVER['QUERY_STRING'];        // id=5&sort=level

// Informacje o kliencie
echo $_SERVER['REMOTE_ADDR'];         // Adres IP użytkownika (np. 192.168.1.1)
echo $_SERVER['HTTP_USER_AGENT'];     // Przeglądarka (np. Mozilla/5.0...)
echo $_SERVER['HTTP_REFERER'];        // Poprzednia strona (skąd przyszedł)

// Informacje o serwerze
echo $_SERVER['SERVER_NAME'];         // localhost
echo $_SERVER['SERVER_ADDR'];         // 127.0.0.1
echo $_SERVER['SERVER_PORT'];         // 80 lub 443
echo $_SERVER['DOCUMENT_ROOT'];       // C:/xampp/htdocs

// HTTPS
echo $_SERVER['HTTPS'] ?? 'off';      // on jeśli HTTPS

// Nagłówki HTTP
echo $_SERVER['HTTP_ACCEPT'];         // Akceptowane typy treści
echo $_SERVER['HTTP_ACCEPT_LANGUAGE']; // Preferowany język
?>

Wyświetlanie informacji o żądaniu

<?php
function getClientIP() {
    $ip = $_SERVER['REMOTE_ADDR'];
    
    // Sprawdź czy użyto proxy
    if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
        $ip = $_SERVER['HTTP_CLIENT_IP'];
    } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
    }
    
    return $ip;
}

function getBrowser() {
    $user_agent = $_SERVER['HTTP_USER_AGENT'];
    
    if (strpos($user_agent, 'Firefox') !== false) {
        return 'Mozilla Firefox';
    } elseif (strpos($user_agent, 'Chrome') !== false) {
        return 'Google Chrome';
    } elseif (strpos($user_agent, 'Safari') !== false) {
        return 'Safari';
    } elseif (strpos($user_agent, 'Edge') !== false) {
        return 'Microsoft Edge';
    } else {
        return 'Nieznana przeglądarka';
    }
}
?>

<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <title>Informacje o żądaniu</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 800px;
            margin: 50px auto;
            padding: 20px;
        }
        table {
            width: 100%;
            border-collapse: collapse;
        }
        th, td {
            padding: 12px;
            border: 1px solid #ddd;
            text-align: left;
        }
        th {
            background: #667eea;
            color: white;
        }
        tr:hover {
            background: #f5f5f5;
        }
    </style>
</head>
<body>

<h1>Informacje o Twoim żądaniu</h1>

<table>
    <tr>
        <th>Parametr</th>
        <th>Wartość</th>
    </tr>
    <tr>
        <td><strong>Twój adres IP:</strong></td>
        <td><?= htmlspecialchars(getClientIP()) ?></td>
    </tr>
    <tr>
        <td><strong>Przeglądarka:</strong></td>
        <td><?= htmlspecialchars(getBrowser()) ?></td>
    </tr>
    <tr>
        <td><strong>User Agent:</strong></td>
        <td><?= htmlspecialchars($_SERVER['HTTP_USER_AGENT']) ?></td>
    </tr>
    <tr>
        <td><strong>Metoda HTTP:</strong></td>
        <td><?= htmlspecialchars($_SERVER['REQUEST_METHOD']) ?></td>
    </tr>
    <tr>
        <td><strong>Request URI:</strong></td>
        <td><?= htmlspecialchars($_SERVER['REQUEST_URI']) ?></td>
    </tr>
    <tr>
        <td><strong>Query String:</strong></td>
        <td><?= htmlspecialchars($_SERVER['QUERY_STRING'] ?? 'brak') ?></td>
    </tr>
    <tr>
        <td><strong>Protokół:</strong></td>
        <td><?= htmlspecialchars($_SERVER['SERVER_PROTOCOL']) ?></td>
    </tr>
    <tr>
        <td><strong>HTTPS:</strong></td>
        <td><?= isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'TAK' : 'NIE' ?></td>
    </tr>
    <tr>
        <td><strong>Serwer:</strong></td>
        <td><?= htmlspecialchars($_SERVER['SERVER_NAME']) ?></td>
    </tr>
    <tr>
        <td><strong>Port:</strong></td>
        <td><?= htmlspecialchars($_SERVER['SERVER_PORT']) ?></td>
    </tr>
    <tr>
        <td><strong>Document Root:</strong></td>
        <td><?= htmlspecialchars($_SERVER['DOCUMENT_ROOT']) ?></td>
    </tr>
    <tr>
        <td><strong>Skrypt PHP:</strong></td>
        <td><?= htmlspecialchars($_SERVER['SCRIPT_NAME']) ?></td>
    </tr>
    <tr>
        <td><strong>Referer (poprzednia strona):</strong></td>
        <td><?= htmlspecialchars($_SERVER['HTTP_REFERER'] ?? 'brak') ?></td>
    </tr>
    <tr>
        <td><strong>Akceptowany język:</strong></td>
        <td><?= htmlspecialchars($_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? 'brak') ?></td>
    </tr>
</table>

<h2>Wszystkie dane $_SERVER:</h2>
<pre><?php print_r($_SERVER); ?></pre>

</body>
</html>

$_ENV – Zmienne środowiskowe

$_ENV zawiera zmienne środowiskowe systemu operacyjnego. W PHP zwykle używane z plikami .env (przez biblioteki jak vlucas/phpdotenv).

<?php
// Odczytywanie zmiennej środowiskowej
$db_host = $_ENV['DB_HOST'] ?? 'localhost';
$db_user = $_ENV['DB_USER'] ?? 'root';
$db_pass = $_ENV['DB_PASSWORD'] ?? '';

// Lub za pomocą getenv()
$db_name = getenv('DB_NAME');

echo "Host: {$db_host}<br>";
echo "User: {$db_user}<br>";
?>

Przykład pliku .env:

DB_HOST=localhost
DB_USER=root
DB_PASSWORD=secret123
DB_NAME=gaming_hub
APP_ENV=development

9. $GLOBALS – Dostęp do zmiennych globalnych

$GLOBALS to tablica zawierająca wszystkie zmienne globalne.

<?php
$username = "ProGamer";
$level = 50;

function displayInfo() {
    // Dostęp do zmiennych globalnych przez $GLOBALS
    echo "Username: {$GLOBALS['username']}<br>";
    echo "Level: {$GLOBALS['level']}<br>";
}

displayInfo();

// Wyświetl wszystkie zmienne globalne
echo "<pre>";
print_r($GLOBALS);
echo "</pre>";
?>

UWAGA: Używanie $GLOBALS jest niezalecane – lepiej przekazywać zmienne jako parametry funkcji.