Ćwiczenie – include / require w PHP (INF.03)

Po co dzielić projekt na pliki?

Wyobraź sobie stronę z 10 podstronami. Na każdej jest ten sam nagłówek z menu i ten sam stopka. Gdybyś wkleił ten kod 10 razy, każda poprawka wymagałaby edycji 10 plików.

Rozwiązanie: wydziel powtarzający się kod do osobnych plików i dołączaj je przez include lub require. Zmiana w jednym miejscu = zmiana wszędzie.
ℹ️ Na egzaminie INF.03 prawie każde zadanie wymaga pliku config.php (lub db.php) z danymi połączeniowymi, który dołączasz do pozostałych plików. To pierwszy wzorzec który musisz znać na pamięć.

1. include vs require – różnica

Cel: Uczeń rozumie kiedy używać include, a kiedy require.

Polecenie Co się stanie gdy plik nie istnieje? Kiedy używać?
include 'plik.php' ⚠️ Warning – skrypt działa dalej Opcjonalne elementy (np. boczny widget)
require 'plik.php' ❌ Fatal Error – skrypt zatrzymuje się Krytyczne pliki (config, połączenie z bazą)
include_once 'plik.php' ⚠️ Warning – skrypt działa dalej Gdy plik może być dołączany z wielu miejsc
require_once 'plik.php' ❌ Fatal Error – skrypt się zatrzymuje Krytyczne pliki dołączane z wielu miejsc Zalecane
💡 Zasada prosta: do pliku z połączeniem PDO zawsze używaj require_once. Jeśli baza nie działa – skrypt i tak nie ma sensu wykonywać dalej. Przyrostek _once zapobiega podwójnemu dołączeniu (i błędowi "function already defined").
<?php
// include – ostrzeżenie, skrypt działa dalej
include 'nieistniejacy.php';
echo "Ten tekst się wyświetli mimo błędu.";

// require – błąd krytyczny, skrypt się zatrzymuje
require 'nieistniejacy.php';
echo "Ten tekst się NIE wyświetli.";

// require_once – dołącza plik tylko raz, nawet jeśli wywołasz kilka razy
require_once 'db.php';
require_once 'db.php';  // drugie wywołanie jest ignorowane – brak błędu "already defined"
?>
  

2. Struktura projektu egzaminacyjnego

Cel: Uczeń zna typowy układ plików projektu INF.03.

Poniżej typowa struktura projektu egzaminacyjnego. Zapamiętaj ją – na egzaminie masz ograniczony czas i nie możesz zaczynać od zera za każdym razem.
📁 projekt/
  ├── config.php <!-- połączenie PDO, dołączane wszędzie przez require_once -->
  ├── index.php <!-- strona główna – lista rekordów z bazy -->
  ├── dodaj.php <!-- formularz + zapis do bazy (INSERT) -->
  ├── edytuj.php <!-- formularz + aktualizacja rekordu (UPDATE) -->
  ├── usun.php <!-- usunięcie rekordu (DELETE) -->
  ├── styl.css <!-- wspólny arkusz stylów -->
  └── baza.sql <!-- skrypt tworzący bazę i tabelę -->
⚠️ Na egzaminie plik ze strukturą SQL często jest wymagany jako osobny plik nazwa_bazy.sql. Pamiętaj żeby go wygenerować lub napisać ręcznie przed oddaniem pracy.

3. config.php – plik konfiguracyjny

Cel: Uczeń potrafi napisać centralny plik konfiguracyjny projektu.
Plik: config.php
Ten plik piszesz raz i dołączasz do każdego innego pliku przez require_once 'config.php'. Dane połączeniowe zmieniasz tylko tu – nie w każdym pliku osobno.
<?php
// config.php – centralny plik konfiguracyjny projektu
// Dołącz go w każdym pliku: require_once 'config.php';

// Dane połączeniowe z bazą MySQL
define('DB_HOST',    'localhost');
define('DB_NAME',    'sklep');       // nazwa bazy – zmień na swoją
define('DB_USER',    'root');
define('DB_PASS',    '');
define('DB_CHARSET', 'utf8mb4');

// Nawiązanie połączenia PDO
$dsn    = "mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=" . DB_CHARSET;
$opcje  = [
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES   => false,
];

try {
    $pdo = new PDO($dsn, DB_USER, DB_PASS, $opcje);
} catch (PDOException $e) {
    die("Błąd połączenia z bazą: " . $e->getMessage());
}
?>
  
Plik config.php jest gotowy. Zmienna $pdo będzie dostępna w każdym pliku który dołączy ten plik przez require_once.

4. Wspólny nagłówek i stopka

Cel: Uczeń potrafi wydzielić powtarzające się elementy do osobnych plików.
Pliki: header.php + footer.php
<!-- header.php -->
<!DOCTYPE html>
<html lang="pl">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Sklep internetowy</title>
  <link rel="stylesheet" href="styl.css">
</head>
<body>
<header>
  <h1>🛒 Sklep internetowy</h1>
  <nav>
    <a href="index.php">Produkty</a> |
    <a href="dodaj.php">Dodaj produkt</a>
  </nav>
</header>
<main>
  
<!-- footer.php -->
</main>
<footer>
  <p>&copy; 2025 Sklep internetowy</p>
</footer>
</body>
</html>
  
Teraz każda podstrona wygląda tak samo i dzieli ten sam nagłówek + stopkę. Zmieniasz logo? Edytujesz tylko header.php.

5. index.php – składamy projekt w całość

Cel: Uczeń potrafi złożyć kompletną podstronę z wielu plików.
Plik: index.php
To jest wzorzec który powielasz na każdej podstronie. Zauważ jak krótki i czytelny jest plik index.php – cała logika połączenia jest w config.php, cały HTML nagłówka w header.php.
<?php
// index.php – lista produktów
require_once 'config.php';   // $pdo gotowy do użycia

// Pobieramy wszystkie produkty z bazy
$stmt     = $pdo->query("SELECT * FROM produkty ORDER BY nazwa");
$produkty = $stmt->fetchAll();
?>

<!-- Dołączamy wspólny nagłówek -->
<?php require_once 'header.php'; ?>

<h2>Lista produktów</h2>

<?php if (empty($produkty)): ?>
  <p>Brak produktów w bazie.</p>
<?php else: ?>
  <table>
    <tr><th>ID</th><th>Nazwa</th><th>Cena</th><th>Akcje</th></tr>
    <?php foreach ($produkty as $p): ?>
    <tr>
      <td><?= htmlspecialchars($p['id'])    ?></td>
      <td><?= htmlspecialchars($p['nazwa']) ?></td>
      <td><?= htmlspecialchars($p['cena'])  ?> zł</td>
      <td>
        <a href="edytuj.php?id=<?= (int)$p['id'] ?>">Edytuj</a> |
        <a href="usun.php?id=<?= (int)$p['id'] ?>">Usuń</a>
      </td>
    </tr>
    <?php endforeach; ?>
  </table>
<?php endif; ?>

<!-- Dołączamy wspólną stopkę -->
<?php require_once 'footer.php'; ?>
  
Gotowa strona główna sklepu z listą produktów pobraną z bazy. Ten wzorzec kopiujesz do każdej kolejnej podstrony – zmienia się tylko zapytanie SQL i zawartość między header.php a footer.php.

6. Zmienne dostępne po dołączeniu pliku

Cel: Uczeń rozumie że dołączony plik działa w tym samym zakresie zmiennych.
💡 Gdy dołączasz plik przez require_once, wszystkie zmienne zdefiniowane w tym pliku stają się dostępne w pliku który go dołączył – i odwrotnie. Dlatego $pdo z config.php jest od razu dostępne w index.php bez żadnego przekazywania.
<?php
// a.php
$miasto = "Pińczów";
$rok    = 2025;
?>

<?php
// b.php – dołączamy a.php
require_once 'a.php';

// $miasto i $rok są teraz dostępne w b.php!
echo $miasto;   // Pińczów
echo $rok;      // 2025

// Możemy też nadpisać zmienne z dołączonego pliku
$miasto = "Kielce";
echo $miasto;   // Kielce
?>
  
Pińczów
2025
Kielce

Podsumowanie – ściągawka include / require

Polecenie Błąd przy braku pliku Wielokrotne dołączenie Typowe użycie
include Warning Dołącza ponownie Opcjonalne elementy strony
require Fatal Error Dołącza ponownie Krytyczne pliki jednorazowe
include_once Warning Ignoruje duplikat Opcjonalne, wielokrotnie importowane
require_once Fatal Error Ignoruje duplikat Zalecane config.php, db.php, header.php