Przejdź do głównej treści
EE.09-01-22.01-SGStyczeń 2022 · 41 kroków · ok. 76 min · 31 kryteriów z klucza

Rozwiązanie krok po kroku: Zgłoszenie na kartę wędkarską (Wersja podstawowa)

Portal kart wędkarskich: baza wedkowanie z tabelami wędkarzy, łowisk i zawodów (import z pliku baza.sql), cztery zapytania - dopisanie wędkarza (INSERT), wybór wędkarzy z liczbą punktów powyżej 20, akwen łowiska wybrany przez relację z tabelą zawodów (JOIN) i utworzenie użytkownika bazy (CREATE USER). Do tego zdjęcie wędki przeskalowane do wysokości 220 px, strona karta.html z formularzem zgłoszenia, listą typów łowisk i odnośnikiem, style w styl_1.css oraz skrypt zapisz.php, który zapisuje dane z formularza w bazie.

To arkusz EE.09 ze stycznia 2022 - kwalifikacji formuły 2017, którą zastąpiła INF.03. Kroki idą zdanie po zdaniu za treścią arkusza - przy każdym jest polecenie z arkusza, a kod pokazuje dokładnie te linie, które je spełniają. Skrypt jest najpierw napisany najprościej, funkcjami mysqli z tabeli 1 arkusza, a na końcu sprawdzony na prawdziwym wstrzyknięciu SQL i zabezpieczony.

To jest wersja podstawowa. W zakładce „Nowoczesny kod (flex, PDO)” jest drugi sposób rozwiązania tego samego arkusza: semantyczne znaczniki, etykiety <label>, układ dolnych bloków w kontenerze flex, PDO z zapytaniem przygotowanym i sprawdzaniem danych - obie wersje są zgodne z kluczem.

Baza i zdjęcie pochodzą z oryginalnego archiwum CKE pliki1.zip (załącznik do pobrania na stronie arkusza, hasło w treści zadania). Zapytania i zrzuty są policzone na MariaDB 10.4 - tej samej, która jest w XAMPP. Podgląd skryptu to wynik prawdziwego uruchomienia kodu w PHP 8.2 (klucz każe sprawdzać w XAMPP 8.0.7 - użyte funkcje działają w obu wersjach tak samo).

Jak liczą się punkty. Klucz ma 31 kryteriów (R.1.1 - R.5.4), każde za 1 punkt. Próg zdania części praktycznej to 75%, czyli 24 punkty (75% z 31 to 23,25, zaokrąglone w górę) - można stracić 7 kryteriów i nadal zdać. Przy każdym kroku jest napisane, które kryteria spełnia; egzaminator ocenia spełnienie kryteriów z klucza, nie zgodność z tym kodem.

  1. Etap 1: Baza danych

    Kroki 1-7 · po tym etapie masz 6 z 31 kryteriów (pkt)

    Krok 1: Folder zdającego i archiwum pliki1.zip

    ok. 2 min
    Polecenie z arkusza

    Należy utworzyć folder o nazwie odpowiadającej numerowi PESEL zdającego lub w przypadku jego braku innemu numerowi, którym został podpisany arkusz. Archiwum należy rozpakować do tego folderu.

    Na pulpicie tworzysz folder nazwany numerem PESEL - w tym rozwiązaniu w jego miejscu stoi imię i nazwisko autora, Bartosz Bryniarski. Archiwum pliki1.zip rozpakowujesz do tego folderu, podając hasło K@RTY* (wielkie litery, małpa i gwiazdka mają znaczenie). W środku są dwa pliki: baza.sql (tabele do importu) i wedka.jpg (zdjęcie).

    Do tego folderu trafia wszystko, co powstanie: zrzuty, kwerendy.txt, pliki strony, stylów i skryptu.

    Typowe błędy

    Pliki zapisane poza folderem zdającego (np. tylko w htdocs) nie trafią na płytę - a ocenia się tylko to, co jest na płycie.

  2. Krok 2: XAMPP i baza wedkowanie

    ok. 2 min
    Polecenie z arkusza

    Uruchom usługi MySQL i Apache za pomocą XAMPP Control Panel. Za pomocą narzędzia phpMyAdmin wykonaj podane operacje na bazie danych: Utwórz bazę danych o nazwie wedkowanie

    W XAMPP Control Panel klikasz Start przy Apache i MySQL, potem w przeglądarce otwierasz http://localhost/phpmyadmin. Nowa w lewym panelu, nazwa wedkowanie (bez polskiej litery), porównywanie np. utf8mb4_polish_ci, Utwórz.

    Typowe błędy

    Nazwa bazy musi brzmieć dokładnie wedkowanie - skrypt łączy się z bazą po nazwie (R.5.1), a klucz sprawdza import do tej bazy (R.1.1).

  3. Krok 3: Import pliku baza.sql i zrzut import.png

    Kryteria:

    R.1.1 Wykonano import tabel do bazy danych wedkowanie , czynność udokumentowano plikiem o nazwie import w formacie PNG. Zrzut zawiera cały obszar ekranu z widocznym paskiem zadań

    ok. 3 min
    Polecenie z arkusza

    Do bazy wedkowanie zaimportuj tabele z pliku baza.sql z rozpakowanego archiwum. Wykonaj zrzut ekranu po imporcie. Zrzut zapisz w folderze z numerem PESEL, lub w przypadku jego braku w folderze z innym numerem, którym został podpisany arkusz, w formacie PNG i nazwij import. Nie kadruj zrzutu. Powinien on obejmować cały ekran monitora, z widocznym paskiem zadań. Na zrzucie powinny być widoczne elementy wskazujące na poprawnie wykonany import tabel

    Zaznacz bazę wedkowanie, karta Import, Wybierz plik → baza.sql, Wykonaj. phpMyAdmin odpowiada zielonym komunikatem „Import zakończył się sukcesem”, a w lewym panelu pod bazą pojawia się lista tabel - w tym pliku jest ich 11, z czego zadanie używa trzech: karty_wedkarskie, lowisko i zawody_wedkarskie (reszta to tabele z innych zadań).

    Zrzut całego ekranu z komunikatem i listą tabel zapisz jako import.png. Plik tworzy tabele z kodowaniem latin1 - zostaje tak, jak jest w archiwum.

    Typowe błędy

    Ten zrzut ma nazwę import i format PNG, zrzuty zapytań - JPEG. Wykadrowany zrzut albo zrzut bez paska zadań nie jest oceniany (uwaga w kluczu przy R.1).

    Podgląd strony po tym kroku
    Podgląd strony po kroku 3
  4. Krok 4: Zapytanie 1: karta Grzegorza Niemczyka

    Kryteria: ,

    R.1.2 Zapisano plik tekstowy o nazwie kwerendy zawierający co najmniej jedno zapytanie SQL, wynikające z treści zadania

    R.1.3 Utworzono zapytanie 1 dodające rekord do tabeli karty_wedkarskie dla Grzegorza Niemczyka, adres="Gdynia, Batorego 14/5", z datą "2018-02-23", punkty=0. Baza powinna sama nadać wartość pola id dla tabeli. W pliku z kwerendami lub na zrzucie istnieje zapis np.: INSERT INTO `karty_wedkarskie` VALUES (NULL, 'Grzegorz', 'Niemczyk', 'Gdynia, Batorego 14/5', '2018-02-23', '0'); oraz wynik działania udokumentowano zrzutem, na którym widoczne jest poprawnie wykonane zapytanie lub tabela z dodanym rekordem

    ok. 4 min
    Polecenie z arkusza

    Zapytanie 1: dodające rekord do tabeli Karty_wedkarskie dla Grzegorza Niemczyka, zamieszkałego pod adresem „Gdynia, Batorego 14/5”, z datą „2018-02-23”; wartość punktów: 0. Baza powinna sama nadać wartość pola id dla tabeli

    Zaznacz bazę wedkowanie i otwórz kartę SQL. Zapytanie po kolei:

    • INSERT INTO karty_wedkarskie - do której tabeli; w bazie jej nazwa jest pisana małymi literami (w XAMPP na Windows wielkość liter w nazwach tabel nie ma znaczenia),
    • VALUES (NULL, ...) - wartości dla wszystkich sześciu kolumn w kolejności z tabeli: id, imie, nazwisko, adres, data_zezwolenia, punkty. NULL w kolumnie id z AUTO_INCREMENT oznacza „nadaj sam” - tak baza „sama nadaje wartość pola id”,
    • napisy i data w apostrofach, punkty jako liczba 0. Data w formacie RRRR-MM-DD - tak zapisuje ją typ DATE.

    Wynik: „1 wiersz wstawiony”, nowy rekord ma id 3 (w tabeli były dwa). Zapytanie kopiujesz do pliku kwerendy.txt w folderze zdającego (R.1.2), a zrzut całego ekranu zapisujesz jako kw1.jpg - na zrzucie widać komunikat i tabelę z dodanym rekordem.

    Typowe błędy

    Bez listy kolumn trzeba podać wartość dla każdej kolumny - pominięcie NULL na początku daje błąd #1136 (liczba kolumn nie odpowiada liczbie wartości). Wpisanie konkretnego id, np. 3, odbiera punkt - arkusz każe nadać je bazie.

    kwerendy.txt Tekst nowy plik
    -- Zapytanie 1
    INSERT INTO karty_wedkarskie VALUES (NULL, 'Grzegorz', 'Niemczyk', 'Gdynia, Batorego 14/5', '2018-02-23', 0);
    Podgląd strony po tym kroku
    Podgląd strony po kroku 4
  5. Krok 5: Zapytanie 2: wędkarze z liczbą punktów większą niż 20

    Kryteria:

    R.1.4 Utworzono zapytanie 2 wybierające jedynie pola imie i nazwisko z tabeli karty_wedkarskie dla wędkarzy, dla których liczba punktów jest większa niż 20. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT imie, nazwisko FROM `karty_wedkarskie` WHERE punkty > 20; oraz wynik działania udokumentowano zrzutem, na którym widoczny jest dokładnie 1 rekord: Jan Kowalski; jedynie pola imie, nazwisko

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 2: wybierające jedynie pola imie i nazwisko z tabeli Karty_wedkarskie dla wędkarzy, dla których liczba punktów jest większa niż 20

    • SELECT imie, nazwisko - tylko dwie kolumny, „jedynie” wyklucza SELECT *,
    • FROM karty_wedkarskie,
    • WHERE punkty > 20 - „większa niż” to ostro większa, więc >, nie >=.

    Wynik: dokładnie jeden wędkarz, Jan Kowalski (23 punkty) - tak jak w kluczu. Andrzej Nowak ma 3 punkty, a dodany przed chwilą Grzegorz Niemczyk 0. Zrzut: kw2.jpg.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    INSERT INTO karty_wedkarskie VALUES (NULL, 'Grzegorz', 'Niemczyk', 'Gdynia, Batorego 14/5', '2018-02-23', 0);
    
    -- Zapytanie 2
    SELECT imie, nazwisko FROM karty_wedkarskie WHERE punkty > 20;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 5
  6. Krok 6: Zapytanie 3: akwen, gdzie sędzią jest Krzysztof Dobrowolski

    Kryteria:

    R.1.5 Utworzono zapytanie 3 wybierające jedynie pole akwen z tabeli lowisko dla łowisk, gdzie sędzią zawodów jest Krzysztof Dobrowolski. Zapytanie wykorzystuje relację. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT akwen FROM lowisko JOIN zawody_wedkarskie ON lowisko.id = zawody_wedkarskie.Lowisko_id WHERE sedzia= "Krzysztof Dobrowolski"; możliwe INNER JOIN lub SELECT akwen FROM lowisko, zawody_wedkarskie WHERE lowisko.id = zawody_wedkarskie.Lowisko_id AND sedzia= "Krzysztof Dobrowolski"; oraz wynik działania udokumentowano zrzutem, na którym widoczny jest dokładnie 1 rekord: Zalew Wegrowski; jedynie pole akwen

    ok. 4 min
    Polecenie z arkusza

    Zapytanie 3: wybierające jedynie pole akwen z tabeli Lowisko dla łowisk, gdzie sędzią zawodów jest Krzysztof Dobrowolski, należy użyć relacji

    Akwen jest w tabeli lowisko, a sędzia - w tabeli zawody_wedkarskie. Łączy je relacja: kolumna Lowisko_id w zawodach wskazuje id łowiska. Zapytanie klauzula po klauzuli:

    • SELECT akwen - jedyna kolumna z wyniku,
    • FROM lowisko JOIN zawody_wedkarskie - złączenie dwóch tabel,
    • ON lowisko.id = zawody_wedkarskie.Lowisko_id - warunek relacji; każdy wiersz zawodów zostaje połączony z łowiskiem, na którym się odbyły. Nazwy kolumn poprzedza nazwa tabeli, bo obie tabele mają kolumnę id,
    • WHERE sedzia = 'Krzysztof Dobrowolski' - tylko zawody tego sędziego.

    Wynik: jeden akwen, Zalew Wegrowski (zgodnie z kluczem; w bazie nazwy są bez polskich liter). Zrzut: kw3.jpg. Klucz przyjmuje też starszy zapis z dwiema tabelami po przecinku i warunkiem relacji w WHERE - daje ten sam wynik.

    Typowe błędy

    Bez warunku ON (albo warunku relacji w WHERE) baza łączy każde łowisko z każdymi zawodami i ten sam sędzia „sędziuje” na wszystkich sześciu łowiskach.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    INSERT INTO karty_wedkarskie VALUES (NULL, 'Grzegorz', 'Niemczyk', 'Gdynia, Batorego 14/5', '2018-02-23', 0);
    
    -- Zapytanie 2
    SELECT imie, nazwisko FROM karty_wedkarskie WHERE punkty > 20;
    
    -- Zapytanie 3
    SELECT akwen FROM lowisko JOIN zawody_wedkarskie ON lowisko.id = zawody_wedkarskie.Lowisko_id WHERE sedzia = 'Krzysztof Dobrowolski';
    Podgląd strony po tym kroku
    Podgląd strony po kroku 6
  7. Krok 7: Zapytanie 4: użytkownik anna

    Kryteria:

    R.1.6 Utworzono zapytanie 4 tworzące użytkownika anna na localhost z hasłem anna123. W pliku z kwerendami lub na zrzucie istnieje zapis np.: CREATE USER "anna"@"localhost" IDENTIFIED BY "anna123"; oraz wynik działania udokumentowano zrzutem wskazującym na prawidłowo dodanego użytkownika

    ok. 3 min
    Polecenie z arkusza

    Zapytanie 4: tworzące użytkownika anna na localhost z hasłem anna123

    • CREATE USER 'anna'@'localhost' - konto użytkownika serwera bazy; po małpie host, z którego może się logować („na localhost”),
    • IDENTIFIED BY 'anna123' - hasło. Baza nie przechowuje go wprost, tylko jego skrót.

    Samo CREATE USER kończy się komunikatem „MySQL zwrócił pusty wynik”. Żeby zrzut kw4.jpg wskazywał na dodanego użytkownika, w tej samej karcie SQL dopisz pod spodem zapytanie sprawdzające SELECT User, Host, Password FROM mysql.user WHERE User = 'anna'; - phpMyAdmin pokaże wtedy wiersz z kontem anna@localhost i skrótem hasła *7E21CC99…. Konto widać też w zakładce Konta użytkowników. Do kwerendy.txt trafia tylko zapytanie 4.

    Typowe błędy

    Nazwa i host w osobnych apostrofach: 'anna'@'localhost'. Zapis 'anna@localhost' utworzy użytkownika o nazwie „anna@localhost” z dowolnego hosta.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    INSERT INTO karty_wedkarskie VALUES (NULL, 'Grzegorz', 'Niemczyk', 'Gdynia, Batorego 14/5', '2018-02-23', 0);
    
    -- Zapytanie 2
    SELECT imie, nazwisko FROM karty_wedkarskie WHERE punkty > 20;
    
    -- Zapytanie 3
    SELECT akwen FROM lowisko JOIN zawody_wedkarskie ON lowisko.id = zawody_wedkarskie.Lowisko_id WHERE sedzia = 'Krzysztof Dobrowolski';
    
    -- Zapytanie 4
    CREATE USER 'anna'@'localhost' IDENTIFIED BY 'anna123';
    Podgląd strony po tym kroku
    Podgląd strony po kroku 7
  8. Etap 2: Grafika i strona HTML

    Kroki 8-26 · po tym etapie masz 18 z 31 kryteriów (pkt)

    Krok 8: Grafika: wysokość 220 px z zachowaniem proporcji

    Kryteria:

    R.2.1 Plik wedka.jpg przeskalowano z zachowaniem proporcji tak, że jego wysokość wynosi dokładnie 220 px, odpowiadająca temu szerokość wynosi 330 px ±5 px

    ok. 2 min
    Polecenie z arkusza

    Plik wedka.jpg, wypakowany z archiwum, należy przeskalować z zachowaniem proporcji tak, aby jego wysokość wynosiła dokładnie 220 px

    Oryginał ma 500 × 333 px. W GIMP-ie Obraz → Skaluj obraz, łańcuch między szerokością a wysokością zamknięty (to jest „zachowanie proporcji”), wysokość 220 px - szerokość przelicza się sama: 500 × 220 / 333 = 330,3, czyli 330 px (klucz: 330 px ±5). Zapis pod tą samą nazwą: Plik → Nadpisz wedka.jpg.

    Typowe błędy

    Wpisanie samej wysokości przy rozpiętym łańcuchu daje obraz 500 × 220 - spłaszczone zdjęcie i brak punktu. Zwykłe Zapisz w GIMP-ie zapisuje format .xcf, a nie JPEG.

    Podgląd strony po tym kroku
    Podgląd strony po kroku 8
  9. Krok 9: Plik karta.html

    ok. 1 min
    Polecenie z arkusza

    Składa się ze strony o nazwie karta.html oraz skryptu zapisz.php. Poniższe wymagania dotyczą tylko pliku karta.html

    W edytorze tworzysz plik karta.html w folderze zdającego, obok wedka.jpg. To zwykła strona HTML - skrypt PHP będzie w osobnym pliku zapisz.php, do którego formularz wyśle dane. <!DOCTYPE html> oznacza HTML5, lang="pl" mówi przeglądarce i czytnikom ekranu, że treść jest po polsku.

    karta.html HTML nowy plik
    <!DOCTYPE html>
    <html lang="pl">
    <head>
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (karta.html)
  10. Krok 10: Kodowanie polskich znaków

    Kryteria:

    R.2.2 Witrynę internetową zapisano w pliku karta.html oraz zastosowano standard kodowania polskich znaków

    ok. 1 min
    Polecenie z arkusza

    Zastosowany właściwy standard kodowania polskich znaków

    <meta charset="UTF-8"> jako pierwsza rzecz w <head>. Bez tej linii „wędkarską”, „łowisk” i „imię” mogą wyświetlić się jako krzaki. Plik trzeba też zapisać w UTF-8 (w Notepad++ menu Kodowanie). Nazwa pliku i kodowanie to razem jedno kryterium (R.2.2).

    karta.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (karta.html)
  11. Krok 11: Tytuł strony

    Kryteria:

    R.2.3 Nadano tytuł strony: "Karty wędkarskie”

    ok. 1 min
    Polecenie z arkusza

    Tytuł strony widoczny na karcie przeglądarki: „Karty wędkarskie”

    <title> w <head> - napis na karcie przeglądarki. Uwaga na podobne teksty: tytuł to „Karty wędkarskie”, nagłówek banera - „Zgłoszenie na kartę wędkarską”, a odnośnik - „Karta wędkarska”.

    karta.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Karty wędkarskie</title>
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (karta.html)
  12. Krok 12: Podpięcie arkusza stylów styl_1.css

    Kryteria:

    R.3.5 Strona zawiera działające połączenie z zewnętrznym arkuszem stylów o nazwie styl_1.css , formatowanie pochodzi jedynie z tego arkusza Uwaga: kryterium to nie jest spełnione również, gdy źle przypisano co najmniej jeden selektor do bloku (np. kropka zamiast #)

    ok. 1 min
    Polecenie z arkusza

    Arkusz stylów w pliku o nazwie styl_1.css prawidłowo połączony z kodem strony

    <link rel="stylesheet" href="styl_1.css"> w <head>. W nazwie jest podkreślenie i cyfra: styl_1.css. Plik stylów powstanie po HTML-u.

    Typowe błędy

    Zła nazwa w href to strona bez stylów, a klucz uznaje R.3.5 tylko przy działającym połączeniu, w którym wszystkie selektory trafiają w bloki (kropka zamiast # też odbiera punkt).

    karta.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Karty wędkarskie</title>
        <link rel="stylesheet" href="styl_1.css">
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (karta.html)
  13. Krok 13: Bloki: baner, główny i trzy dolne

    Kryteria:

    R.2.4 Wygląd strony zdefiniowano dzieląc ją na bloki: baner, główny, trzy bloki: lewy, środkowy i prawy. Zastosowano znaczniki sekcji

    ok. 2 min
    Polecenie z arkusza

    Podział strony na bloki: na górze blok banera, poniżej blok główny, na dole trzy bloki: lewy, środkowy i prawy. Podział zrealizowany za pomocą znaczników sekcji tak, aby po uruchomieniu w przeglądarce wygląd układu bloków był zgodny z Obrazem 2

    Pięć bloków w kolejności z obrazu 2: baner <header>, a blok główny i trzy dolne jako <section>. Każda sekcja dostaje identyfikator, bo w CSS mają różne kolory i wymiary: main, left, middle i right (nazwy po angielsku - arkusz ich nie narzuca). Bloki są na razie puste i stoją jeden pod drugim; trzy dolne ustawi obok siebie CSS.

    karta.html HTML zmienione: 10 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Karty wędkarskie</title>
        <link rel="stylesheet" href="styl_1.css">
    </head>
    <body>
        <header>
        </header>
        <section id="main">
        </section>
        <section id="left">
        </section>
        <section id="middle">
        </section>
        <section id="right">
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (karta.html)
  14. Krok 14: Baner: nagłówek drugiego stopnia

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku banera: nagłówek drugiego stopnia o treści „Zgłoszenie na kartę wędkarską”

    Drugiego stopnia to <h2> - w tym arkuszu baner nie ma nagłówka <h1>. Klucz R.2.5 sprawdza go razem z nagłówkiem <h4> i paragrafem w bloku prawym - punkt przyjdzie po kroku z paragrafem.

    karta.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Karty wędkarskie</title>
        <link rel="stylesheet" href="styl_1.css">
    </head>
    <body>
        <header>
            <h2>Zgłoszenie na kartę wędkarską</h2>
        </header>
        <section id="main">
        </section>
        <section id="left">
        </section>
        <section id="middle">
        </section>
        <section id="right">
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (karta.html)
  15. Krok 15: Blok główny: nagłówek czwartego stopnia

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku głównego: Nagłówek czwartego stopnia o treści: „Formularz - karta wędkarska”

    <h4> - nagłówek czwartego stopnia, mniejszy niż zwykły tekst w niektórych przeglądarkach, ale pogrubiony.

    karta.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Karty wędkarskie</title>
        <link rel="stylesheet" href="styl_1.css">
    </head>
    <body>
        <header>
            <h2>Zgłoszenie na kartę wędkarską</h2>
        </header>
        <section id="main">
            <h4>Formularz - karta wędkarska</h4>
        </section>
        <section id="left">
        </section>
        <section id="middle">
        </section>
        <section id="right">
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (karta.html)
  16. Krok 16: Formularz wysyłający dane metodą POST do zapisz.php

    Kryteria:

    R.3.4 Formularz wysyła dane metodą POST do pliku zapisz.php

    ok. 2 min
    Polecenie z arkusza

    Formularz wysyłający dane metodą POST do pliku zapisz.php zawierający pola

    • action="zapisz.php" - adres, pod który przeglądarka wyśle dane po kliknięciu przycisku wysyłającego,
    • method="post" - dane jadą w treści żądania, a nie w adresie strony; w PHP odczyta je tablica $_POST.

    Formularz sprawdza się tylko przez serwer: stronę otwierasz jako http://localhost/…/karta.html, a nie dwuklikiem z dysku - inaczej przeglądarka pokaże kod zapisz.php zamiast go wykonać.

    Typowe błędy

    method="get" dopisze dane do adresu (zapisz.php?imie=...), a skrypt czytający $_POST nic nie dostanie.

    karta.html HTML zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Karty wędkarskie</title>
        <link rel="stylesheet" href="styl_1.css">
    </head>
    <body>
        <header>
            <h2>Zgłoszenie na kartę wędkarską</h2>
        </header>
        <section id="main">
            <h4>Formularz - karta wędkarska</h4>
            <form action="zapisz.php" method="post">
            </form>
        </section>
        <section id="left">
        </section>
        <section id="middle">
        </section>
        <section id="right">
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (karta.html)
  17. Krok 17: Pole „imię: ” podpisane powyżej

    ok. 1 min
    Polecenie z arkusza

    Pole edycyjne podpisane powyżej tekstem: „imię: ”

    „Podpisane powyżej” - napis, potem złamanie linii <br>, a pole w nowej linii, jak na obrazie 2. name="imie" (bez polskiej litery, tak jak kolumna w bazie) to klucz, pod którym wartość trafi do PHP - $_POST['imie']. Drugie <br> przenosi kolejny napis niżej.

    karta.html HTML zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Karty wędkarskie</title>
        <link rel="stylesheet" href="styl_1.css">
    </head>
    <body>
        <header>
            <h2>Zgłoszenie na kartę wędkarską</h2>
        </header>
        <section id="main">
            <h4>Formularz - karta wędkarska</h4>
            <form action="zapisz.php" method="post">
                imię:<br>
                <input type="text" name="imie"><br>
            </form>
        </section>
        <section id="left">
        </section>
        <section id="middle">
        </section>
        <section id="right">
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (karta.html)
  18. Krok 18: Pole „nazwisko: ” podpisane powyżej

    ok. 1 min
    Polecenie z arkusza

    Pole edycyjne podpisane powyżej tekstem: „nazwisko: ”

    Ten sam układ: napis, <br>, pole name="nazwisko", <br>.

    karta.html HTML zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Karty wędkarskie</title>
        <link rel="stylesheet" href="styl_1.css">
    </head>
    <body>
        <header>
            <h2>Zgłoszenie na kartę wędkarską</h2>
        </header>
        <section id="main">
            <h4>Formularz - karta wędkarska</h4>
            <form action="zapisz.php" method="post">
                imię:<br>
                <input type="text" name="imie"><br>
                nazwisko:<br>
                <input type="text" name="nazwisko"><br>
            </form>
        </section>
        <section id="left">
        </section>
        <section id="middle">
        </section>
        <section id="right">
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (karta.html)
  19. Krok 19: Pole „adres: ” o rozmiarze 30

    ok. 1 min
    Polecenie z arkusza

    Pole edycyjne podpisane powyżej tekstem: „adres: ”; pole ma rozmiar 30

    Atrybut size="30" ustawia szerokość pola na około 30 znaków - dlatego na obrazie 2 pole adresu jest dłuższe niż pola imienia i nazwiska. Klucz przyjmuje też maxlength albo szerokość w CSS (R.2.8).

    Typowe błędy

    size zmienia tylko szerokość widoczną na ekranie, a maxlength - największą liczbę znaków, którą da się wpisać. Klucz przyjmuje oba, ale „rozmiar” pola to size.

    karta.html HTML zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Karty wędkarskie</title>
        <link rel="stylesheet" href="styl_1.css">
    </head>
    <body>
        <header>
            <h2>Zgłoszenie na kartę wędkarską</h2>
        </header>
        <section id="main">
            <h4>Formularz - karta wędkarska</h4>
            <form action="zapisz.php" method="post">
                imię:<br>
                <input type="text" name="imie"><br>
                nazwisko:<br>
                <input type="text" name="nazwisko"><br>
                adres:<br>
                <input type="text" name="adres" size="30"><br>
            </form>
        </section>
        <section id="left">
        </section>
        <section id="middle">
        </section>
        <section id="right">
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (karta.html)
  20. Krok 20: Przycisk „CZYŚĆ”

    ok. 1 min
    Polecenie z arkusza

    Przycisk czyszczący zawartość formularza z etykietą „CZYŚĆ”

    <input type="reset"> przywraca polom formularza wartości początkowe - tutaj puste. Napis na przycisku to value. Nie potrzeba do tego ani linijki JavaScriptu.

    karta.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Karty wędkarskie</title>
        <link rel="stylesheet" href="styl_1.css">
    </head>
    <body>
        <header>
            <h2>Zgłoszenie na kartę wędkarską</h2>
        </header>
        <section id="main">
            <h4>Formularz - karta wędkarska</h4>
            <form action="zapisz.php" method="post">
                imię:<br>
                <input type="text" name="imie"><br>
                nazwisko:<br>
                <input type="text" name="nazwisko"><br>
                adres:<br>
                <input type="text" name="adres" size="30"><br>
                <input type="reset" value="CZYŚĆ">
            </form>
        </section>
        <section id="left">
        </section>
        <section id="middle">
        </section>
        <section id="right">
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (karta.html)
  21. Krok 21: Przycisk „ZAPISZ”

    Kryteria: ,

    R.2.8 W bloku głównym umieszczono formularz z trzema polami edycyjnymi w tym pole do wpisania adresu ma rozmiar 30 (size lub maxlength lub width lub w CSS) oraz dwoma przyciskami "CZYŚĆ" i "ZAPISZ"

    R.3.3 Pierwszy przycisk czyści zawartość formularza, drugi przycisk wysyła dane z formularza (input z typem submit lub button)

    ok. 1 min
    Polecenie z arkusza

    Przycisk wysyłający zawartość formularza z etykietą „ZAPISZ”

    <input type="submit"> wysyła formularz pod adres z action. Formularz jest kompletny: trzy pola edycyjne, w tym pole adresu o rozmiarze 30, i dwa przyciski (R.2.8); pierwszy czyści, drugi wysyła (R.3.3).

    Typowe błędy

    <input type="button"> wygląda tak samo, ale niczego nie wysyła - brak punktu R.3.3. Kolejność ma znaczenie: klucz mówi o pierwszym przycisku czyszczącym i drugim wysyłającym.

    karta.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Karty wędkarskie</title>
        <link rel="stylesheet" href="styl_1.css">
    </head>
    <body>
        <header>
            <h2>Zgłoszenie na kartę wędkarską</h2>
        </header>
        <section id="main">
            <h4>Formularz - karta wędkarska</h4>
            <form action="zapisz.php" method="post">
                imię:<br>
                <input type="text" name="imie"><br>
                nazwisko:<br>
                <input type="text" name="nazwisko"><br>
                adres:<br>
                <input type="text" name="adres" size="30"><br>
                <input type="reset" value="CZYŚĆ">
                <input type="submit" value="ZAPISZ">
            </form>
        </section>
        <section id="left">
        </section>
        <section id="middle">
        </section>
        <section id="right">
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (karta.html)
  22. Krok 22: Blok lewy: nagłówek „Typy łowisk”

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku lewego: Nagłówek czwartego stopnia o treści: „Typy łowisk”

    Drugi <h4> na stronie - tym razem w bloku lewym.

    karta.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Karty wędkarskie</title>
        <link rel="stylesheet" href="styl_1.css">
    </head>
    <body>
        <header>
            <h2>Zgłoszenie na kartę wędkarską</h2>
        </header>
        <section id="main">
            <h4>Formularz - karta wędkarska</h4>
            <form action="zapisz.php" method="post">
                imię:<br>
                <input type="text" name="imie"><br>
                nazwisko:<br>
                <input type="text" name="nazwisko"><br>
                adres:<br>
                <input type="text" name="adres" size="30"><br>
                <input type="reset" value="CZYŚĆ">
                <input type="submit" value="ZAPISZ">
            </form>
        </section>
        <section id="left">
            <h4>Typy łowisk</h4>
        </section>
        <section id="middle">
        </section>
        <section id="right">
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (karta.html)
  23. Krok 23: Lista punktowana typów łowisk

    Kryteria:

    R.2.6 W bloku lewym umieszczono listę punktowaną (nieuporządkowaną) z czterema elementami: Zalewy, Stawy, Jeziora, Rzeki, zastosowano znaczniki <ul>, <li> oraz ich zamknięcia

    ok. 1 min
    Polecenie z arkusza

    Lista punktowana (nieuporządkowana) zawierająca elementy: Zalewy, Stawy, Jeziora, Rzeki

    Lista punktowana (nieuporządkowana) to <ul>, każdy element w <li>. Kropki dopisze przeglądarka (R.2.6).

    Typowe błędy

    <ol> to lista numerowana - klucz wymaga <ul> i <li> wraz z ich zamknięciami.

    karta.html HTML zmienione: 6 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Karty wędkarskie</title>
        <link rel="stylesheet" href="styl_1.css">
    </head>
    <body>
        <header>
            <h2>Zgłoszenie na kartę wędkarską</h2>
        </header>
        <section id="main">
            <h4>Formularz - karta wędkarska</h4>
            <form action="zapisz.php" method="post">
                imię:<br>
                <input type="text" name="imie"><br>
                nazwisko:<br>
                <input type="text" name="nazwisko"><br>
                adres:<br>
                <input type="text" name="adres" size="30"><br>
                <input type="reset" value="CZYŚĆ">
                <input type="submit" value="ZAPISZ">
            </form>
        </section>
        <section id="left">
            <h4>Typy łowisk</h4>
            <ul>
                <li>Zalewy</li>
                <li>Stawy</li>
                <li>Jeziora</li>
                <li>Rzeki</li>
            </ul>
        </section>
        <section id="middle">
        </section>
        <section id="right">
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (karta.html)
  24. Krok 24: Blok środkowy: zdjęcie z tekstem alternatywnym

    Kryteria:

    R.2.7 W bloku środkowym umieszczono obraz wedka.jpg oraz ma on tekst alternatywny "karta wędkarska"

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku środkowego: obraz wedka.jpg z tekstem alternatywnym o treści: „karta wędkarska”

    <img> z atrybutami src (przeskalowany plik z folderu zdającego) i alt - tekst, który czytnik ekranu przeczyta zamiast zdjęcia i który pokaże się, gdy plik się nie wczyta (R.2.7). Znacznik <img> w HTML5 nie ma znacznika zamykającego.

    karta.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Karty wędkarskie</title>
        <link rel="stylesheet" href="styl_1.css">
    </head>
    <body>
        <header>
            <h2>Zgłoszenie na kartę wędkarską</h2>
        </header>
        <section id="main">
            <h4>Formularz - karta wędkarska</h4>
            <form action="zapisz.php" method="post">
                imię:<br>
                <input type="text" name="imie"><br>
                nazwisko:<br>
                <input type="text" name="nazwisko"><br>
                adres:<br>
                <input type="text" name="adres" size="30"><br>
                <input type="reset" value="CZYŚĆ">
                <input type="submit" value="ZAPISZ">
            </form>
        </section>
        <section id="left">
            <h4>Typy łowisk</h4>
            <ul>
                <li>Zalewy</li>
                <li>Stawy</li>
                <li>Jeziora</li>
                <li>Rzeki</li>
            </ul>
        </section>
        <section id="middle">
            <img src="wedka.jpg" alt="karta wędkarska">
        </section>
        <section id="right">
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (karta.html)
  25. Krok 25: Blok prawy: paragraf z autorem strony

    Kryteria:

    R.2.5 W banerze zapisano nagłówek h2: "Zgłoszenie na kartę wędkarską" oraz zapisano przynajmniej jeden nagłówek h4 z: "Formularz - karta wędkarska" w bloku głównym lub "Typy łowisk" w lewym oraz w bloku prawym paragraf z numerem PESEL lub innym numerem, którym został podpisany arkusz

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku prawego: Akapit (paragraf) o treści: „Stronę przygotował: ”, dalej wstawiony numer PESEL zdającego lub w przypadku jego braku inny numer, którym został podpisany arkusz

    Na egzaminie po dwukropku wpisujesz swój numer PESEL. W tym rozwiązaniu w jego miejscu stoi imię i nazwisko autora: Bartosz Bryniarski. Tekst w znaczniku <p>. Strona ma teraz nagłówek <h2> w banerze, nagłówki <h4> w bloku głównym i lewym oraz paragraf w bloku prawym (R.2.5).

    karta.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Karty wędkarskie</title>
        <link rel="stylesheet" href="styl_1.css">
    </head>
    <body>
        <header>
            <h2>Zgłoszenie na kartę wędkarską</h2>
        </header>
        <section id="main">
            <h4>Formularz - karta wędkarska</h4>
            <form action="zapisz.php" method="post">
                imię:<br>
                <input type="text" name="imie"><br>
                nazwisko:<br>
                <input type="text" name="nazwisko"><br>
                adres:<br>
                <input type="text" name="adres" size="30"><br>
                <input type="reset" value="CZYŚĆ">
                <input type="submit" value="ZAPISZ">
            </form>
        </section>
        <section id="left">
            <h4>Typy łowisk</h4>
            <ul>
                <li>Zalewy</li>
                <li>Stawy</li>
                <li>Jeziora</li>
                <li>Rzeki</li>
            </ul>
        </section>
        <section id="middle">
            <img src="wedka.jpg" alt="karta wędkarska">
        </section>
        <section id="right">
            <p>Stronę przygotował: Bartosz Bryniarski</p>
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (karta.html)
  26. Krok 26: Odnośnik do strony kartawedkarska.pl

    Kryteria:

    R.3.2 Wybranie odnośnika "Karta wędkarska" inicjuje otwarcie strony http://www.kartawedkarska.pl/

    ok. 1 min
    Polecenie z arkusza

    Odnośnik do strony „http://www.kartawedkarska.pl/” o treści: „Karta wędkarska”

    <a href="http://www.kartawedkarska.pl/"> - adres przepisany dokładnie z arkusza, z http:// na początku. Bez protokołu przeglądarka szukałaby pliku o takiej nazwie w folderze strony (R.3.2). Odnośnik stoi pod paragrafem, poza nim - na obrazie 2 to osobny prostokąt.

    karta.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Karty wędkarskie</title>
        <link rel="stylesheet" href="styl_1.css">
    </head>
    <body>
        <header>
            <h2>Zgłoszenie na kartę wędkarską</h2>
        </header>
        <section id="main">
            <h4>Formularz - karta wędkarska</h4>
            <form action="zapisz.php" method="post">
                imię:<br>
                <input type="text" name="imie"><br>
                nazwisko:<br>
                <input type="text" name="nazwisko"><br>
                adres:<br>
                <input type="text" name="adres" size="30"><br>
                <input type="reset" value="CZYŚĆ">
                <input type="submit" value="ZAPISZ">
            </form>
        </section>
        <section id="left">
            <h4>Typy łowisk</h4>
            <ul>
                <li>Zalewy</li>
                <li>Stawy</li>
                <li>Jeziora</li>
                <li>Rzeki</li>
            </ul>
        </section>
        <section id="middle">
            <img src="wedka.jpg" alt="karta wędkarska">
        </section>
        <section id="right">
            <p>Stronę przygotował: Bartosz Bryniarski</p>
            <a href="http://www.kartawedkarska.pl/">Karta wędkarska</a>
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (karta.html)
  27. Etap 3: Styl CSS

    Kroki 27-33 · po tym etapie masz 27 z 31 kryteriów (pkt)

    Krok 27: Plik styl_1.css: krój Georgia dla całej strony

    Kryteria:

    R.4.1 Ustawiono domyślny krój czcionki dla całej strony na Georgia (dla selektora * lub body lub html lub kontenera całej strony)

    ok. 1 min
    Polecenie z arkusza

    Cechy formatowania CSS: Są zawarte wyłącznie w zewnętrznym arkuszu stylów. Domyślne dla całej strony: krój czcionki Georgia

    Nowy plik styl_1.css w folderze zdającego - od teraz każda reguła trafia tylko tutaj, bez atrybutów style w HTML-u. Pierwsza reguła: selektor uniwersalny * z font-family: Georgia.

    Dlaczego *, a nie body: pola formularza i przyciski nie dziedziczą kroju po body, a na obrazie 2 napisy „CZYŚĆ” i „ZAPISZ” są pisane krojem szeryfowym. Klucz R.4.1 przyjmuje oba selektory.

    styl_1.css CSS nowy plik
    * {
        font-family: Georgia;
    }
    Podgląd strony po tym kroku (karta.html)
  28. Krok 28: Baner: tło, kolor tekstu, marginesy wewnętrzne, wyrównanie

    ok. 1 min
    Polecenie z arkusza

    Dla bloku banera: kolor tła DodgerBlue, biały kolor czcionki, marginesy wewnętrzne 10 px, wyrównanie tekstu do środka

    Selektor znacznika header - na stronie jest jeden baner. DodgerBlue i white to nazwy kolorów CSS, „marginesy wewnętrzne” to padding, a text-align: center wyśrodkowuje nagłówek.

    styl_1.css CSS zmienione: 6 linii
    * {
        font-family: Georgia;
    }
    header {
        background-color: DodgerBlue;
        color: white;
        padding: 10px;
        text-align: center;
    }
    Podgląd strony po tym kroku (karta.html)
  29. Krok 29: Blok główny: tło LightBlue i marginesy wewnętrzne

    Kryteria:

    R.4.7 Ustawiono marginesy wewnętrzne (padding) dla banera na 10px i bloku głównego na 100px

    ok. 1 min
    Polecenie z arkusza

    Dla bloku głównego: kolor tła LightBlue, marginesy wewnętrzne 100 px

    Selektor identyfikatora #main - z krzyżykiem, bo w HTML-u jest id="main". padding: 100px odsuwa formularz od wszystkich czterech krawędzi bloku - stąd duży jasnoniebieski obszar na obrazie 2. Marginesy wewnętrzne banera i bloku głównego dają R.4.7.

    styl_1.css CSS zmienione: 4 linie
    * {
        font-family: Georgia;
    }
    header {
        background-color: DodgerBlue;
        color: white;
        padding: 10px;
        text-align: center;
    }
    #main {
        background-color: LightBlue;
        padding: 100px;
    }
    Podgląd strony po tym kroku (karta.html)
  30. Krok 30: Blok lewy: tło, kolor tekstu, szerokość, wysokość

    ok. 1 min
    Polecenie z arkusza

    Dla bloku lewego: kolor tła DodgerBlue, biały kolor czcionki, szerokość 20%, wysokość 220 px

    Wysokość 220 px to dokładnie wysokość zdjęcia po skalowaniu - trzy dolne bloki będą równe zdjęciu.

    styl_1.css CSS zmienione: 6 linii
    * {
        font-family: Georgia;
    }
    header {
        background-color: DodgerBlue;
        color: white;
        padding: 10px;
        text-align: center;
    }
    #main {
        background-color: LightBlue;
        padding: 100px;
    }
    #left {
        background-color: DodgerBlue;
        color: white;
        width: 20%;
        height: 220px;
    }
    Podgląd strony po tym kroku (karta.html)
  31. Krok 31: Blok środkowy i prawy: wspólna reguła

    Kryteria: , , , ,

    R.4.2 Ustawiono kolor tła DodgerBlue dla banera i trzech bloków dolnych oraz kolor LightBlue dla bloku głównego

    R.4.3 Ustawiono biały kolor czcionki dla banera i trzech bloków dolnych

    R.4.4 Ustawiono wysokość trzech bloków dolnych na 220px

    R.4.5 Ustawiono szerokość dolnych bloków: lewego na 20% oraz środkowego i prawego na 40%

    R.4.6 Ustawiono wyrównanie tekstu do środka dla banera, bloku środkowego i prawego

    ok. 2 min
    Polecenie z arkusza

    Wspólne dla bloku środkowego i bloku prawego: kolor tła DodgerBlue, biały kolor czcionki, szerokość 40%, wysokość 220 px, wyrównanie tekstu do środka

    „Wspólne” - dwa selektory rozdzielone przecinkiem dostają jedną regułę. Teraz komplet kolorów tła (R.4.2), biały tekst banera i trzech dolnych bloków (R.4.3), wysokości 220 px (R.4.4), szerokości 20% + 40% + 40% = 100% (R.4.5) i wyśrodkowanie banera, bloku środkowego i prawego (R.4.6). text-align: center wyśrodkowuje też zdjęcie, bo <img> jest elementem w linii tekstu.

    Typowe błędy

    Bloki o sumie szerokości 100% nie mogą mieć marginesów, padding ani obramowań - każdy piksel więcej zepchnie blok prawy pod pozostałe.

    styl_1.css CSS zmienione: 7 linii
    * {
        font-family: Georgia;
    }
    header {
        background-color: DodgerBlue;
        color: white;
        padding: 10px;
        text-align: center;
    }
    #main {
        background-color: LightBlue;
        padding: 100px;
    }
    #left {
        background-color: DodgerBlue;
        color: white;
        width: 20%;
        height: 220px;
    }
    #middle, #right {
        background-color: DodgerBlue;
        color: white;
        width: 40%;
        height: 220px;
        text-align: center;
    }
    Podgląd strony po tym kroku (karta.html)
  32. Krok 32: Układ trzech dolnych bloków zgodny z obrazem 2

    Kryteria:

    R.3.1 Układ bloków po uruchomieniu strony w przeglądarce jest zgodny z Obrazem 2 w arkuszu egzaminacyjnym (prawidłowo zastosowano właściwości CSS układające bloki na stronie, np. float i clear albo display flex albo grid)

    ok. 2 min
    Polecenie z arkusza

    Podział zrealizowany za pomocą znaczników sekcji tak, aby po uruchomieniu w przeglądarce wygląd układu bloków był zgodny z Obrazem 2

    Trzy dolne bloki dostają float: left: blok lewy (20%) staje przy lewej krawędzi, środkowy (40%) obok niego, a prawy (40%) - obok środkowego. Razem mają dokładnie 100% szerokości, więc mieszczą się w jednym rzędzie. Baner i blok główny nie pływają - zajmują całą szerokość, jeden pod drugim.

    Pod pływającymi blokami nie ma już żadnego elementu, więc clear nie jest potrzebne. Klucz R.3.1 przyjmuje float, flex albo grid; wersja nowoczesna pokazuje ten sam układ we flex.

    Typowe błędy

    float na samym bloku lewym nie wystarczy: środkowy blok jako zwykły blok zajmie całą szerokość pod nim, a prawy stanie jeszcze niżej.

    styl_1.css CSS zmienione: 3 linie
    * {
        font-family: Georgia;
    }
    header {
        background-color: DodgerBlue;
        color: white;
        padding: 10px;
        text-align: center;
    }
    #main {
        background-color: LightBlue;
        padding: 100px;
    }
    #left {
        background-color: DodgerBlue;
        color: white;
        width: 20%;
        height: 220px;
    }
    #middle, #right {
        background-color: DodgerBlue;
        color: white;
        width: 40%;
        height: 220px;
        text-align: center;
    }
    #left, #middle, #right {
        float: left;
    }
    Podgląd strony po tym kroku (karta.html)
  33. Krok 33: Odnośnik: obramowanie kreskowane, tło i kolor tekstu

    Kryteria:

    R.4.8 Ustawiono styl odnośnika: obramowanie 1px dashed DimGray, kolor tła Gold, kolor czcionki DarkRed, marginesy wewnętrzne 10px (selektor a lub klasa lub identyfikator)

    ok. 2 min
    Polecenie z arkusza

    Dla znacznika odnośnika: obramowanie linią kreskowaną o szerokości 1 px i kolorze DimGray, kolor tła Gold, kolor czcionki DarkRed, marginesy wewnętrzne 10 px

    Selektor znacznika a. Skrót border: 1px dashed DimGray - szerokość, styl linii (dashed - kreskowana, dotted - kropkowana, solid - ciągła) i kolor w jednej właściwości. Złoty prostokąt z ciemnoczerwonym napisem, jak na obrazie 2 (R.4.8). Arkusz stylów jest kompletny.

    Typowe błędy

    dotted to linia z kropek, a arkusz chce kreskowanej - dashed.

    styl_1.css CSS zmienione: 6 linii
    * {
        font-family: Georgia;
    }
    header {
        background-color: DodgerBlue;
        color: white;
        padding: 10px;
        text-align: center;
    }
    #main {
        background-color: LightBlue;
        padding: 100px;
    }
    #left {
        background-color: DodgerBlue;
        color: white;
        width: 20%;
        height: 220px;
    }
    #middle, #right {
        background-color: DodgerBlue;
        color: white;
        width: 40%;
        height: 220px;
        text-align: center;
    }
    #left, #middle, #right {
        float: left;
    }
    a {
        border: 1px dashed DimGray;
        background-color: Gold;
        color: DarkRed;
        padding: 10px;
    }
    Podgląd strony po tym kroku (karta.html)
  34. Etap 4: Skrypt PHP

    Kroki 34-37 · po tym etapie masz 31 z 31 kryteriów (pkt)

    Krok 34: Plik zapisz.php i połączenie z bazą wedkowanie

    Kryteria:

    R.5.1 Skrypt realizuje połączenie z serwerem bazy danych i wybór bazy wedkowanie

    ok. 3 min
    Polecenie z arkusza

    Skrypt połączenia z bazą. Napisany w języku PHP, w pliku zapisz.php. Skrypt łączy się z serwerem bazodanowym na localhost, użytkownik root bez hasła, baza danych o nazwie wedkowanie

    Nowy plik zapisz.php w folderze zdającego - ten sam, który wskazuje action formularza. Cały plik to skrypt między <?php a ?>.

    Pierwsza instrukcja: mysqli_connect z tabeli 1 arkusza - kolejno serwer localhost, użytkownik root, puste hasło '' i nazwa bazy wedkowanie. Połączenie trafia do zmiennej $connection, z której skorzystają kolejne funkcje (R.5.1).

    Skrypt niczego nie wypisuje - arkusz nie każe pokazywać żadnego komunikatu - więc po wysłaniu formularza przeglądarka pokaże pustą stronę. Efekt widać w bazie. Dlatego podgląd w krokach skryptu pokazuje formularz z karta.html, a od kroku z zapytaniem - tabelę w phpMyAdmin po wysłaniu formularza.

    zapisz.php PHP nowy plik
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'wedkowanie');
    ?>

    Podgląd strony bez zmian - taki jak po kroku 33.

  35. Krok 35: Dane z formularza w tablicy $_POST

    Kryteria:

    R.5.3 Skrypt pobiera dane z formularza za pomocą tablicy $_POST (lub $_REQUEST gdy sprawdzono, że REQUEST_METHOD jest równe POST)

    ok. 2 min
    Polecenie z arkusza

    Skrypt działa na danych przesłanych z formularza

    Trzy wartości z formularza trafiają do zmiennych o tych samych nazwach. Kluczem w $_POST jest atrybut name pola: $_POST['imie'], $_POST['nazwisko'], $_POST['adres'] (R.5.3). Tablica $_POST istnieje, bo formularz ma method="post".

    Typowe błędy

    Nazwa w nawiasie musi być identyczna z name w HTML-u: $_POST['imię'] (z „ę”) albo $_POST['Imie'] nie znajdzie pola i PHP zgłosi ostrzeżenie „Undefined array key”.

    zapisz.php PHP zmienione: 3 linie
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'wedkowanie');
    $imie = $_POST['imie'];
    $nazwisko = $_POST['nazwisko'];
    $adres = $_POST['adres'];
    ?>

    Podgląd strony bez zmian - taki jak po kroku 33.

  36. Krok 36: Zmodyfikowane zapytanie 1 z danymi z formularza

    Kryteria:

    R.5.4 Skrypt wysyła do bazy danych zapytanie 1 wstawiające dane do bazy: pola data_zezwolenia i punkty = NULL, pozostałe wartości wypełnione są danymi z formularza. Należy sprawdzić w bazie czy rekord został dodany

    ok. 3 min
    Polecenie z arkusza

    Skrypt wysyła do bazy danych zmodyfikowane zapytanie 1, które w polach data_zezwolenia i punkty zawiera wartość NULL, pozostałe wartości wypełnione są danymi z formularza

    Zapytanie 1 z kwerendy.txt z trzema zmianami: w miejsce 'Grzegorz', 'Niemczyk' i adresu stoją zmienne '$imie', '$nazwisko', '$adres', a w miejsce daty i punktów - NULL (bez apostrofów, bo to „brak wartości”, a nie napis). Pierwsze NULL zostaje: id nadaje baza. Całe zapytanie jest w cudzysłowie "…", więc PHP podstawia wartości zmiennych, a apostrofy w środku są ogranicznikami napisów w SQL.

    Sprawdzenie, jak każe klucz (R.5.4): formularz z danymi Marek, Lis, „Sopot, Morska 3” i w phpMyAdmin nowy wiersz 3 z NULL w kolumnach data_zezwolenia i punkty - podgląd pokazuje tabelę po wysłaniu.

    Typowe błędy

    'NULL' w apostrofach to napis: w kolumnie DATE zamieni się na „0000-00-00” albo zgłosi błąd, zamiast zostawić puste pole. Zapytanie w apostrofach 'INSERT ... '$imie' ...' - PHP nie podstawi zmiennych.

    Tabela z archiwum ma kodowanie latin1, które nie zna liter ą, ć, ę, ł, ń, ś, ź, ż - dane Łukasz Żółć, Gdańsk zapisały się jako „?ukasz ?ó??, Gda?sk”. To nie jest błąd skryptu i nie traci się za to punktu: klucz sprawdza import pliku bez zmian, więc kodowania tabeli nie zmieniasz.

    zapisz.php PHP zmienione: 1 linia
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'wedkowanie');
    $imie = $_POST['imie'];
    $nazwisko = $_POST['nazwisko'];
    $adres = $_POST['adres'];
    mysqli_query($connection, "INSERT INTO karty_wedkarskie VALUES (NULL, '$imie', '$nazwisko', '$adres', NULL, NULL);");
    ?>
    Podgląd strony po tym kroku (karta.html)
    Podgląd strony po kroku 36
  37. Krok 37: Zamknięcie połączenia z bazą

    Kryteria:

    R.5.2 Ostatnią operacją na bazie jest jej zamknięcie (zgodne ze składnią)

    ok. 1 min
    Polecenie z arkusza

    Na końcu działania skrypt zamyka połączenie z serwerem.

    mysqli_close($connection) jako ostatnia instrukcja skryptu - po zapytaniu (R.5.2). Skrypt spełnia wszystkie kryteria arkusza. Dalej trzy kroki o zabezpieczeniach - klucz ich nie wymaga.

    Typowe błędy

    mysqli_close przed mysqli_query sprawia, że zapytanie dostaje zamknięte połączenie i PHP kończy się błędem - a klucz wymaga, by zamknięcie było ostatnią operacją na bazie.

    zapisz.php PHP zmienione: 1 linia
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'wedkowanie');
    $imie = $_POST['imie'];
    $nazwisko = $_POST['nazwisko'];
    $adres = $_POST['adres'];
    mysqli_query($connection, "INSERT INTO karty_wedkarskie VALUES (NULL, '$imie', '$nazwisko', '$adres', NULL, NULL);");
    mysqli_close($connection);
    ?>

    Podgląd strony bez zmian - taki jak po kroku 36.

  38. Etap 5: Dobre praktyki (poza kluczem)

    Kroki 38-40 · po tym etapie masz 31 z 31 kryteriów (pkt)

    Krok 38: Zabezpieczenie: zapytanie przygotowane

    ok. 4 min
    Polecenie z arkusza

    Skrypt wysyła do bazy danych zmodyfikowane zapytanie 1, które w polach data_zezwolenia i punkty zawiera wartość NULL, pozostałe wartości wypełnione są danymi z formularza

    Dane z formularza trafiają do zapytania wprost - to SQL injection. Sprawdzone na wersji z poprzednich kroków:

    • w pole adresu wpisano x', NULL, NULL), (NULL, 'Jan', 'Mistrz', 'Gdynia', '2018-01-01', 999) -- - apostrof kończy napis, a reszta staje się kodem SQL. Do tabeli trafiły dwa rekordy, w tym wymyślony wędkarz z 999 punktami i datą zezwolenia, choć formularz w ogóle nie ma takich pól - zapytanie 2 pokazuje go teraz obok Jana Kowalskiego,
    • nazwisko z apostrofem, np. O'Brien, rozbija składnię - PHP 8.1 i nowsze zgłaszają wyjątek mysqli_sql_exception i zamiast strony widać „Fatal error”.

    Lekarstwo to zapytanie przygotowane: mysqli_prepare ze znakami ? w miejscu danych, mysqli_stmt_bind_param z typami 'sss' (trzy napisy) i mysqli_stmt_execute. Baza dostaje treść zapytania i dane osobno, więc dane nigdy nie staną się kodem SQL. Podgląd: ten sam „adres-atak” zapisuje się jako zwykły, dziwny adres jednej osoby, a O'Brien zapisuje się bez błędu. Stara linia zostaje w komentarzu. Na egzaminie wystarczy wersja wcześniejsza - klucz tego nie sprawdza.

    Typowe błędy

    Liczba liter w 'sss' musi równać się liczbie znaków ? i liczbie zmiennych - inaczej mysqli_stmt_bind_param zgłosi błąd i rekord nie powstanie.

    zapisz.php PHP zmienione: 4 linie
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'wedkowanie');
    $imie = $_POST['imie'];
    $nazwisko = $_POST['nazwisko'];
    $adres = $_POST['adres'];
    // mysqli_query($connection, "INSERT INTO karty_wedkarskie VALUES (NULL, '$imie', '$nazwisko', '$adres', NULL, NULL);");
    $statement = mysqli_prepare($connection, 'INSERT INTO karty_wedkarskie VALUES (NULL, ?, ?, ?, NULL, NULL);');
    mysqli_stmt_bind_param($statement, 'sss', $imie, $nazwisko, $adres);
    mysqli_stmt_execute($statement);
    mysqli_close($connection);
    ?>
    Podgląd strony po tym kroku (karta.html)
    Podgląd strony po kroku 38
  39. Krok 39: Zabezpieczenie: sprawdzenie danych przed zapisem

    ok. 4 min
    Polecenie z arkusza

    Skrypt działa na danych przesłanych z formularza

    Dwa przypadki, które w wersji egzaminacyjnej zapisują do bazy śmieci - oba sprawdzone:

    • wejście na zapisz.php bez formularza (np. z historii przeglądarki albo przez robota) - tablica $_POST jest pusta, PHP wypisuje trzy ostrzeżenia „Undefined array key”, a do tabeli trafia rekord z pustym imieniem, nazwiskiem i adresem. Teraz skrypt sprawdza $_SERVER['REQUEST_METHOD'] i każde wejście inne niż POST przekierowuje z powrotem do formularza (header('Location: …') z exit),
    • puste pola - formularz można wysłać bez wpisania czegokolwiek. trim() zdejmuje spacje z brzegów (pole z samą spacją też jest puste), ?? '' chroni przed brakującym kluczem, a gdy któreś pole jest puste, exit kończy skrypt komunikatem, zanim cokolwiek trafi do bazy.

    htmlspecialchars nie jest tu potrzebny: skrypt nie wypisuje niczego, co wpisał użytkownik. Gdyby wypisywał (np. „Zapisano kartę dla Marka Lisa”), dane trzeba przepuścić przez htmlspecialchars przed echo - pokazuje to wersja nowoczesna.

    Typowe błędy

    Bez exit po header(...) skrypt działa dalej i zapisuje rekord - przekierowanie to tylko nagłówek odpowiedzi.

    zapisz.php PHP zmienione: 13 linii
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'wedkowanie');
    // $imie = $_POST['imie'];
    // $nazwisko = $_POST['nazwisko'];
    // $adres = $_POST['adres'];
    if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
        header('Location: karta.html');
        exit;
    }
    $imie = trim($_POST['imie'] ?? '');
    $nazwisko = trim($_POST['nazwisko'] ?? '');
    $adres = trim($_POST['adres'] ?? '');
    if ($imie === '' || $nazwisko === '' || $adres === '') {
        exit('Wypełnij wszystkie pola formularza.');
    }
    // mysqli_query($connection, "INSERT INTO karty_wedkarskie VALUES (NULL, '$imie', '$nazwisko', '$adres', NULL, NULL);");
    $statement = mysqli_prepare($connection, 'INSERT INTO karty_wedkarskie VALUES (NULL, ?, ?, ?, NULL, NULL);');
    mysqli_stmt_bind_param($statement, 'sss', $imie, $nazwisko, $adres);
    mysqli_stmt_execute($statement);
    mysqli_close($connection);
    ?>
    Podgląd strony po tym kroku (karta.html)
  40. Krok 40: Hasła: konto anna i użytkownik root

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 4: tworzące użytkownika anna na localhost z hasłem anna123

    Dwie rzeczy, które na egzaminie są w porządku, a w prawdziwym serwisie nie:

    • skrypt łączy się jako root bez hasła - administrator całego serwera baz danych. W XAMPP do nauki tak jest domyślnie, a arkusz tego wymaga (R.5.1). Na serwerze strona łączy się kontem z prawami tylko do swojej bazy (np. GRANT SELECT, INSERT ON wedkowanie.karty_wedkarskie TO …), z długim losowym hasłem,
    • hasło anna123 z zapytania 4 jest do ćwiczeń - słowo i trzy kolejne cyfry odgaduje się w ułamku sekundy ze słownika popularnych haseł.

    Do pliku egzaminacyjnego nic z tego nie przenosisz - zapytanie 4 i połączenie zostają takie, jak każe arkusz. Plik skryptu bez zmian.

    zapisz.php PHP zmienione: 0 linii
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'wedkowanie');
    // $imie = $_POST['imie'];
    // $nazwisko = $_POST['nazwisko'];
    // $adres = $_POST['adres'];
    if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
        header('Location: karta.html');
        exit;
    }
    $imie = trim($_POST['imie'] ?? '');
    $nazwisko = trim($_POST['nazwisko'] ?? '');
    $adres = trim($_POST['adres'] ?? '');
    if ($imie === '' || $nazwisko === '' || $adres === '') {
        exit('Wypełnij wszystkie pola formularza.');
    }
    // mysqli_query($connection, "INSERT INTO karty_wedkarskie VALUES (NULL, '$imie', '$nazwisko', '$adres', NULL, NULL);");
    $statement = mysqli_prepare($connection, 'INSERT INTO karty_wedkarskie VALUES (NULL, ?, ?, ?, NULL, NULL);');
    mysqli_stmt_bind_param($statement, 'sss', $imie, $nazwisko, $adres);
    mysqli_stmt_execute($statement);
    mysqli_close($connection);
    ?>
    Podgląd strony po tym kroku (karta.html)
    Podgląd strony po kroku 40
  41. Etap 6: Oddanie pracy

    Krok 41 · po tym etapie masz 31 z 31 kryteriów (pkt)

    Krok 41: Plik przeglądarka.txt i nagranie płyty

    ok. 5 min
    Polecenie z arkusza

    UWAGA: po zakończeniu pracy utwórz w folderze z numerem PESEL lub w przypadku jego braku w folderze z innym numerem, którym został podpisany arkusz plik tekstowy o nazwie przeglądarka.txt. Zapisz w nim nazwę przeglądarki internetowej, w której weryfikowano poprawność działania witryny. Nagraj płytę z rezultatami pracy.

    W przeglądarka.txt wpisujesz nazwę przeglądarki, w której sprawdzasz stronę przez http://localhost/….

    W folderze z numerem zdającego muszą być: import.png, karta.html, kw1.jpg, kw2.jpg, kw3.jpg, kw4.jpg, kwerendy.txt, przeglądarka.txt, styl_1.css, wedka.jpg i zapisz.php (plik baza.sql z archiwum może zostać). Nagraj płytę, sprawdź jej odczyt w obecności przewodniczącego zespołu nadzorującego i opisz ją numerem zdającego. Pusta lub nieczytelna płyta to zero punktów za wszystkie pięć rezultatów.

    przeglądarka.txt Tekst nowy plik
    Google Chrome
    Podgląd strony po tym kroku (karta.html)

Podgląd

To jedno z możliwych rozwiązań. Egzaminator ocenia spełnienie kryteriów z klucza odpowiedzi, a nie zgodność z tym kodem - inna, poprawna droga też daje punkty.

Autor rozwiązania: . Licencja CC BY-NC 4.0 - kopiowanie i przeróbki do celów niekomercyjnych, z podaniem autora i źródła (link do tej strony) (zasady wykorzystania). Treść arkusza i klucza oceniania pochodzi z CKE.

Potwierdzenie

Informacja