W budowie
← Wróć na pulpit Materiał egzaminacyjny · Informatyka Materiał referencyjny · nie jest kursem

Materiał referencyjny · nie jest kursem

Analiza arkuszy egzaminacyjnych INF.03
z lat 2024–2026

Co wymagają arkusze i czym się między rocznikami różnią: szablony plików, katalog zapytań SQL z wagą wymagania, wzorce skryptów JavaScript i pułapki z kryteriów CKE. Opracowanie na 66 arkuszach egzaminacyjnych z lat 2024–2026 (18 ze stycznia i czerwca 2024, 24 z 2025, 24 z 2026) — z osobną kolumną dla każdego rocznika, bo te arkusze różnią się znacząco. Liczby policzone na zasadach oceniania i na samych arkuszach, nie na gotowych rozwiązaniach. Wszystkie przykłady są uruchamialne — sprawdzone w interpreterze, nie pisane z pamięci.

Jak tego używaćNie ucz się tego od deski do deski. Weź arkusz, przeczytaj kryteria pod każdym plikiem, zrób listę plików i zacznij od najwyżej punktowanego. Wszystkie przykłady poniżej są uruchamialne — sprawdzone w interpreterze, nie pisane z pamięci.

01

Kolejność pracy

Kryteria są uporządkowane według plików, a punkty przydzielają w tej samej kolejności. Zrobienie wszystkiego w kolejności plików z zadania oszczędza czas i nie gubi punktów.

  1. Wgraj bazę — plik .sql z zadania przez phpMyAdmin (import). Bez tego nie ma większości punktów. Od razu po imporcie zrób zrzut całego ekranu i zapisz go jako import — nazwy i format są w poleceniu arkusza, nie przepisuj z pamięci.
  2. CSS — zewnętrzny arkusz stylów, o nazwie podanej w arkuszu: styl.css najczęściej, ale bywa style.css albo styles.css. Wymagany we 66/66 egzaminach. Całe formatowanie musi być wyłącznie w tym pliku. Zwykły styl inline w HTML oznacza utratę punktu za arkusz.
  3. Strona — plik o nazwie podanej w Twoim arkuszu (najczęściej index.html albo index.php) ze wszystkimi blokami i znacznikami, o których mówi zadanie. Nie zgaduj nazwy — sprawdź polecenie i listę plików na końcu arkusza.
  4. Skrypt JS — tylko gdy zadanie tego wymaga. Nazwa pliku z arkusza; w 2026 najczęściej main.js. 27/66 egzaminów 2024–2026 ma w ogóle część w JavaScripcie. Bez serwera i bazy: obsługa kliknięć, zmiana obrazów i stylów, tworzenie elementów, wyświetlenie wyniku.
  5. Skrypt PHP — *.php: połączenie, zapytania, wyświetlenie, zamknięcie połączenia.
  6. Zapytania — kwerendy.txt. Wymagany w 63/66 (wszędzie tam, gdzie w ogóle jest zadanie bazodanowe). Sam plik z zapisanym tekstem zapytań.
  7. Zrzuty zapytań — osobny plik na wynik każdego zapytania: kw1, kw2, kw3, kw4 (czasem kw5). Zrzut ma obejmować cały ekran z widocznym paskiem zadań i pokazywać wykonane zapytanie. Nie kadruj.
  8. Sprawdź listę plików — na końcu arkusza jest lista plików, które mają leżeć w twoim folderze. To jedyne miejsce, gdzie podano dokładne nazwy, formaty i liczbę zrzutów.
Największa strata punktów to nie SQLUczeń gubi punkty przede wszystkim na rzeczach dookoła zapytań: brak pliku kwerendy.txt (63/66), formatowanie w HTML zamiast w CSS (arkusz wymagany we 66/66), nazwy zmiennych typu $a zamiast $cenaProduktu i brak zamknięcia połączenia.

02

Różnice między latami

Analiza arkuszy z lat 2024–2026.

Pliki, których wymaga zadanie

Plik2024 (18 egz.)2025 (24 egz.)2026 (24 egz.)
arkusz .css (nazwa z arkusza)18/1824/2424/24
zrzut bazy .sql16/1824/2423/24
kwerendy.txt16/1824/2423/24
strona .html11/189/2411/24
skrypt .php8/1819/2413/24
skrypt .js (nazwa z arkusza)10/186/2411/24
Trzy profile, nie jeden2025 to rok zdecydowanie bazodanowy: 79% egzaminów ma skrypt PHP i 100% wymaga zapisania zapytań, a JavaScript spada do 25%. 2024 jest odwrotnie — JavaScript w 55% egzaminów, PHP tylko w 44%. 2026 leży pośrodku.

Co CKE zmieniało między rocznikami

Wymaganie202420252026
Wynik zapytania widoczny na zrzucie18/1824/2417/24
Układ bloków zgodny z obrazem z arkusza18/180/240/24
Ułożenie przez float i clear18/185/243/24
Ułożenie przez flex lub grid18/1817/2420/24
overflow i paski przewijania6/1816/2410/24
Instrukcja połączenia z bazą3/1839/6613/24
Zamknięcie połączenia8/1819/2413/24
Formularz i kontrolki10/1819/2413/24
$_GET / $_POST2/1812/2411/24
Sesje0/180/242/24
GROUP BY5/189/2413/24
UPDATE5/184/242/24
ROUND / zaokrąglanie wyniku1/183/242/24
Co musi być w folderze zdającego: zrzut import, zrzuty kw i plik kwerendy.txt„Wykonaj zrzut ekranu po imporcie. Zapisz zrzut w formacie JPEG pod nazwą import. Nie kadruj zrzutu. Powinien on obejmować cały ekran monitora, z widocznym paskiem zadań.” „Wykonaj zapytania SQL działające na bazie samochody. Zapytania zapisz w pliku kwerendy.txt. Wykonaj zrzuty ekranu przedstawiające wyniki działania kwerend. Zrzuty zapisz w formacie PNG i nadaj im nazwy kw1, kw2, kw3, kw4.”
Układ strony: kryterium jest w każdym egzaminie, zmienia się tylko numer ilustracjiWszystkie 66 egzaminów z lat 2024–2026 zawierają kryterium „układ bloków po uruchomieniu strony w przeglądarce jest zgodny z ilustracją w arkuszu”. W 2024 wskazywało ono na obraz 2, od 2025 na ilustrację 2, 3 albo 4 (w 2026 bywa 5) — zawsze podaną w Twoim arkuszu, nie zgaduj numeru. W nawiasie CKE wymienia metody równorzędne: float i clear, display: flex, grid albo position. Żadna nie jest obowiązkowa — float zdaje ten sam punkt co flex. W 2026 doszedł warunek: żaden blok nie może zachodzić na inny, co sprawdza się w inspektorze.
Najwyżej punktowane wymaganie jest wspólne dla wszystkich latKryterium „zastosowano przynajmniej jedną zmienną lub funkcję, a nazwy odzwierciedlają cel” występuje w 66/66 egzaminach z lat 2024–2026. W 2024 jest sformułowane inaczej niż w 2025, więc wyszukiwanie go po jednym słowie kluczowym daje zero wyników — ale wymóg jest identyczny.

03

Pliki do dostarczenia

Zadanie zawsze podaje listę plików — nazwy są dosłowne, z rozróżnieniem wielkości liter. Nazwa zależy od arkusza, więc przepisz ją z polecenia, nie zgaduj. Poniżej, co się powtarza:

PlikW ilu egzaminachUwagi
kwerendy.txt63/66Ta nazwa jest stała. Zapis SQL użytego w zadaniu, każde zapytanie jednym ciągiem.
arkusz .css (nazwa z arkusza)66/66Jedyny plik z formatowaniem. styl.css w 44 arkuszach, style.css w 7, styles.css w 6 — zawsze sprawdź, jak się nazywa u Ciebie. Podłącz w <link>.
skrypt .js (nazwa z arkusza)27/66Gdy zadanie tego wymaga. Obsługa kliknięć, zmiana obrazów, tworzenie elementów, liczenie i wyświetlanie wyniku.
strona .php (nazwa z arkusza)40/66Strona główna z podłączonym CSS, zwykle index.php. Czasem też osobne skrypty (wynik.php, login.php).
strona .html (nazwa z arkusza)31/66Strona główna bez PHP, zwykle index.html; dane wstrzykiwane przez JS.
plik .sql63/66To dane wejściowe — wgrywasz, nie tworzysz.
import + kw1–kw5 + przeglądarka.txt58/66Zrzuty i plik przeglądarki pod arkusz dostaje praktycznie każde zadanie z bazą. Nazwy i format przepisz z listy.
Zadania są wieloplikoweW 2026 roku typowe zadanie to kilka stron (index.html + sklep.html + rezerwacja.html) i kilka skryptów. Nie zakładaj, że jest jeden plik — przeczytaj listę na początku arkusza.

04

Szablon strony .html

W gotowych rozwiązaniach 59/66 egzaminów ma znacznik <header>, a 60/66 — <footer>. Podobnie <main> (60/66) i <section> (57/66). Zakładaj, że są zawsze. Tabela pojawia się tylko w 29/66. Najbezpieczniej użyć znaczników sekcji semantycznych — egzamin często wprost o nie prosi.

<!doctype html>
<html lang="pl">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Portal samochodowy</title>
    <link rel="stylesheet" href="styl.css">
</head>
<body>

    <header>
        <h1>Portal samochodowy</h1>
        <nav>
            <ul>
                <li><a href="index.html">Strona główna</a></li>
                <li><a href="sklep.html">Sklep</a></li>
            </ul>
        </nav>
    </header>

    <main>
        <section id="lewy">
            <h2>Lista produktów</h2>
            <table>
                <tr><th>Nazwa</th><th>Cena</th><th>Kategoria</th></tr>
                <tr><td>Stół</td><td>899,50 zł</td><td>Meble</td></tr>
            </table>
        </section>

        <section id="prawy">
            <h2>Promocje</h2>
            <img src="promocja.jpg" alt="promocja">
            <p>tekst</p>
        </section>
    </main>

    <footer>
        <p>Autor: Jan Kowalski</p>
    </footer>

</body>
</html>
Co jest sprawdzane w HTMLKodowanie znaków w <head> (66/66), połączenie z zewnętrznym arkuszem stylów (66/66), bloki strony, tabela z wierszem nagłówkowym, obraz z alt, lista punktowana, znaczniki <header>, <nav>, <main>, <section>, <footer>.

05

Szablon arkusza .css

Egzamin wymaga konkretnych właściwości. Poniżej szkielet pokrywający najczęstsze wymagania 2026: domyślne formatowanie, kolory bloków, marginesy, padding, wyrównanie tekstu i reakcja na kursor.

* {
    font-family: Helvetica, sans-serif;
    text-align: center;
    margin: 0;
    padding: 0;
}

body {
    background-color: #f4f4f4;
}

header, nav, footer {
    background-color: DarkGreen;
    color: white;
    padding: 2px;
}

main {
    display: flex;
    gap: 2%;
}

section {
    width: 33.3%;
    height: 550px;
    overflow: auto;
    padding-top: 10px;
    margin: 0 1%;
    background-color: LightGreen;
}

table {
    width: 90%;
    margin: auto;
    border-collapse: collapse;
}

h2 {
    width: 33%;
}

img:hover {
    border: 1px dotted yellowgreen;
}

a:hover {
    color: white;
    background-color: ForestGreen;
    border-radius: 6px;
}
WłaściwośćJak często wymaganaUwaga
Podłączenie arkuszu z <link>66/66Bez wyjątku. W HTML nie może być style="...".
padding (margines wewnętrzny)60/66Często podana dokładna wartość, np. 2px.
color i background-color60/66Osobno dla nagłówka, nawigacji i stopki — kolory bywają różne.
text-align66/66Najczęściej center, czasem left.
:hover48/66W 2026 roku w 18/24. Zmiana koloru lub obramowania po najechaniu.
width, height66/66Kryterium podaje konkretną wartość, nie metodę: szerokość w procentach (66/66) i wysokość w px (65/66). Od 2026 często wszystko w jednym kryterium, np. „szerokość: blok nawigacyjny 90%, oba bloki sekcji 45%, blok boczny 10%; wysokość: nagłówek 170px”. Metodę układania CKE wylicza w nawiasie i wszystkie są równorzędne: float i clear, display: flex, grid albo position. grid nigdy nie jest wymagany — ale też nie jest zabroniony, więc nie ma powodu go unikać.
Najczęstsza strata punktuStyl w HTML. Kryterium brzmi: „formatowanie pochodzi jedynie z tego arkusza”. Jeśli cokolwiek przesuniesz do style="...", punkt przepada.

06

Skrypt JavaScript

Skrypt w JavaScripcie jest w 27 z 66 egzaminów z lat 2024–2026 (10 w 2024, 6 w 2025, 11 w 2026). Poniżej wzorce z tych 11 egzaminów 2026, które w ogóle mają część w JS; w nawiasie liczba z tych 11, w których dany wzorzec był potrzebny.

<script src="main.js"></script>
Kod JS zawsze w osobnym plikuZapisuj skrypt w osobnym pliku .js i podłącz go przez <script src="…"></script> — nigdy wewnątrz <script> w HTML ani jako atrybut onclick w znaczniku. Nazwy pliku arkusz prawie nigdy nie podaje: w całym materiale 2024–2026 występuje tylko 3 razy na 66 egzaminów — skrypty.js, React.js, dane.js — a w 2024 w żadnym. Jeśli nazwa jest w Twoim arkuszu, użyj jej; jeśli nie ma, wybierz dowolną, np. main.js, i używaj jej konsekwentnie. Nazwy zmiennych i funkcji muszą być znaczące — po polsku albo po angielsku i opisujące, do czego służą. Nazwa jednoliterowa albo skrót bez sensu nie spełnia kryterium i kosztuje punkt. W skrypcie musi być przy tym przynajmniej jedna zmienna lub funkcja.

Odczyt z kontrolek i obliczenie 15/27 · wynik na stronie 17/27

Najczęstszy wzorzec: pobrać wartości, policzyć, pokazać. parseFloat zamienia tekst na liczbę — bez niego mnożenie da NaN.

// Wymagany HTML:
// <input id="podstawa" type="number" value="4">
// <input id="wysokosc" type="number" value="6">
// <button id="oblicz">Oblicz</button>
// <p id="wynik"></p>

function obliczPole() {
    const podstawa = parseFloat(document.getElementById('podstawa').value);
    const wysokosc = parseFloat(document.getElementById('wysokosc').value);
    const pole = Math.round((podstawa * wysokosc) / 2);
    document.getElementById('wynik').textContent = 'Pole = ' + pole;
}

document.getElementById('oblicz').addEventListener('click', obliczPole);
Suwak i przyciski radioweSuwak to <input type="range"> i czyta się tak samo — document.getElementById('wzrost').value. Radio sprawdzasz w warunku: if (document.getElementById('kolarowa').checked). Wymagane w 7/27, ale egzamin często daje kilka radio naraz i każde osobno punktuje.

Zdarzenie kliknięcia 24/27

Tak podpina się zdarzenia w gotowych rozwiązaniach CKE: wywołanie funkcji przez atrybut onclick w znaczniku, a sama funkcja w pliku main.js. Tak robi 24 z 27 egzaminów z lat 2024–2026, które w ogóle mają plik .js, a w 26 z 27 nazywa się on właśnie main.js. addEventListener pojawia się tylko w 2 z 27, a przypisanie element.onclick = w zero. Kryterium wymienia wszystkie trzy zapisy, ale zgodne z kluczem odpowiedzi są dwa pierwsze.

<!-- plik index.html — kliknięcie przypięte atrybutem w znaczniku -->
<button id="przyciskDemo" onclick="zareagujNaKlikniecie()">Przycisk</button>
<p id="tekstKlikniec"></p>

<!-- ten sam zapis na każdym znaczniku, też z argumentem -->
<button id="wybierzKolor" onclick="pokazSekcje('sekcjaKolor')">Kolor</button>
function zareagujNaKlikniecie() {
    const tekst = document.getElementById('tekstKlikniec');
    tekst.textContent = tekst.textContent + 'klik ';
}

// alternatywa, rzadka w kluczu, ale w kryteriach jawnie dopuszczona:
// document.getElementById('przyciskDemo').addEventListener('click', zareagujNaKlikniecie);
Identyfikator jest jeden i musi się zgadzaćHTML dopuszcza tylko jeden element z danym id. getElementById('przycisk') zwraca pierwszy znaleziony element, więc powtórzony identyfikator po cichu ustawia obsługę na złym przycisku i nic nie zgłasza. Klasa class może się powtarzać — do wielu elementów używaj querySelectorAll.

Zmiana obrazu 7/27 i stylu elementu 5/27

Galeria miniatur i okno modalne to dwa osobne kryteria, ale oba polegają na `display`. Kryterium bywa sformułowane bardzo dosłownie: „np. document.getElementById("okno").style.display = "block"”.

// Wymagany HTML:
// <img id="obrazGlowny" src="1.jpg" alt="produkt">
// <img class="mini" src="1.jpg" alt="miniatura 1">
// <img class="mini" src="2.jpg" alt="miniatura 2">
// <div id="okno"><img id="obrazOkno" src="1.jpg" alt=""><span id="zamknij">&times;</span></div>

const obrazGlowny = document.getElementById('obrazGlowny');
const okno = document.getElementById('okno');
okno.style.display = 'none';

document.querySelectorAll('.mini').forEach(function (miniatura) {
    miniatura.addEventListener('click', function () {
        const adres = miniatura.getAttribute('src');
        obrazGlowny.setAttribute('src', adres);
        document.getElementById('obrazOkno').setAttribute('src', adres);
        okno.style.display = 'block';
    });
});

obrazGlowny.addEventListener('click', function () {
    document.getElementById('obrazOkno').setAttribute('src',
        obrazGlowny.getAttribute('src'));
    okno.style.display = 'block';
});

document.getElementById('zamknij').addEventListener('click', function () {
    okno.style.display = 'none';
});
CKE wymaga różnych rzeczy w różnych arkuszach — czytaj kryteriumNie ma jednej poprawnej odpowiedzi na pytanie „co ukrywa element”. W arkuszu ze stycznia 2026 jest kryterium „sposób wyświetlania: pierwszy blok sekcji display: block; pozostałe display: none; (visibility jest błędem)”. W arkuszu z czerwca 2026 jest odwrotnie: „blok sekcji prawej jest niewidoczny (visibility: hidden lub opacity: 0); (display: none jest błędem)”. W 2024 jedno kryterium dopuszcza obie właściwości. Zasada jest jedna: przeczytaj zdanie kryterium i zrób dokładnie to, co w nim napisano — najwięcej punktów kosztuje wierne wykonanie, nie „poprawna technika”.

Zakładki 5/27

// Wymagany HTML:
// <button id="kolor">Kolor</button> <button id="ksztalt">Kształt</button>
// <section id="panelKolor">kolor</section>
// <section id="panelKsztalt">kształt</section>

const zakladki = [
    { przycisk: 'kolor', panel: 'panelKolor' },
    { przycisk: 'ksztalt', panel: 'panelKsztalt' }
];

function pokazPanel(numer) {
    zakladki.forEach(function (pozycja, index) {
        const panel = document.getElementById(pozycja.panel);
        const przycisk = document.getElementById(pozycja.przycisk);
        if (index === numer) {
            panel.style.display = 'block';
            przycisk.style.backgroundColor = 'Salmon';
        } else {
            panel.style.display = 'none';
            przycisk.style.backgroundColor = 'Crimson';
        }
    });
}

zakladki.forEach(function (pozycja, index) {
    document.getElementById(pozycja.przycisk).addEventListener('click', function () {
        pokazPanel(index);
    });
});

pokazPanel(0);
Wywołaj funkcję na starcieOstatnia linia pokazPanel(0) ustawia stan pierwszej zakładki. Bez niej wszystkie panele są widoczne naraz i kryterium „tylko pierwszy blok sekcji jest widoczny” nie działa. Ten sam wzorzec pojawia się przy grze planszowej: stan początkowy ustawiasz przez wywołanie funkcji, nie przez nadpisanie zmiennej w kodzie.

Tworzenie elementów 6/27 · dodanie do kontenera 6/27 · klasa 4/27

Trik egzaminacyjny: skrypt ma tworzyć elementy w pętli, „uniwersalnie dla dowolnej liczby elementów”. Dlatego tworzysz je funkcją, a nie dopisujesz dziesięciu createElement pod rząd.

// Wymagany HTML: <div id="galeria"></div>

for (let numer = 1; numer <= 10; numer += 1) {
    const obraz = document.createElement('img');
    obraz.setAttribute('src', numer + '.jpg');
    obraz.setAttribute('alt', 'obraz numer ' + numer);
    obraz.setAttribute('title', numer + '.jpg');
    obraz.classList.add('wzory');
    document.getElementById('galeria').appendChild(obraz);
}
Trzy sposoby przypisania klasy, wszystkie poprawneelement.classList.add('wzory') · element.className = 'wzory' · element.setAttribute('class', 'wzory'). Kryterium brzmi „ma przypisaną klasę wzory” i nie rozróżnia zapisów.

Lista z kliknięć, czyszczenie i alert 6/27

// Wymagany HTML:
// <ul id="menu"></ul>
// <div class="potrawa">Rosół</div> <div class="potrawa">Kotlet</div>
// <button id="wyczysc">Wyczyść</button>
// <button id="zatwierdz">Zatwierdź</button>

const listaMenu = document.getElementById('menu');

document.querySelectorAll('.potrawa').forEach(function (potrawa) {
    potrawa.addEventListener('click', function () {
        const element = document.createElement('li');
        element.textContent = potrawa.textContent;
        listaMenu.appendChild(element);
    });
});

document.getElementById('wyczysc').addEventListener('click', function () {
    listaMenu.innerHTML = '';
});

document.getElementById('zatwierdz').addEventListener('click', function () {
    alert('Zamówienie zostało przekazane do realizacji');
    listaMenu.innerHTML = '';
});
Czyszczenie to osobne kryteriumW 2026 roku jest jednocześnie punktowane „dodanie elementu”, „wyczyszczenie listy” i „po wyczyszczeniu można dodać element ponownie”. Dlatego czyścisz przez innerHTML = '', a nie przez removeChild w pętli — po innerHTML = '' lista jest gotowa na ponowne dodawanie.

Budowanie sekcji z tablicy 6/27

Największe zadanie JS w 2026: skrypt czyta dane z tablicy obiektów (czasem z pliku dane.json) i buduje z nich całą sekcję — nagłówek, opis i listę.

// Wymagany HTML: <div id="glowny"></div>

const drzewa = [
    { nazwa: 'Jesion', opis: 'Drewno twarde, kwitnie późnym wiosną', leki: ['wierzba', 'kasztan'] },
    { nazwa: 'Sosna', opis: 'Igliasta, zielona cały rok', leki: [] }
];

function pokazDrzewa() {
    const blokGlowny = document.getElementById('glowny');
    blokGlowny.innerHTML = '';
    drzewa.forEach(function (drzewo) {
        const blok = document.createElement('div');
        blok.classList.add('opis');
        const naglowek = document.createElement('h2');
        naglowek.textContent = drzewo.nazwa;
        const opis = document.createElement('p');
        opis.textContent = drzewo.opis;
        blok.appendChild(naglowek);
        blok.appendChild(opis);
        if (drzewo.leki.length > 0) {
            const lista = document.createElement('ol');
            drzewo.leki.forEach(function (lek) {
                const pozycja = document.createElement('li');
                pozycja.textContent = lek;
                lista.appendChild(pozycja);
            });
            blok.appendChild(lista);
        }
        blokGlowny.appendChild(blok);
    });
}

pokazDrzewa();

Szukanie w tablicy 13/27

// Wymagany HTML:
// <input id="szukaj" type="text">
// <button id="sprawdz">Sprawdź</button>
// <p id="odpowiedz"></p>

function znajdzDrzewo() {
    const szukana = document.getElementById('szukaj').value.trim();
    const odpowiedz = document.getElementById('odpowiedz');
    const znalezione = drzewa.find(function (drzewo) {
        return drzewo.nazwa === szukana;
    });
    if (znalezione) {
        odpowiedz.textContent = 'Opis: ' + znalezione.opis;
    } else {
        odpowiedz.textContent = 'Drewno o podanej nazwie nie występuje w bazie';
    }
}

document.getElementById('sprawdz').addEventListener('click', znajdzDrzewo);
Tekst „nie występuje w bazie” jest wymagany dosłownieKryterium brzmi: „w przeciwnym wypadku wypisuje tekst »Drewno o podanej nazwie nie występuje w bazie«”. Własna rewizja zdania nie dostanie punktu, bo egzamin sprawdza treść komunikatu. Podobnie z alert — treść podana w cudzysłowie jest sprawdzana co do znaku.

Przewijanie z zawinięciem 1/27

Galeria trzech obrazów ma przewijać się w kół. Odpowiada za to reszta z dzieleniem — (indeks + 1) % dlugosc. Dodanie + dlugosc przy cofaniu chroni przed ujemnym indeksem.

// Wymagany HTML:
// <img id="obraz" src="barcelona.jpg" alt="miasto">
// <button id="wlewo">&lt;</button> <button id="wprawo">&gt;</button>

const zdjecia = ['barcelona.jpg', 'londyn.jpg', 'rzym.jpg'];
let biezneZdjecie = 0;

function nastepneZdjecie() {
    biezneZdjecie = (biezneZdjecie + 1) % zdjecia.length;
    document.getElementById('obraz').setAttribute('src', zdjecia[biezneZdjecie]);
}

function poprzednieZdjecie() {
    biezneZdjecie = (biezneZdjecie - 1 + zdjecia.length) % zdjecia.length;
    document.getElementById('obraz').setAttribute('src', zdjecia[biezneZdjecie]);
}

document.getElementById('wprawo').addEventListener('click', nastepneZdjecie);
document.getElementById('wlewo').addEventListener('click', poprzednieZdjecie);

Licznik, który pamięta między stronami 1/27

// Wymagany HTML: <p id="licznik"></p>

function licznik() {
    let odwiedziny = 0;
    const zapisane = localStorage.getItem('odwiedziny');
    if (zapisane !== null) {
        odwiedziny = parseInt(zapisane, 10);
    }
    odwiedziny += 1;
    localStorage.setItem('odwiedziny', odwiedziny);
    document.getElementById('licznik').textContent = 'Odwiedzin: ' + odwiedziny;
}

window.addEventListener('load', licznik);
localStorage działa tylko w przeglądarceZapis idzie do pamięci użytkownika, nie do bazy. Jeśli zadanie wymaga, żeby licznik przetrwał czyszczenie danych przeglądarki albo był widoczny dla innych, potrzebna jest tabela w bazie i PHP. Zanim napiszesz kod, sprawdź, czy w zadaniu pada słowo „w bazie”, „w tabeli” albo „po zamknięciu przeglądarki”.

Wzorce z 2024 i 2025, których nie było w 2026

Te konstrukcje wypadły z najnowszych arkuszy, ale w starszych były osobnym kryterium. Jeśli dostajesz arkusz sprzed 2026, sprawdź tę listę.

// Wymagany HTML: <input id="imie" type="text">
// <input id="email" type="text">
// <input id="regulamin" type="checkbox">
// <button id="wyslij">Prześlij</button>
// <p id="komunikat"></p>

function wyslijFormularz() {
    // 2024: imię i nazwisko wielkimi literami, email małymi
    const pelneImie = document.getElementById('imie').value.trim().toUpperCase();
    const email = document.getElementById('email').value.trim().toLowerCase();
    const komunikat = document.getElementById('komunikat');
    // 2024: bez zaznaczenia pola wyboru — komunikat i kolor czerwony
    if (!document.getElementById('regulamin').checked) {
        komunikat.textContent = 'Musisz zapoznać się z regulaminem';
        komunikat.style.color = 'red';
        return;
    }
    // 2024: w innym przypadku kolor Navy i treść z kontrolek
    komunikat.textContent = 'Treść Twojej sprawy: ' + pelneImie + ' / ' + email;
    komunikat.style.color = 'Navy';
    // 2024: dokładna treść alertu jest sprawdzana co do znaku
    window.alert('Dane zostały poprawnie wypełnione');
}

document.getElementById('wyslij').addEventListener('click', wyslijFormularz);
Przypadek bez gałęzi: najczęstszy błąd w JSif (!zaznaczono) { ... return; } bez else oznacza, że przy zaznaczonym polu druga gałąź już się nie wykona. Albo pełne if / else, albo return wewnątrz pierwszej gałęzi — nigdy jedno bez drugiego.

Suma zaznaczonych pól 7/27 w 2024

Checkboxy mają wspólną nazwę, a cena siedzi w tabeli w arkuszu. Odczyty `checked` ze wszystkich pól dają tylko zaznaczone.

// Wymagany HTML:
// <input type="checkbox" name="usluga" value="50">
// <input type="checkbox" name="usluga" value="70">
// <input type="checkbox" name="usluga" value="90">
// <button id="policz">Policz</button>
// <p id="wynikCeny"></p>

function policzCene() {
    const zaznaczone = document.querySelectorAll('input[name="usluga"]:checked');
    let suma = 0;
    zaznaczone.forEach(function (pole) {
        suma += parseInt(pole.value, 10);
    });
    document.getElementById('wynikCeny').textContent =
        'Cena zabiegów: ' + suma + ' zł';
}

document.getElementById('policz').addEventListener('click', policzCene);
Selektor :checked zamiast pętli po wszystkich polachquerySelectorAll('input[name="usluga"]:checked') zwraca tylko zaznaczone pola. Wariant z pętlą po wszystkich i if (pole.checked) jest też poprawny, ale dłuższy. Uwaga na cudzysłowy w name="usluga" — to atrybut HTML, nie id, więc w JS go nie ma.

Pasek postępu na zdarzeniu blur 1/27 w 2024

// Wymagany HTML:
// <div id="pasekPostepu"></div>
// <input id="dane1" type="text">
// <input id="dane2" type="text">

let szerokoscPaska = 4;
document.getElementById('pasekPostepu').style.width = szerokoscPaska + '%';

document.getElementById('dane1').addEventListener('blur', postepPostępu);
document.getElementById('dane2').addEventListener('blur', postepPostępu);

function postepPostępu() {
    // warunek jest wymagany osobno: pasek nie może przekroczyć 100%
    if (szerokoscPaska < 100) {
        szerokoscPaska = Math.min(szerokoscPaska + 12, 100);
        document.getElementById('pasekPostepu').style.width = szerokoscPaska + '%';
    }
}

Losowanie wypowiedzi z tablicy 1/27 w 2024

// Wymagany HTML:
// <button id="generuj">Generuj...</button>
// <p id="czat"></p>

const wypowiedziKrzysztofa = [
    'Cześć!', 'Jak leci?', 'Do zobaczenia', 'Miłego dnia'
];

function wylosujWypowiedz() {
    // Math.random() daje liczbę z przedziału [0, 1), mnożenie i obcięcie
    // dają indeks z przedziału [0, długość - 1]
    const indeks = Math.floor(Math.random() * wypowiedziKrzysztofa.length);
    document.getElementById('czat').textContent =
        wypowiedziKrzysztofa[indeks];
}

document.getElementById('generuj').addEventListener('click', wylosujWypowiedz);
Trzy miejsca na wynik obliczeń w JStextContent w akapicie pod przyciskiem (najczęściej, 9 z 11 egzaminów), window.alert z dokładną treścią oraz console.log — konsola przeglądarki, wymagana w 2 egzaminach z 2024 jako jedyne miejsce wyniku.

Zmiana filtra obrazu 1/27 w 2024

// Wymagany HTML:
// <img id="foto" src="zajecie.jpg" alt="zdjęcie">
// <button id="sepia">Sepia</button>
// <button id="kolory">Kolory</button>

function ustawFiltr(wartosc) {
    document.getElementById('foto').style.filter = wartosc;
}

document.getElementById('sepia').addEventListener('click', function () {
    ustawFiltr('sepia(100%)');
});

document.getElementById('kolory').addEventListener('click', function () {
    ustawFiltr('none');
});
Filtr wraca do normy przez wartość nonePo kliknięciu „Kolory” nie usuwaj właściwości — ustaw style.filter = 'none'. Kryterium z 2024 sprawdza wartości blur z przedziału 4–8 px, sepia(100%), invert(100%) oraz grayscale 0 lub 100%.

CSS towarzyszące skryptom

W arkuszach z JavaScriptem częściej pojawia się float niż flex, bo w 2024 układ oceniano osobnym kryterium z obrazem. Reszta właściwości poniżej występuje sporadycznie — nie ucz się ich na pamięć, ale miej je w zasięgu wzroku.

Właściwość2024 · 2025 · 2026Uwaga
float i clear18/18 · 5/24 · 3/24W 2024 to podstawowy sposób ustawienia bloków obok siebie. Nadal uznawany.
display: block / nonewymagane w wielu zadaniachCzytać kryterium: czasem visibility jest błędem, czasem display: none.
overflow6/18 · 16/24 · 10/24Najczęściej auto przy dużej zawartości bloku.
box-shadow, border-radius13/18 · 19/24 · 16/24Cień pod grafikami, zaokrąglone rogi — podawana dokładna wartość.
letter-spacing7/18 · 4/24 · 9/24Sporadycznie, zwykle w nagłówku i stopce.
outline po najechaniu0/18 · 0/24 · 4/24Tylko w 2026, np. outline: 3px dashed na obrazie.
list-style: none0/18 · 8/24 · 3/24Lista punktowana bez punktorów.
::first-letter1/18 · 0/24 · 2/24Pseudoelement — rzadki, ale pojawia się w zadaniach.

07

Szablon skryptu PHP

Sześć kroków, w tej kolejności. Każdy z nich jest osobnym kryterium, więc pominięcie jednego kosztuje punkty niezależnie od tego, czy reszta działa.

<?php
// 1. Połączenie z bazą danych
$conn = mysqli_connect("localhost", "root", "", "sklep");
if (!$conn) {
    die("Błąd połączenia: " . mysqli_connect_error());
}
$conn->set_charset("utf8mb4");

// 2. Zapytanie
$wynik = $conn->query("SELECT nazwa, cena FROM produkty");

// 3. Wyświetlenie wyniku
// htmlspecialchars i number_format sa poprawne, ale w rozwiazaniach
// z lat 2024-2026 nie wystepuja (0 z 66) — zaokraglanie robi
// zapytanie przez ROUND. Oba zostaw, bo nie szkodza.
echo "<ul>";
while ($produkt = $wynik->fetch_assoc()) {
    echo "<li>" . htmlspecialchars($produkt['nazwa'])
        . " — " . number_format($produkt['cena'], 2, ',', ' ') . " zł</li>";
}
echo "</ul>";

// 4. Opcjonalnie: zmienne zamiast wklejania wartości
$cenaZBrutto = 899.50 * 1.23;

// 5. Zamknięcie połączenia — wymagane w ponad połowie egzaminów
mysqli_close($conn);

// Ten sam skrypt w PDO — inny interfejs, ten sam wynik
$pdo = new PDO("mysql:host=localhost;dbname=sklep;charset=utf8mb4",
    "root", "", [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                 PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC]);
foreach ($pdo->query("SELECT nazwa, cena FROM produkty") as $produkt) {
    echo "<li>" . htmlspecialchars($produkt['nazwa'])
        . " — " . $produkt['cena'] . " zł</li>";
}
$pdo = null;

// A gdy w zapytaniu jest wartość z formularza — parametr, nie tekst
$stmt = $pdo->prepare("SELECT nazwa FROM produkty WHERE kategoria = :kat");
$stmt->execute(["kat" => $kategoria]);
?>
W kryteriach nie ma mysqli_connect ani PDOCKE wymaga „instrukcji połączenia z serwerem bazy danych” — bez wskazania interfejsu. mysqli i PDO są równorzędne; wybierz to, które znasz. Ale mysqli_close() albo $pdo = null sprawdza osobno i osobno punktuje.
Trzy sposoby na to samo zapytanie$db->all('produkty') to skrót pomocniczy Pracowni — na egzaminie go nie ma. mysqli i PDO są prawdziwymi interfejsami. Wszystkie trzy dają ten sam wynik; różni je wyłącznie zapis.
Nazwy zmiennych są punktowane dwukrotnieW 66/66 egzaminów jest kryterium „zastosowano znaczące nazewnictwo dla wszystkich zmiennych i funkcji, nazwy odzwierciedlają cel zastosowania” oraz „zastosowano przynajmniej jedną zmienną lub funkcję”. $a, $x, $tmp — nie przechodzą. $cenaProduktu, $liczbaZamowien — przechodzą.

08

Katalog zapytań SQL

Każdy egzamin z 2026 wymaga czterech zapytań, czasem pięciu. Poniżej komplet operacji wraz z wagą wymagania w 2026. Wszystkie przykłady działają na schemacie podanym niżej — możesz je wkleić i sprawdzić.

Schemat przykładowy (na nim działają wszystkie przykłady poniżej):
kategorie(id, nazwa) — Meble, AGD
produkty(id, idKategoria, nazwa, cena, kolor) — Stół 899,50 brzozowy / Krzesło 349,00 dębowy / Lodówka 2499,99 biały / Pralka 1899,00 biały

Wypisanie kolumn 63/66

Egzamin prawie zawsze wymaga wymienienia kolumn, a nie SELECT *. Warunek brzmi wtedy „wybierające jedynie pola…”.

SELECT nazwa, cena FROM produkty;

Warunek 60/66

SELECT nazwa, cena FROM produkty WHERE kolor = 'biały';

Dwa warunki AND 21/66 · alternatywa OR 5/66

SELECT nazwa FROM produkty WHERE kolor = 'biały' AND cena > 1000;

SELECT nazwa FROM produkty WHERE kolor = 'biały' OR kolor = 'brzozowy';

Łączenie z inną tabelą JOIN 50/66

Najczęstsza operacja w 2026 — szczegóły w rozdziale 7.

SELECT produkty.nazwa AS produkt, kategorie.nazwa AS kategoria
FROM produkty
JOIN kategorie ON produkty.idKategoria = kategorie.id;

Sortowanie ORDER BY 31/66

SELECT nazwa, cena FROM produkty ORDER BY cena ASC;
SELECT nazwa, cena FROM produkty ORDER BY cena DESC;

Ograniczenie liczby wierszy LIMIT 13/66

SELECT nazwa, cena FROM produkty ORDER BY cena DESC LIMIT 3;

Wyszukiwanie fragmentu tekstu LIKE 19/66

SELECT nazwa FROM produkty WHERE nazwa LIKE '%stół%';

Tylko unikalne DISTINCT 7/66

SELECT DISTINCT kolor FROM produkty;

Wartość z zakresu BETWEEN 5/66

SELECT nazwa, cena FROM produkty WHERE cena BETWEEN 300 AND 1000;
Kolejność klauzul jest stałaFROM → WHERE → GROUP BY → HAVING → ORDER BY → LIMIT. LIMIT nigdy nie stoi przed ORDER BY — to najczęstszy błąd przy sortowaniu.

Wartość z formularza — parametr, nigdy tekst

Powyższe zapytania mają wartości wplecione w cudzysłowy — bo są stałe. Gdy wartość pochodzi z formularza, wstawia się ją obok zapytania jako parametr. W SQL-u wygląda to jak znak zapytania albo nazwa:

-- tak NIE wolno
SELECT nazwa FROM produkty WHERE kolor = '$kolor';

-- tak w mysqli — znak zapytania
$stmt = $conn->prepare('SELECT nazwa FROM produkty WHERE kolor = ?');
mysqli_stmt_bind_param($stmt, 's', $kolor);
mysqli_stmt_execute($stmt);
$wynik = mysqli_stmt_get_result($stmt);

-- tak w PDO — parametr nazwany
$st = $pdo->prepare('SELECT nazwa FROM produkty WHERE kolor = :kolor');
$st->execute(['kolor' => $kolor]);
Trzy interfejsy do jednej bazy$db->all('produkty') to skrót pomocniczy Pracowni — na egzaminie go nie ma. mysqli i PDO są prawdziwymi interfejsami PHP i robią dokładnie to samo. Wystarczy dobrze znać jeden, ale warto widzieć, że drugi istnieje.

09

Łączenie tabel

W 2026 roku 19 z 24 egzaminów wymaga JOIN — to druga najczęstsza operacja po SELECT i WHERE. Schemat zadań jest bardzo podobny, więc wzorzec się powtarza.

Typowy układ tabel w zadaniu
tabela główna (np. obiekty) z kluczem obcym idKategoria, idRodzaj
tabele słownikowe (np. kategorie, rodzaje) — po jednej wartości
tabela łącząca (np. osiagniecia) z dwoma kluczami obcymi
tabela osób (np. turysci, klienci)
-- Dwie tabele: wystarczy JOIN po kluczu obcemu
SELECT produkty.nazwa AS produkt, kategorie.nazwa AS kategoria
FROM produkty
JOIN kategorie ON produkty.idKategoria = kategorie.id
WHERE kategorie.nazwa = 'Meble';

-- Trzy tabele: łańcuch JOIN
SELECT turysci.nick, obiekty.nazwa, rodzaje.rodzaj
FROM osiagniecia
JOIN turysci ON osiagniecia.idTurysta = turysci.idTurysta
JOIN obiekty ON osiagniecia.idObiekt = obiekty.idObiekt
JOIN rodzaje ON obiekty.idRodzaj = rodzaje.idRodzaj;

-- LEFT JOIN: wiersze bez odpowiednika też mają zostać
SELECT produkty.nazwa AS produkt, kategorie.nazwa AS kategoria
FROM produkty
LEFT JOIN kategorie ON produkty.idKategoria = kategorie.id;
Zapis JOIN — bez słowa INNERW gotowych rozwiązaniach z lat 2024–2026 samo JOIN pojawia się w 50 z 66 egzaminów, a INNER JOIN w żadnym. Nie dopisuj INNER — nie jest błędem, ale w kluczu tak nie ma. LEFT JOIN występuje w 3 z 66.
Daj aliasy, gdy łączysz tabele z taką samą nazwą kolumnySELECT produkty.nazwa, kategorie.nazwa wykonuje się bez błędu, ale obie kolumny nazywają się nazwa. W PHP przez fetch_assoc() dostajesz jeden klucz nazwa — druga wartość nadpisuje pierwszą i w tabeli wyląduje jedna kolumna zamiast dwóch. Zapis produkty.nazwa AS produkt, kategorie.nazwa AS kategoria daje dwa osobne pola i działa tak, jak widać. Prefiks tabela. jest konieczny w ON, alias — w SELECT.

10

Agregaty i grupowanie

GROUP BY w 26/66, COUNT w 24/66, AVG w 17/66. Wszystkie liczby liczone są w zapytaniu, nie w PHP.

-- Ile jest produktów
SELECT COUNT(*) AS ilosc FROM produkty;

-- Ile jest produktów danej kategorii
SELECT kategorie.nazwa, COUNT(*) AS ilosc
FROM produkty
JOIN kategorie ON produkty.idKategoria = kategorie.id
GROUP BY kategorie.nazwa;

-- Średnia cena zaokrąglona do dwóch miejsc
SELECT kategorie.nazwa, ROUND(AVG(produkty.cena), 2) AS srednia
FROM produkty
JOIN kategorie ON produkty.idKategoria = kategorie.id
GROUP BY kategorie.nazwa;

-- Najdroższy i najtańszy
SELECT MAX(cena) AS najwyzsza, MIN(cena) AS najnizsza FROM produkty;

-- Filtr po wyniku grupowania
SELECT kategorie.nazwa, COUNT(*) AS ilosc
FROM produkty
JOIN kategorie ON produkty.idKategoria = kategorie.id
GROUP BY kategorie.nazwa
HAVING COUNT(*) > 1;
HAVING — w żadnym gotowym rozwiązaniu z 66 egzaminówWszystkie zapytania z grupowaniem kończą się na GROUP BY. Sam HAVING występuje w kryteriach zaledwie raz w 2026 roku. Jeśli więc zadanie nie każe wprost „tylko te grupy, które…”, nie dodawaj HAVING — to dodatkowa konstrukcja bez punktu za nią. Umiejętność jest poprawna, ale w praktyce zbędna.

WHERE czy HAVINGWHERE filtruje wiersze przed grupowaniem, HAVING — po. WHERE cena > 100 liczy tylko drogie produkty i dzieli resztę; HAVING COUNT(*) > 1 odsiewa z wyniku kategorie z jednym produktem.

11

Zapis danych

Rzadziej niż odczyt, ale pojawia się w 12/66 egzaminach. ALTER TABLE w 14/66.

-- Dodanie kolumny (wymagane, gdy zadanie każe dodać kolumnę ocena)
ALTER TABLE produkty ADD COLUMN ocena INT;

-- Dodanie rekordu
INSERT INTO produkty (nazwa, cena, kolor) VALUES ('Biurko', 1299.00, 'jesion');

-- Zmiana danych
UPDATE produkty SET cena = 799.00 WHERE nazwa = 'Stół';

-- Usunięcie rekordów
DELETE FROM produkty WHERE kolor = 'dębowy';
Warunek po identyfikatorze, nie po nazwieWHERE nazwa = 'Stół' zmieni wszystkie stoły naraz. Egzamin prawie zawsze podaje id — używaj go.

Konta i uprawnienia w MySQL 6/66

To polecenie wymieniają w kryteriach wszystkie trzy lata, a w arkuszu pojawia się jako osobne zapytanie z jawnie podanym hasłem. Nie jest to fragment SQL-a, tylko administracja serwerem — wykonuje się je w phpMyAdmin w zakładce SQL albo w konsoli.

-- Konto lokalne z hasłem. W kryteriach zawsze z jawnym hasłem w cudzysłowie.
CREATE USER 'Lekarz'@'localhost' IDENTIFIED BY 'Lek@rz';

-- Nadanie praw do jednej tabeli (składnia bezpierwotnie z kropką: baza.tabela)
GRANT SELECT, UPDATE ON salon.uslugi TO 'Lekarz'@'localhost';

-- Usunięcie całej tabeli
DROP TABLE uzytkownik;
Trzy warianty, wszystkie uznawaneKryteria dopuszczają CREATE USER 'k'@'localhost' IDENTIFIED BY 'h' oraz CREATE USER k@localhost IDENTIFIED BY 'h' (bez cudzysłowów). Przy GRANT wystarczy sam SELECT, czasem z UPDATE. W kryteriach pojawia się też informacja, że komunikat „nie wybrano bazy” jest dopuszczalnym błędem — najpierw wybierz bazę w phpMyAdmin, wtedy zapytanie przejdzie czysto.

Pułapki w zapisie zapytań

-- COUNT(*) liczy wiersze, COUNT(kolumna) liczy wiersze z niepustą kolumną.
-- Przy JOIN z tabelą obcą licz właściwą kolumnę, inaczej wynik się rozjedzie.
SELECT nazwisko, COUNT(zadania.id_zadania) AS "Liczba zadań"
FROM osoby JOIN zadania ON id_osoba = osoba_id
GROUP BY nazwisko;

-- Alias może być w cudzysłowie i po polsku — tak właśnie brzmi kryterium.
-- Agregatowi zawsze daj alias: bez niego w fetch_assoc() dostajesz
-- nazwę funkcji albo "value" zamiast czytelnej etykiety.
SELECT trenerzy.Imie, trenerzy.Nazwisko, COUNT(*) AS "Liczba szkoleń"
FROM trenerzy JOIN szkolenia ON trenerzy.Id = Id_trenera
GROUP BY trenerzy.Id;

-- Kolumna logiczna: 0/1 albo TRUE/FALSE, oba zapisy są poprawne
SELECT cel, dataWyjazdu FROM wycieczki WHERE dostepna = FALSE;
SELECT cel, cena FROM wycieczki WHERE cena > 1300;

-- Dwie tabele połączone kluczem obcym
SELECT cel, cena, podpis FROM zdjecia
JOIN wycieczki ON zdjecia.id = wycieczki.zdjecia_id
WHERE cena > 1300;
JOIN bywa opcjonalny — ale tylko w 2024CKE przy kryteriach z 2024 dopisywał w nawiasie, że za poprawne uzna też „porównanie kluczy po WHERE”, czyli FROM zdjecia, wycieczki WHERE zdjecia.id = wycieczki.zdjecia_id. W 2025 i 2026 tej adnotacji już nie ma. Jeśli trafasz na stary arkusz i nie masz czasu, zapisanie kluczy w WHERE wystarczy; w nowszych lepiej użyć JOIN.

12

Pułapki z kryteriów

Sformułowania, które uczniowie czytają jako oczywiste, a które CKE punktuje osobno.

Co mówi kryteriumCzęstośćNa co uważać
„W pliku kwerendy.txt zapisano co najmniej jedno zapytanie SQL”63/66Plik musi istnieć i zawierać tekst zapytań. Zapis w bazie nie wystarczy.
„Ostatnią operacją na bazie jest jej zamknięcie”39/66mysqli_close($conn) na końcu skryptu. Najczęstsza brakująca linia.
„wybierające jedynie pola…”63/66SELECT * nie spełnia warunku „jedynie”.
„formatowanie pochodzi jedynie z tego arkusza”66/66Żadnego style="..." w HTML.
„zastosowano znaczące nazewnictwo dla wszystkich zmiennych”66/66Nazwy w języku polskim lub angielskim, odzwierciedlające cel.
„zastosowano przynajmniej jedną zmienną lub funkcję”66/66Choćby jedna funkcja własna albo zmienna zamiast wklejonej wartości.
„zgodne ze składnią”66/66Zapytanie ma się wykonać, nie tylko wyglądać poprawnie.
„udokumentowano zrzutem”66/66Wynik każdego zapytania musi być widoczny na zrzucie — w każdym roczniku. Zrzut jest plikiem, który oddajesz (obok kwerendy.txt) — nie zastępuje zapytania i nie jest zastępowany przez nie.

13

Co powtarza się najczęściej

Ranking wszystkich 66 egzaminów z lat 2024–2026 (18 + 24 + 24), a nie tylko egzaminów 2026. Liczono po identyfikatorach sesji. Wiersze, w których lata się różnią, mają osobną kolumnę.

Umiejętność2024–20262024 · 2025 · 2026Co robić
Zewnętrzny arkusz stylów66/6618 · 24 · 24Jedno <link>, zero stylów inline.
DOCTYPE i język strony66/6618 · 24 · 24<!doctype html> i lang="pl".
Kodowanie znaków w <head>66/6618 · 24 · 24Wszystkie polskie znaki muszą się wyświetlać.
Zmienna lub funkcja + znaczące nazwy66/6618 · 24 · 24Nazwa zmiennej opisuje, co trzyma.
Kolory tła i czcionki66/6618 · 24 · 24Osobno dla każdego bloku strony.
Krój czcionki66/6618 · 24 · 24Kolejność czcionek ma znaczenie, np. Helvetica, sans-serif.
Szerokości i wysokości bloków66/6618 · 24 · 24Procenty albo px, zgodnie z zadaniem.
Marginesy wewnętrzne i zewnętrzne65/6618 · 24 · 23padding i margin osobno dla każdego bloku.
Wyrównanie tekstu64/6617 · 23 · 24Najczęściej center.
Zapisanie zapytań do pliku63/6616 · 24 · 23kwerendy.txt — założyć przed pisaniem kodu.
Wskazane kolumny w SELECT63/6616 · 24 · 23Nigdy SELECT *, bo kryterium mówi „jedynie pola”.
Wyświetlenie danych w PHP62/6616 · 24 · 22Wynik zapytania musi być widoczny na stronie.
Wysłanie zapytania do bazy63/6616 · 24 · 23query() albo execute().
JOIN dwóch tabel59/6614 · 22 · 23Klucz obcy w ON, prefiks w SELECT.
Ułożenie bloków (flex, grid, float)57/6618 · 18 · 21W 2024 dodatkowo osobne kryterium z obrazem.
Bloki semantyczne HTML560/6612 · 24 · 24header, nav, main, section, footer.
Tabela55/6616 · 21 · 18Obramowanie, komórki, często wiersz nagłówkowy.
:hover i reakcja na kursor50/6614 · 16 · 20Zmiana koloru, obramowania albo obrysu.
Obramowanie, zaokrąglenie, cień48/6613 · 19 · 16Wartości podawane dokładnie, np. 5px 5px 10px DimGray.
Obliczanie wartości w PHP62/6616 · 24 · 22Zmienna zamiast wklejonej wartości.
Zamknięcie połączenia z bazą40/668 · 19 · 13Ostatnia operacja na bazie w skrypcie.
Instrukcja połączenia z bazą35/663 · 19 · 13mysqli albo PDO — oba uznawane, wybierz ten, który znasz.
Zapytanie parametryzowane—17 · 12mysqli_prepare + mysqli_stmt_bind_param albo prepare + execute. Nigdy sklejanie.
Odczyt wyników (fetch)29/666 · 14 · 9fetch_assoc(), fetch_row() lub fetch_array().
Formularz i kontrolki42/6610 · 19 · 13Pola, przyciski, lista rozwijana, radio, checkbox.
$_GET / $_POST25/662 · 12 · 11Identyfikator przekazany metodą GET.
ORDER BY30/664 · 15 · 11ASC rosnąco, DESC malejąco.
GROUP BY27/665 · 9 · 13Grupowanie po kolumnie, która jest też w SELECT.
LIKE19/663 · 9 · 7'%tekst%' — znaki procentowe w cudzysłowie.
COUNT19/663 · 6 · 10COUNT(*) albo COUNT(kolumna) przy JOIN.
LIMIT18/664 · 9 · 5Po ORDER BY, nigdy przed.
ALTER TABLE / dodanie kolumny14/666 · 5 · 3ADD COLUMN albo samo ADD.
INSERT13/662 · 6 · 5Gdy zadanie każe dodać rekord.
CREATE USER i GRANT6/662 · 2 · 2Konto z jawnym hasłem i nadanie praw do tabeli.
AVG15/664 · 4 · 7Zwykle z ROUND(..., 2).
UPDATE11/665 · 4 · 2Warunek po id, nie po nazwie.
DISTINCT7/663 · 3 · 1Bez powtórzeń w wyniku.
DELETE5/660 · 4 · 1Usunięcie wskazanych rekordów.
LEFT JOIN4/660 · 1 · 3Gdy trzeba zachować wiersze bez odpowiednika.
ROUND / zaokrąglanie6/661 · 3 · 2Dwa miejsca po przecinku.
Sesje2/660 · 0 · 2session_start() na początku pliku.
HAVING1/660 · 0 · 1Filtr po grupowaniu. W praktyce prawie nigdy.
Co zmieniło się między rocznikami — w skrócieW 2024 i 2025 każde zapytanie wymagało udokumentowania zrzutem ekranu z konkretnymi wartościami; w 2026 ten wymóg niemal zniknął. W 2024 float był podstawowym sposobem ustawienia bloków i był wymagany w każdym egzaminie; w 2025–2026 CKE oczekuje flex albo grid. Formularze, sesje i zabezpieczenie wyjścia w 2026 wypadają sporadycznie. Rdzeń egzaminu we wszystkich latach to SQL i składnia strony — jeśli czas jest ograniczony, pilnuj najpierw kwerendy.txt, listy kolumn w SELECT i styl.css.