Przejdź do głównej treści
INF.03-02-26.06-SGCzerwiec 2026 · 51 kroków · ok. 93 min · 41 kryteriów z klucza

Rozwiązanie krok po kroku: Witryna Łowcy wodospadów (Wersja podstawowa)

Rozwiązanie buduje hobbystyczną witrynę łowców wodospadów: baza wodospady (kontynenty, obiekty przyrodnicze, rodzaje, turyści i tabela pośrednicząca osiagniecia dla relacji m:n) i pięć zapytań - prosty SELECT, dwa warunki połączone AND, INSERT z kluczem nadawanym automatycznie - potem grafika przeskalowana z zachowaniem proporcji, strona index.php z blokiem bocznym, tabelą, formularzem i galerią oraz cztery skrypty PHP: odnośniki kontynentów przekazujące identyfikator metodą GET, tabela wodospadów wybranego kontynentu (domyślnie Europa), lista turystów z bazy i zapis osiągnięcia wysłanego formularzem.

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ą. Skrypty są najpierw pisane najprościej, funkcjami z tabeli 1 arkusza (mysqli_query, mysqli_fetch_row, isset), a na końcu zostają przerobione na wersję z prawdziwych projektów: liczba zamiast surowego tekstu z adresu, zapytanie przygotowane, obsługa błędu zapisu i htmlspecialchars.

To jest wersja podstawowa. W zakładce „Nowoczesny kod (grid, PDO)” jest drugi sposób rozwiązania tego samego arkusza: blok główny na siatce CSS, PHP na PDO z filtrami danych wejściowych, zapytaniami przygotowanymi i przekierowaniem po zapisie od pierwszej linii - obie wersje są zgodne z kluczem.

Baza i zdjęcia pochodzą z prawdziwego archiwum pliki2 (załącznik do arkusza, hasło w treści zadania). Zrzuty wyników zapytań są odtworzone z tej bazy - na egzaminie robisz je sam, z całego ekranu. Podgląd strony od kroków z PHP to wynik prawdziwego uruchomienia kodu z danego kroku w PHP 8.2 na bazie z arkusza; tabela pokazuje Europę, jak na ilustracji 2.

Jak liczą się punkty. Klucz ma 41 kryteriów (R.1.1 - R.5.9), każde za 1 punkt. Próg zdania części praktycznej to 75%, czyli 31 punktów - można stracić 10 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-8 · po tym etapie masz 7 z 41 kryteriów (pkt)

    Krok 1: Baza danych wodospady

    ok. 2 min
    Polecenie z arkusza

    Utwórz bazę danych o nazwie wodospady, z zestawem znaków utf8_unicode_ci

    Rozpakuj pliki2.7z z pulpitu (hasło WodosP@dy - z wielką literą P i małpą zamiast „a”) i załóż folder z numerem zdającego. W phpMyAdmin: Nowa, nazwa wodospady, porównywanie utf8_unicode_ci. Arkusz nazywa to „zestawem znaków”, ale utf8_unicode_ci to metoda porównywania (zestawem jest utf8) - na liście w phpMyAdmin wybierasz właśnie tę pozycję.

    Typowe błędy

    Nazwa bazy musi brzmieć dokładnie wodospady - skrypty łączą się z bazą po nazwie, więc literówka zabiera też punkty za skrypty (R.5.1).

  2. Krok 2: Import tabel z pliku baza2.sql

    ok. 2 min
    Polecenie z arkusza

    Do utworzonej bazy zaimportuj tabele z pliku baza2.sql

    Zaznacz bazę wodospady, potem Import → baza2.sql → Wykonaj. Powstaje pięć tabel z ilustracji 1: kontynenty, rodzaje, obiekty, turysci i pusta jeszcze osiagniecia, która łączy turystów z obiektami (relacja m:n - jeden turysta odwiedza wiele miejsc, jedno miejsce odwiedza wielu turystów).

  3. Krok 3: Zrzut ekranu import.jpg

    Kryteria:

    R.1.1 Wykonany import tabel do bazy danych wodospady - plik import w formacie JPEG

    ok. 2 min
    Polecenie z arkusza

    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ń. Na zrzucie powinny być widoczne elementy wskazujące na poprawnie wykonany import tabel

    Print Screen, wklejasz do edytora grafiki i zapisujesz jako import.jpg. Import idzie do JPEG, zrzuty zapytań do PNG - formaty są różne.

    Typowe błędy

    Wykadrowany zrzut albo zrzut bez paska zadań nie jest oceniany (uwaga w kluczu przy R.1).

  4. Krok 4: Zapytanie 1: wszystkie kontynenty

    Kryteria: ,

    R.1.2 W pliku kwerendy.txt zapisane co najmniej jedno zapytanie SQL, wynikające z treści zadania

    R.1.3 Wykonane zapytanie 1 wybierające identyfikatory i nazwy wszystkich kontynentów. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT idKontynent, nazwa FROM kontynenty; (lub * po SELECT ) oraz na zrzucie widoczne są dane dla identyfikatorów 1 ÷ 7

    ok. 1 min
    Polecenie z arkusza

    Zapytanie 1: wybierające identyfikatory i nazwy wszystkich kontynentów

    Dwie kolumny, bez warunku: siedem wierszy, identyfikatory 1 - 7. Z tego wyniku Skrypt 1 zrobi odnośniki w bloku bocznym. Zapytanie zapisujesz w kwerendy.txt, zrzut jako kw1.png (cały ekran z paskiem zadań).

    kwerendy.txt Tekst nowy plik
    -- Zapytanie 1
    SELECT idKontynent, nazwa FROM kontynenty;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 4
  5. Krok 5: Zapytanie 2: wodospady w Polsce

    Kryteria:

    R.1.4 Wykonane zapytanie 2 wybierające jedynie pola nazwa, wartoscCechy i plik z tabeli obiekty dla wodospadów z Polski. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT nazwa, wartoscCechy, plik FROM obiekty WHERE idRodzaj = 10 AND panstwo = "Polska";(wymagane sprawdzenie, że jest to wodospad) oraz na zrzucie widoczne są dokładnie 4 rekordy dla: Kamieńczyk, Mała Siklawa, Wielka Siklawa, Wilczki

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 2: wybierające jedynie pola nazwa, wartoscCechy i plik z tabeli obiekty dla wodospadów z Polski (w warunku można zastosować pole idRodzaj = 10)

    • SELECT nazwa, wartoscCechy, plik - trzy pola, nic więcej,
    • FROM obiekty - jedna tabela,
    • WHERE idRodzaj = 10 AND panstwo = 'Polska' - oba warunki naraz: rodzaj 10 to wodospad (tabela rodzaje), a państwo zawęża wynik do Polski.

    Wynik: cztery wiersze - Kamieńczyk, Mała Siklawa, Wielka Siklawa, Wilczki, każdy z nazwą pliku zdjęcia. Zrzut: kw2.png.

    Typowe błędy

    Sam warunek idRodzaj = 10 (bez państwa) zwraca 12 wodospadów z całego świata, a sam warunek na Polskę nie sprawdza, czy to wodospad - klucz wymaga obu i dokładnie 4 rekordów.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT idKontynent, nazwa FROM kontynenty;
    
    -- Zapytanie 2
    SELECT nazwa, wartoscCechy, plik FROM obiekty WHERE idRodzaj = 10 AND panstwo = 'Polska';
    Podgląd strony po tym kroku
    Podgląd strony po kroku 5
  6. Krok 6: Zapytanie 3: wodospady Europy

    Kryteria:

    R.1.5 Wykonane zapytanie 3 wybierające jedynie pola idObiekt, panstwo, nazwa i wartoscCechy z tabeli obiekty dla pól idRodzaj = 10 i idKontynent = 6. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT idObiekt, panstwo, nazwa, wartoscCechy FROM obiekty WHERE idRodzaj = 10 AND idKontynent = 6; oraz na zrzucie widocznych jest dokładnie 8 rekordów o id: 42, 43, 44, 45, 47, 48, 53, 54

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 3: wybierające jedynie pola idObiekt, panstwo, nazwa i wartoscCechy z tabeli obiekty dla pól idRodzaj = 10 i idKontynent = 6

    Te same dwa warunki z AND, tylko zamiast państwa kontynent 6 (Europa). Wynik: osiem wierszy o identyfikatorach 42, 43, 44, 45, 47, 48, 53, 54 - cztery wodospady polskie i cztery islandzkie. Zrzut: kw3.png. W Skrypcie 2 w miejscu 6 stanie identyfikator kontynentu z adresu strony.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT idKontynent, nazwa FROM kontynenty;
    
    -- Zapytanie 2
    SELECT nazwa, wartoscCechy, plik FROM obiekty WHERE idRodzaj = 10 AND panstwo = 'Polska';
    
    -- Zapytanie 3
    SELECT idObiekt, panstwo, nazwa, wartoscCechy FROM obiekty WHERE idRodzaj = 10 AND idKontynent = 6;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 6
  7. Krok 7: Zapytanie 4: osiągnięcie turysty

    Kryteria:

    R.1.6 Wykonane zapytanie 4 wstawiające do tabeli osiagniecia rekord o wartościach: idObiekt = 34, idTurysta = 2. Klucz podstawowy nadawany automatycznie. W pliku z kwerendami lub na zrzucie istnieje zapis np.: INSERT INTO osiagniecia(`idObiekt`, `idTurysta`) VALUES (34, 2); (klucz główny pominięty lub NULL) oraz na zrzucie widoczny jest komunikat o poprawnie dodanym rekordzie lub tabela z dodanym rekordem

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 4: wstawiające do tabeli osiagniecia rekord o wartościach: idObiekt = 34, idTurysta = 2. Klucz podstawowy nadawany automatycznie

    Wymień w nawiasie tylko dwie kolumny, które wypełniasz - idOsiagniecie pomiń i baza nada je sama (AUTO_INCREMENT). Tabela była pusta, więc nowy rekord dostaje identyfikator 1: turystka nr 2 (Monika) zdobyła obiekt 34 (Kilimanjaro). Zrzut z komunikatem albo z tabelą po wstawieniu: kw4.png.

    Typowe błędy

    Wpisanie klucza ręcznie (VALUES (1, 34, 2)) przeczy wymaganiu „klucz nadawany automatycznie” - klucz pomijasz albo podajesz NULL.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT idKontynent, nazwa FROM kontynenty;
    
    -- Zapytanie 2
    SELECT nazwa, wartoscCechy, plik FROM obiekty WHERE idRodzaj = 10 AND panstwo = 'Polska';
    
    -- Zapytanie 3
    SELECT idObiekt, panstwo, nazwa, wartoscCechy FROM obiekty WHERE idRodzaj = 10 AND idKontynent = 6;
    
    -- Zapytanie 4
    INSERT INTO osiagniecia (idObiekt, idTurysta) VALUES (34, 2);
    Podgląd strony po tym kroku
    Podgląd strony po kroku 7
  8. Krok 8: Zapytanie 5: turyści

    Kryteria:

    R.1.7 Wykonane zapytanie 5 wybierające identyfikatory i wszystkie pola nick turystów. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT idTurysta, nick FROM turysci; oraz na zrzucie widocznych jest dokładnie 13 rekordów

    ok. 1 min
    Polecenie z arkusza

    Zapytanie 5: wybierające pola idTurysta i nick z tabeli turysci

    Dwie kolumny, 13 wierszy - od Ewy (1) do Adama (13). Skrypt 3 zrobi z nich opcje listy rozwijanej: identyfikator pójdzie do atrybutu value, nick będzie widoczną treścią. Zrzut: kw5.png.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT idKontynent, nazwa FROM kontynenty;
    
    -- Zapytanie 2
    SELECT nazwa, wartoscCechy, plik FROM obiekty WHERE idRodzaj = 10 AND panstwo = 'Polska';
    
    -- Zapytanie 3
    SELECT idObiekt, panstwo, nazwa, wartoscCechy FROM obiekty WHERE idRodzaj = 10 AND idKontynent = 6;
    
    -- Zapytanie 4
    INSERT INTO osiagniecia (idObiekt, idTurysta) VALUES (34, 2);
    
    -- Zapytanie 5
    SELECT idTurysta, nick FROM turysci;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 8
  9. Etap 2: Grafika i strona HTML

    Kroki 9-25 · po tym etapie masz 19 z 41 kryteriów (pkt)

    Krok 9: Grafika siklawica.jpg: szerokość 133 px

    Kryteria:

    R.2.1 Grafika siklawica.jpg ma szerokość 133 px i wysokość 200 px (± 5 px)

    ok. 3 min
    Polecenie z arkusza

    Grafikę należy przeskalować z zachowaniem proporcji do szerokości 133 px

    Oryginał ma 1000 × 1500 px. W GIMP-ie Obraz → Skaluj obraz, szerokość 133 px przy zamkniętym łańcuchu proporcji - wysokość wychodzi sama: 200 px (klucz: 133 × 200 ±5). Eksport pod tą samą nazwą. Po skalowaniu zdjęcie ma tę samą wysokość co pozostałe trzy (200 px), więc w galerii stanie z nimi w równym rzędzie.

    Typowe błędy

    Wpisanie samej szerokości przy otwartym łańcuchu zostawia wysokość 1500 px - zdjęcie jest zniekształcone i niezgodne z kluczem.

    Podgląd strony po tym kroku
    Podgląd strony po kroku 9
  10. Krok 10: Plik index.php w HTML5

    ok. 2 min
    Polecenie z arkusza

    Składa się ze strony o nazwie index.php. Zapisana w języku HTML5

    Deklaracja <!DOCTYPE html> i szkielet strony. Rozszerzenie .php, bo dojdą skrypty; na egzaminie plik leży w htdocs XAMPP-a i otwierasz go przez http://localhost/....

    index.php PHP nowy plik
    <!DOCTYPE html>
    <html>
    <head>
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  11. Krok 11: Język strony

    Kryteria:

    R.2.2 W pliku index.php znajduje się deklaracja HTML5 <!DOCTYPE HTML> i deklaracja języka zawartości: polski np. <html lang="pl">

    ok. 1 min
    Polecenie z arkusza

    Zadeklarowany polski język zawartości witryny

    Atrybut lang="pl" w znaczniku <html> - razem z deklaracją HTML5 to jedno kryterium klucza.

    index.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  12. Krok 12: Kodowanie polskich znaków

    ok. 1 min
    Polecenie z arkusza

    Jawnie zastosowany właściwy standard kodowania polskich znaków

    <meta charset="UTF-8"> jako pierwszy element <head> - bez niego „Łowcy” mogą wyświetlić się krzakami.

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

    Kryteria:

    R.2.3 W sekcji head znajduje się jawnie podany standard kodowania polskich znaków i tytuł strony "Wodospady"

    ok. 1 min
    Polecenie z arkusza

    Tytuł strony „Wodospady”

    <title> w <head> - widać go na karcie przeglądarki.

    index.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wodospady</title>
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  14. Krok 14: Podpięcie arkusza stylów

    Kryteria:

    R.3.2 Strona zawiera działające połączenie z zewnętrznym arkuszem stylów o nazwie styl.css formatowanie CSS pochodzi jedynie z tego arkusza

    ok. 1 min
    Polecenie z arkusza

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

    Nazwa pliku: styl.css (nie style.css). Całe formatowanie ma pochodzić z tego pliku - żadnych atrybutów style w HTML-u.

    index.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wodospady</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  15. Krok 15: Bloki: nagłówek, główny, artykuł, stopka

    Kryteria:

    R.2.4 W sekcji body zdefiniowany jest podział na bloki za pomocą semantycznych znaczników HTML5: header, main -> aside + section, article, footer (dopuszcza się stosowanie bloków pomocniczych)

    ok. 2 min
    Polecenie z arkusza

    Podział strony na bloki: nagłówkowy, główny, artykułu, stopki. Blok główny zawiera blok boczny i blok sekcji. Podział zrealizowany za pomocą semantycznych znaczników języka HTML5 tak, aby po uruchomieniu w przeglądarce układ bloków był zgodny z ilustracją 3

    Klucz wymaga wprost header, main z aside i section w środku, potem article i footer (R.2.4). Artykuł i stopka stoją poza <main> - na ilustracji 3 zajmują całą szerokość pod blokiem głównym. Bloki boczny i sekcji ustawisz obok siebie w CSS.

    index.php PHP zmienione: 12 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wodospady</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
        </header>
        <main>
            <aside>
            </aside>
            <section>
            </section>
        </main>
        <article>
        </article>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  16. Krok 16: Nagłówek strony

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku nagłówkowego: nagłówek drugiego stopnia o treści „Łowcy wodospadów”

    Drugiego stopnia, czyli <h2>, nie <h1> - arkusz mówi to wprost.

    index.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wodospady</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Łowcy wodospadów</h2>
        </header>
        <main>
            <aside>
            </aside>
            <section>
            </section>
        </main>
        <article>
        </article>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  17. Krok 17: Tabela: wiersz nagłówkowy

    Kryteria: ,

    R.2.6 W bloku sekcji znajduje się tabela o czterech kolumnach (znaczniki <table>, <tr>, <td>; w skrypcie lub HTML )

    R.2.7 Pierwszy wiersz tabeli zawiera cztery komórki nagłówkowe (znaczniki <tr>, <th> )

    ok. 2 min
    Polecenie z arkusza

    Tabela o czterech kolumnach. Pierwszy wiersz jest wierszem nagłówkowym z komórkami: „Identyfikator”, „Państwo”, „Nazwa wodospadu”. „Wysokość”. Tabela jest wypełniona skryptem 2

    Pierwszy wiersz <tr> z czterema komórkami nagłówkowymi <th> - przeglądarka pogrubia je i wyśrodkowuje. Kropka po „Nazwa wodospadu” w arkuszu to literówka, nagłówków jest cztery. Wiersze z danymi (<td>) dopisze Skrypt 2, dlatego zostawiasz po nagłówku miejsce przed </table>.

    index.php PHP zmienione: 8 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wodospady</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Łowcy wodospadów</h2>
        </header>
        <main>
            <aside>
            </aside>
            <section>
                <table>
                    <tr>
                        <th>Identyfikator</th>
                        <th>Państwo</th>
                        <th>Nazwa wodospadu</th>
                        <th>Wysokość</th>
                    </tr>
                </table>
            </section>
        </main>
        <article>
        </article>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  18. Krok 18: Nagłówek nad formularzem

    ok. 1 min
    Polecenie z arkusza

    Nagłówek czwartego stopnia o treści „Wpisz osiągnięcie do bazy”

    <h4> pod tabelą, w tym samym bloku sekcji.

    index.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wodospady</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Łowcy wodospadów</h2>
        </header>
        <main>
            <aside>
            </aside>
            <section>
                <table>
                    <tr>
                        <th>Identyfikator</th>
                        <th>Państwo</th>
                        <th>Nazwa wodospadu</th>
                        <th>Wysokość</th>
                    </tr>
                </table>
                <h4>Wpisz osiągnięcie do bazy</h4>
            </section>
        </main>
        <article>
        </article>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  19. Krok 19: Formularz wysyłany metodą POST

    Kryteria:

    R.3.4 Formularz wysyła dane metodą POST do tego samego pliku (poprawne również bez atrybutu action )

    ok. 2 min
    Polecenie z arkusza

    Formularz wysyłający dane metodą bezpieczną do tego samego pliku. Formularz zawiera pola rozmieszczone zgodnie z ilustracją 2.

    method="post" - dane jadą w treści żądania, nie w adresie. Atrybut action pomijasz: formularz bez niego wysyła dane pod bieżący adres, razem z ?id=..., więc po wpisaniu osiągnięcia tabela nadal pokazuje wybrany kontynent (z action="index.php" wracałaby do Europy). Klucz uznaje oba zapisy (R.3.4).

    index.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wodospady</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Łowcy wodospadów</h2>
        </header>
        <main>
            <aside>
            </aside>
            <section>
                <table>
                    <tr>
                        <th>Identyfikator</th>
                        <th>Państwo</th>
                        <th>Nazwa wodospadu</th>
                        <th>Wysokość</th>
                    </tr>
                </table>
                <h4>Wpisz osiągnięcie do bazy</h4>
                <form method="post">
                </form>
            </section>
        </main>
        <article>
        </article>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  20. Krok 20: Etykieta i pole identyfikatora

    ok. 2 min
    Polecenie z arkusza

    Etykieta o treści: „identyfikator wodospadu”. Pole edycyjne typu numerycznego połączone z etykietą

    <label for="waterfall"> łączy się z polem po jego id - kliknięcie napisu ustawia kursor w polu. type="number" pozwala wpisać tylko liczbę, a name="waterfall" to klucz, pod którym wartość trafi do $_POST.

    index.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wodospady</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Łowcy wodospadów</h2>
        </header>
        <main>
            <aside>
            </aside>
            <section>
                <table>
                    <tr>
                        <th>Identyfikator</th>
                        <th>Państwo</th>
                        <th>Nazwa wodospadu</th>
                        <th>Wysokość</th>
                    </tr>
                </table>
                <h4>Wpisz osiągnięcie do bazy</h4>
                <form method="post">
                    <label for="waterfall">identyfikator wodospadu</label>
                    <input type="number" id="waterfall" name="waterfall">
                </form>
            </section>
        </main>
        <article>
        </article>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  21. Krok 21: Etykieta i lista turystów

    ok. 1 min
    Polecenie z arkusza

    Etykieta o treści: „turysta”. Lista rozwijana połączona z etykietą, której elementy są wypełnione skryptem 3

    Tak samo: for etykiety równe id listy. Opcji na razie nie ma - wypisze je Skrypt 3 z tabeli turysci.

    index.php PHP zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wodospady</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Łowcy wodospadów</h2>
        </header>
        <main>
            <aside>
            </aside>
            <section>
                <table>
                    <tr>
                        <th>Identyfikator</th>
                        <th>Państwo</th>
                        <th>Nazwa wodospadu</th>
                        <th>Wysokość</th>
                    </tr>
                </table>
                <h4>Wpisz osiągnięcie do bazy</h4>
                <form method="post">
                    <label for="waterfall">identyfikator wodospadu</label>
                    <input type="number" id="waterfall" name="waterfall">
                    <label for="tourist">turysta</label>
                    <select id="tourist" name="tourist">
                    </select>
                </form>
            </section>
        </main>
        <article>
        </article>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  22. Krok 22: Przycisk „Wpisz”

    Kryteria: ,

    R.2.8 W bloku sekcji znajduje się formularz z 2 etykietami, polem edycyjnym, listą rozwijaną (może być pusta) , i przyciskiem "Wpisz". Co najmniej jedno pole formularza ma powiązaną etykietę (label z for i id lub zagnieżdżenie kontrolki w label)

    R.3.5 Przycisk realizuje funkcję wysłania danych z formularza (input lub button z typem submit lub button bez typu )

    ok. 1 min
    Polecenie z arkusza

    Przycisk o treści „Wpisz” wysyłający dane do skryptu 4

    <button type="submit"> wysyła formularz; Skrypt 4 odczyta dane po przeładowaniu tej samej strony. Formularz ma już komplet: dwie etykiety, pole, listę i przycisk w jednym wierszu, jak na ilustracji 2.

    index.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wodospady</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Łowcy wodospadów</h2>
        </header>
        <main>
            <aside>
            </aside>
            <section>
                <table>
                    <tr>
                        <th>Identyfikator</th>
                        <th>Państwo</th>
                        <th>Nazwa wodospadu</th>
                        <th>Wysokość</th>
                    </tr>
                </table>
                <h4>Wpisz osiągnięcie do bazy</h4>
                <form method="post">
                    <label for="waterfall">identyfikator wodospadu</label>
                    <input type="number" id="waterfall" name="waterfall">
                    <label for="tourist">turysta</label>
                    <select id="tourist" name="tourist">
                    </select>
                    <button type="submit">Wpisz</button>
                </form>
            </section>
        </main>
        <article>
        </article>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  23. Krok 23: Nagłówek artykułu

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku artykułu: Nagłówek trzeciego stopnia o treści „Wodospady w Polsce”

    <h3> w <article>.

    index.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wodospady</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Łowcy wodospadów</h2>
        </header>
        <main>
            <aside>
            </aside>
            <section>
                <table>
                    <tr>
                        <th>Identyfikator</th>
                        <th>Państwo</th>
                        <th>Nazwa wodospadu</th>
                        <th>Wysokość</th>
                    </tr>
                </table>
                <h4>Wpisz osiągnięcie do bazy</h4>
                <form method="post">
                    <label for="waterfall">identyfikator wodospadu</label>
                    <input type="number" id="waterfall" name="waterfall">
                    <label for="tourist">turysta</label>
                    <select id="tourist" name="tourist">
                    </select>
                    <button type="submit">Wpisz</button>
                </form>
            </section>
        </main>
        <article>
            <h3>Wodospady w Polsce</h3>
        </article>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  24. Krok 24: Galeria czterech wodospadów

    Kryteria:

    R.2.9 W bloku artykułu znajdują się grafiki kamienczyk.jpg , siklawica.jpg , siklawa.jpg , wilczki.jpg z tekstem alternatywnym "wodospad"

    ok. 2 min
    Polecenie z arkusza

    Obrazy o nazwach kamienczyk.jpg, siklawica.jpg, siklawa.jpg, wilczki.jpg z tekstem alternatywnym „wodospad”

    Cztery <img> w kolejności z arkusza, każdy z alt="wodospad". Na razie stoją wyśrodkowane jeden za drugim - ułożysz je w CSS.

    index.php PHP zmienione: 4 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wodospady</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Łowcy wodospadów</h2>
        </header>
        <main>
            <aside>
            </aside>
            <section>
                <table>
                    <tr>
                        <th>Identyfikator</th>
                        <th>Państwo</th>
                        <th>Nazwa wodospadu</th>
                        <th>Wysokość</th>
                    </tr>
                </table>
                <h4>Wpisz osiągnięcie do bazy</h4>
                <form method="post">
                    <label for="waterfall">identyfikator wodospadu</label>
                    <input type="number" id="waterfall" name="waterfall">
                    <label for="tourist">turysta</label>
                    <select id="tourist" name="tourist">
                    </select>
                    <button type="submit">Wpisz</button>
                </form>
            </section>
        </main>
        <article>
            <h3>Wodospady w Polsce</h3>
            <img src="kamienczyk.jpg" alt="wodospad">
            <img src="siklawica.jpg" alt="wodospad">
            <img src="siklawa.jpg" alt="wodospad">
            <img src="wilczki.jpg" alt="wodospad">
        </article>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  25. Krok 25: Stopka

    Kryteria:

    R.2.5 W bloku nagłówkowym znajduje się <h2>: "Łowcy wodospadów", w bloku sekcji <h4>: "Wpisz osiągnięcie do bazy", w bloku artykułu <h3>: "Wodospady w Polsce" oraz <p> z numerem zdającego w stopce

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku stopki: paragraf o treści „Autor: ”, dalej wstawiony numer zdającego

    Akapit w <footer>. Na egzaminie po dwukropku wpisujesz swój numer zdającego (PESEL) - tutaj stoi imię i nazwisko autora rozwiązania. Z tym krokiem są już wszystkie nagłówki z klucza: <h2>, <h4>, <h3> i akapit w stopce.

    index.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wodospady</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Łowcy wodospadów</h2>
        </header>
        <main>
            <aside>
            </aside>
            <section>
                <table>
                    <tr>
                        <th>Identyfikator</th>
                        <th>Państwo</th>
                        <th>Nazwa wodospadu</th>
                        <th>Wysokość</th>
                    </tr>
                </table>
                <h4>Wpisz osiągnięcie do bazy</h4>
                <form method="post">
                    <label for="waterfall">identyfikator wodospadu</label>
                    <input type="number" id="waterfall" name="waterfall">
                    <label for="tourist">turysta</label>
                    <select id="tourist" name="tourist">
                    </select>
                    <button type="submit">Wpisz</button>
                </form>
            </section>
        </main>
        <article>
            <h3>Wodospady w Polsce</h3>
            <img src="kamienczyk.jpg" alt="wodospad">
            <img src="siklawica.jpg" alt="wodospad">
            <img src="siklawa.jpg" alt="wodospad">
            <img src="wilczki.jpg" alt="wodospad">
        </article>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  26. Etap 3: Styl CSS

    Kroki 26-35 · po tym etapie masz 30 z 41 kryteriów (pkt)

    Krok 26: Plik styl.css: krój i wyrównanie

    Kryteria:

    R.4.1 domyślne formatowanie selektorów (*): krój czcionki Garamond - jako pierwszy, serif - jako ostatni, wyrównanie tekstu do środka

    ok. 1 min
    Polecenie z arkusza

    Domyślnie, dla wszystkich selektorów: krój czcionki Garamond, w przypadku braku serif, wyrównanie tekstu do środka

    Selektor *. Kolejność krojów ma znaczenie: najpierw Garamond, na końcu rodzina zapasowa serif - klucz sprawdza właśnie tę kolejność.

    styl.css CSS nowy plik
    * {
        font-family: Garamond, serif;
        text-align: center;
    }
    Podgląd strony po tym kroku (index.php)
  27. Krok 27: Nagłówek i stopka

    ok. 1 min
    Polecenie z arkusza

    Dla bloku nagłówkowego i stopki: kolor tła SkyBlue, marginesy wewnętrzne 8 px, zewnętrzne 10 px, zaokrąglenie rogów 20 px

    Jedna reguła dla dwóch selektorów po przecinku. Marginesy wewnętrzne to padding, zewnętrzne margin.

    styl.css CSS zmienione: 6 linii
    * {
        font-family: Garamond, serif;
        text-align: center;
    }
    header, footer {
        background-color: SkyBlue;
        padding: 8px;
        margin: 10px;
        border-radius: 20px;
    }
    Podgląd strony po tym kroku (index.php)
  28. Krok 28: Blok boczny

    ok. 1 min
    Polecenie z arkusza

    Dla bloku bocznego: szerokość 30%

    Szerokość w procentach liczy się od rodzica, czyli od <main>.

    styl.css CSS zmienione: 3 linie
    * {
        font-family: Garamond, serif;
        text-align: center;
    }
    header, footer {
        background-color: SkyBlue;
        padding: 8px;
        margin: 10px;
        border-radius: 20px;
    }
    aside {
        width: 30%;
    }
    Podgląd strony po tym kroku (index.php)
  29. Krok 29: Blok sekcji: wysokość i paski przewijania

    Kryteria:

    R.4.5 paski przewijania (overflow) : blok sekcji - auto

    ok. 2 min
    Polecenie z arkusza

    Dla bloku sekcji: szerokość 70%, wysokość 300 px, paski przewijania jedynie w przypadku przepełnienia bloku

    overflow: auto - pasek pojawia się tylko wtedy, gdy treść nie mieści się w 300 px (scroll pokazywałby go zawsze). Dla Europy tabela z formularzem się mieści, więc paska nie ma.

    styl.css CSS zmienione: 5 linii
    * {
        font-family: Garamond, serif;
        text-align: center;
    }
    header, footer {
        background-color: SkyBlue;
        padding: 8px;
        margin: 10px;
        border-radius: 20px;
    }
    aside {
        width: 30%;
    }
    section {
        width: 70%;
        height: 300px;
        overflow: auto;
    }
    Podgląd strony po tym kroku (index.php)
  30. Krok 30: Układ bloków zgodny z ilustracją 3

    Kryteria:

    R.3.1 Układ bloków po uruchomieniu strony w przeglądarce jest zgodny z ilustracją 3 w arkuszu egzaminacyjnym (prawidłowo zastosowane właściwości CSS decydujące o układzie bloków na stronie, np. float i clear albo display flex albo grid albo position; żaden blok nie zachodzi na inne bloki - sprawdzić w inspektorze)

    ok. 2 min
    Polecenie z arkusza

    Podział zrealizowany za pomocą semantycznych znaczników języka HTML5 tak, aby po uruchomieniu w przeglądarce układ bloków był zgodny z ilustracją 3

    Arkusz nie mówi, jak postawić blok boczny obok sekcji - wybierasz display: flex na <main>. Dzieci kontenera flex stają w rzędzie, a szerokości 30% i 70% dają razem całą szerokość. Przy float trzeba by pamiętać o clear: both dla artykułu, inaczej wjechałby pod pływające bloki; flex nie wypuszcza dzieci poza kontener, więc artykuł i stopka same zostają pod spodem (R.3.1).

    Typowe błędy

    Bloki, które na siebie zachodzą (sprawdzane w inspektorze), zabierają punkt za układ, nawet gdy strona „na oko” wygląda dobrze.

    styl.css CSS zmienione: 3 linie
    * {
        font-family: Garamond, serif;
        text-align: center;
    }
    header, footer {
        background-color: SkyBlue;
        padding: 8px;
        margin: 10px;
        border-radius: 20px;
    }
    aside {
        width: 30%;
    }
    section {
        width: 70%;
        height: 300px;
        overflow: auto;
    }
    main {
        display: flex;
    }
    Podgląd strony po tym kroku (index.php)
  31. Krok 31: Blok artykułu

    Kryteria:

    R.4.7 zaokrąglenie rogów (border-radius) : blok nagłówkowy, stopki, artykułu - 20px

    ok. 1 min
    Polecenie z arkusza

    Dla bloku artykułu: kolor tła AliceBlue, wysokość 280 px, marginesy wewnętrzne 8 px, zewnętrzne 10 px, zaokrąglenie rogów 20 px

    Te same marginesy i zaokrąglenie co nagłówek i stopka - trzy bloki wyglądają jak jedna rodzina. To zamyka kryterium zaokrągleń 20 px.

    styl.css CSS zmienione: 7 linii
    * {
        font-family: Garamond, serif;
        text-align: center;
    }
    header, footer {
        background-color: SkyBlue;
        padding: 8px;
        margin: 10px;
        border-radius: 20px;
    }
    aside {
        width: 30%;
    }
    section {
        width: 70%;
        height: 300px;
        overflow: auto;
    }
    main {
        display: flex;
    }
    article {
        background-color: AliceBlue;
        height: 280px;
        padding: 8px;
        margin: 10px;
        border-radius: 20px;
    }
    Podgląd strony po tym kroku (index.php)
  32. Krok 32: Obrazy obok siebie od lewej

    Kryteria:

    R.4.3 dla selektora img marginesy zewnętrzne (margin) - 4px

    ok. 2 min
    Polecenie z arkusza

    Dla selektora obrazu: marginesy zewnętrzne 4 px, umieszczone obok siebie od lewej strony

    Obrazy domyślnie są elementami liniowymi i stoją obok siebie, ale text-align: center z selektora * przesuwa je na środek. float: left dosuwa je do lewej krawędzi artykułu, jak na ilustracji 2. Selektor znacznika img - zgodnie z uwagą arkusza.

    styl.css CSS zmienione: 4 linie
    * {
        font-family: Garamond, serif;
        text-align: center;
    }
    header, footer {
        background-color: SkyBlue;
        padding: 8px;
        margin: 10px;
        border-radius: 20px;
    }
    aside {
        width: 30%;
    }
    section {
        width: 70%;
        height: 300px;
        overflow: auto;
    }
    main {
        display: flex;
    }
    article {
        background-color: AliceBlue;
        height: 280px;
        padding: 8px;
        margin: 10px;
        border-radius: 20px;
    }
    img {
        margin: 4px;
        float: left;
    }
    Podgląd strony po tym kroku (index.php)
  33. Krok 33: Tabela

    Kryteria:

    R.4.8 obramowanie: tabela - 1px dotted black

    ok. 1 min
    Polecenie z arkusza

    Dla selektora tabeli: szerokość 90%, obramowanie kropkowane o szerokości 1 px i kolorze czarnym

    Skrót border: 1px dotted black - grubość, styl (kropki) i kolor w jednej właściwości. Obramowanie dostaje sama tabela, nie komórki.

    styl.css CSS zmienione: 4 linie
    * {
        font-family: Garamond, serif;
        text-align: center;
    }
    header, footer {
        background-color: SkyBlue;
        padding: 8px;
        margin: 10px;
        border-radius: 20px;
    }
    aside {
        width: 30%;
    }
    section {
        width: 70%;
        height: 300px;
        overflow: auto;
    }
    main {
        display: flex;
    }
    article {
        background-color: AliceBlue;
        height: 280px;
        padding: 8px;
        margin: 10px;
        border-radius: 20px;
    }
    img {
        margin: 4px;
        float: left;
    }
    table {
        width: 90%;
        border: 1px dotted black;
    }
    Podgląd strony po tym kroku (index.php)
  34. Krok 34: Odnośniki jako niebieskie paski

    Kryteria: , , ,

    R.4.2 kolor tła: blok nagłówkowy, stopka - SkyBlue, blok artykułu - AliceBlue, selektor a - DodgerBlue, kolor czcionki: odnośnik - biały

    R.4.4 wysokość: blok sekcji - 300px, blok artykułu - 280px szerokość: blok boczny - 30%, blok sekcji - 70% (width lub grid-template-columns lub flex ), selektor table - 90%, odnośnik - 65%

    R.4.6 marginesy wewnętrzne (padding ): blok nagłówkowy, stopki, artykułu - 8px marginesy zewnętrzne (margin ): blok nagłówkowy, stopki, artykułu, odnośnik - 10px

    R.4.9 styl odnośnika: blokowy sposób wyświetlania (display: block) , rozmiar czcionki - 130%, bez podkreślenia (text-decoration: none)

    ok. 2 min
    Polecenie z arkusza

    Dla selektora odnośnika: blokowy sposób wyświetlania, kolor tła DodgerBlue, biały kolor czcionki, szerokość 65%, rozmiar czcionki 130%, marginesy zewnętrzne 10 px, bez podkreślenia

    display: block robi z odnośnika prostokąt na całą linię (tabela 2 w arkuszu) - dopiero wtedy działa width: 65% i każdy kontynent stoi w osobnym wierszu. text-decoration: none usuwa podkreślenie. Odnośników jeszcze nie ma, styl zobaczysz po Skrypcie 1. Ta reguła zamyka kryteria kolorów tła, szerokości i marginesów.

    styl.css CSS zmienione: 9 linii
    * {
        font-family: Garamond, serif;
        text-align: center;
    }
    header, footer {
        background-color: SkyBlue;
        padding: 8px;
        margin: 10px;
        border-radius: 20px;
    }
    aside {
        width: 30%;
    }
    section {
        width: 70%;
        height: 300px;
        overflow: auto;
    }
    main {
        display: flex;
    }
    article {
        background-color: AliceBlue;
        height: 280px;
        padding: 8px;
        margin: 10px;
        border-radius: 20px;
    }
    img {
        margin: 4px;
        float: left;
    }
    table {
        width: 90%;
        border: 1px dotted black;
    }
    a {
        display: block;
        background-color: DodgerBlue;
        color: white;
        width: 65%;
        font-size: 130%;
        margin: 10px;
        text-decoration: none;
    }
    Podgląd strony po tym kroku (index.php)
  35. Krok 35: Odnośnik pod kursorem

    Kryteria:

    R.4.10 gdy kursor znajdzie się na odnośniku, jego kolor tła zmienia się na RoyalBlue

    ok. 1 min
    Polecenie z arkusza

    Gdy kursor znajdzie się na odnośniku, jego kolor tła zmienia się na RoyalBlue

    Pseudoklasa :hover - na ilustracji 2 kursor stoi na „Europa” i ten pasek jest ciemniejszy.

    styl.css CSS zmienione: 3 linie
    * {
        font-family: Garamond, serif;
        text-align: center;
    }
    header, footer {
        background-color: SkyBlue;
        padding: 8px;
        margin: 10px;
        border-radius: 20px;
    }
    aside {
        width: 30%;
    }
    section {
        width: 70%;
        height: 300px;
        overflow: auto;
    }
    main {
        display: flex;
    }
    article {
        background-color: AliceBlue;
        height: 280px;
        padding: 8px;
        margin: 10px;
        border-radius: 20px;
    }
    img {
        margin: 4px;
        float: left;
    }
    table {
        width: 90%;
        border: 1px dotted black;
    }
    a {
        display: block;
        background-color: DodgerBlue;
        color: white;
        width: 65%;
        font-size: 130%;
        margin: 10px;
        text-decoration: none;
    }
    a:hover {
        background-color: RoyalBlue;
    }
    Podgląd strony po tym kroku (index.php)
  36. Etap 4: Skrypty PHP

    Kroki 36-46 · po tym etapie masz 41 z 41 kryteriów (pkt)

    Krok 36: Połączenie z bazą i zamknięcie na końcu

    Kryteria: ,

    R.5.1 Skrypt realizuje połączenie z serwerem bazy danych i wybór bazy wodospady oraz ostatnią operacją na bazie jest jej zamknięcie

    R.5.2 Zastosowana przynajmniej jedna zmienna oraz nazewnictwo jest w języku polskim lub angielskim i odzwierciedla cel zastosowania

    ok. 2 min
    Polecenie z arkusza

    Łączą się z serwerem bazodanowym na localhost, użytkownik root bez hasła, baza danych o nazwie wodospady. Na końcu należy zamknąć połączenie z bazą

    Pierwszy skrypt na stronie stoi w bloku bocznym, więc tam otwierasz połączenie: mysqli_connect z czterema argumentami łączy się z serwerem i od razu wybiera bazę. Uchwyt w zmiennej $connection posłuży wszystkim czterem skryptom. Ostatni blok PHP, pod formularzem, na razie tylko zamyka połączenie - Skrypt 4 dopiszesz nad tą linią, żeby zamknięcie zostało ostatnią operacją na bazie (R.5.1, R.5.2). Od tego kroku podgląd to wynik prawdziwego uruchomienia strony.

    index.php PHP zmienione: 6 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wodospady</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Łowcy wodospadów</h2>
        </header>
        <main>
            <aside>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "wodospady");
                ?>
            </aside>
            <section>
                <table>
                    <tr>
                        <th>Identyfikator</th>
                        <th>Państwo</th>
                        <th>Nazwa wodospadu</th>
                        <th>Wysokość</th>
                    </tr>
                </table>
                <h4>Wpisz osiągnięcie do bazy</h4>
                <form method="post">
                    <label for="waterfall">identyfikator wodospadu</label>
                    <input type="number" id="waterfall" name="waterfall">
                    <label for="tourist">turysta</label>
                    <select id="tourist" name="tourist">
                    </select>
                    <button type="submit">Wpisz</button>
                </form>
                <?php
                    mysqli_close($connection);
                ?>
            </section>
        </main>
        <article>
            <h3>Wodospady w Polsce</h3>
            <img src="kamienczyk.jpg" alt="wodospad">
            <img src="siklawica.jpg" alt="wodospad">
            <img src="siklawa.jpg" alt="wodospad">
            <img src="wilczki.jpg" alt="wodospad">
        </article>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  37. Krok 37: Skrypt 1: zapytanie 1

    Kryteria:

    R.5.3 Skrypt 1 zawiera instrukcję wysyłającą do bazy danych zapytanie 1 lub Skrypt 3 zawiera instrukcję wysyłającą do bazy danych zapytanie 5

    ok. 1 min
    Polecenie z arkusza

    Wysyła do bazy danych zapytanie 1

    Treść zapytania w zmiennej, mysqli_query wysyła ją do bazy, a w $result zostaje wynik do odczytania wiersz po wierszu.

    index.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wodospady</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Łowcy wodospadów</h2>
        </header>
        <main>
            <aside>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "wodospady");
                    $query = "SELECT idKontynent, nazwa FROM kontynenty;";
                    $result = mysqli_query($connection, $query);
                ?>
            </aside>
            <section>
                <table>
                    <tr>
                        <th>Identyfikator</th>
                        <th>Państwo</th>
                        <th>Nazwa wodospadu</th>
                        <th>Wysokość</th>
                    </tr>
                </table>
                <h4>Wpisz osiągnięcie do bazy</h4>
                <form method="post">
                    <label for="waterfall">identyfikator wodospadu</label>
                    <input type="number" id="waterfall" name="waterfall">
                    <label for="tourist">turysta</label>
                    <select id="tourist" name="tourist">
                    </select>
                    <button type="submit">Wpisz</button>
                </form>
                <?php
                    mysqli_close($connection);
                ?>
            </section>
        </main>
        <article>
            <h3>Wodospady w Polsce</h3>
            <img src="kamienczyk.jpg" alt="wodospad">
            <img src="siklawica.jpg" alt="wodospad">
            <img src="siklawa.jpg" alt="wodospad">
            <img src="wilczki.jpg" alt="wodospad">
        </article>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>

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

  38. Krok 38: Skrypt 1: odnośniki kontynentów z parametrem id

    Kryteria: ,

    R.3.3 Przynajmniej jeden odnośnik z nazwą kontynentu prowadzi do strony index.php (w skrypcie lub HTML )

    R.5.4 Skrypt 1 dla wszystkich zwróconych rekordów tworzy odnośnik do pliku index.php , w którym identyfikator jest przesyłany metodą GET, a nazwa jest treścią odnośnika. Po kliknięciu w odnośnik zmienia się zawartość tabeli na odpowiadającą wybranemu kontynentowi

    ok. 3 min
    Polecenie z arkusza

    Dla każdego zwróconego zapytaniem rekordu wyświetla odnośnik, którego treścią jest nazwa kontynentu. Odnośnik prowadzi do tej samej strony i przesyła identyfikator kontynentu jako parametr metody GET. Na ilustracji 4 jest przedstawiony adres URL po wybraniu odnośnika Europa

    mysqli_fetch_row oddaje kolejny wiersz jako tablicę ($row[0] - identyfikator, $row[1] - nazwa), a po ostatnim zwraca null i pętla while się kończy. Parametr GET doklejasz do adresu po znaku zapytania: index.php?id=6 - dokładnie jak na ilustracji 4 (tabela 4 arkusza). Cudzysłowy atrybutu wewnątrz napisu PHP poprzedzasz ukośnikiem \". W podglądzie siedem niebieskich pasków - styl a czekał już w CSS.

    index.php PHP zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wodospady</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Łowcy wodospadów</h2>
        </header>
        <main>
            <aside>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "wodospady");
                    $query = "SELECT idKontynent, nazwa FROM kontynenty;";
                    $result = mysqli_query($connection, $query);
                    while ($row = mysqli_fetch_row($result)) {
                        echo "<a href=\"index.php?id=$row[0]\">$row[1]</a>";
                    }
                ?>
            </aside>
            <section>
                <table>
                    <tr>
                        <th>Identyfikator</th>
                        <th>Państwo</th>
                        <th>Nazwa wodospadu</th>
                        <th>Wysokość</th>
                    </tr>
                </table>
                <h4>Wpisz osiągnięcie do bazy</h4>
                <form method="post">
                    <label for="waterfall">identyfikator wodospadu</label>
                    <input type="number" id="waterfall" name="waterfall">
                    <label for="tourist">turysta</label>
                    <select id="tourist" name="tourist">
                    </select>
                    <button type="submit">Wpisz</button>
                </form>
                <?php
                    mysqli_close($connection);
                ?>
            </section>
        </main>
        <article>
            <h3>Wodospady w Polsce</h3>
            <img src="kamienczyk.jpg" alt="wodospad">
            <img src="siklawica.jpg" alt="wodospad">
            <img src="siklawa.jpg" alt="wodospad">
            <img src="wilczki.jpg" alt="wodospad">
        </article>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  39. Krok 39: Skrypt 2: identyfikator kontynentu z adresu

    ok. 2 min
    Polecenie z arkusza

    Pobiera wartość przesłaną metodą GET, a w przypadku braku – wartością 6. Wartość ta jest identyfikatorem kontynentu

    Skrypt 2 stoi w tabeli, pod wierszem nagłówkowym. Parametr z adresu czeka w tablicy $_GET pod nazwą id. Przy pierwszym wejściu na stronę adresu bez ?id= tego klucza nie ma - isset to sprawdza i wtedy przyjmujesz 6 (Europa). Bez tego warunku pierwsze wejście kończyłoby się ostrzeżeniem „Undefined array key”.

    index.php PHP zmienione: 7 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wodospady</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Łowcy wodospadów</h2>
        </header>
        <main>
            <aside>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "wodospady");
                    $query = "SELECT idKontynent, nazwa FROM kontynenty;";
                    $result = mysqli_query($connection, $query);
                    while ($row = mysqli_fetch_row($result)) {
                        echo "<a href=\"index.php?id=$row[0]\">$row[1]</a>";
                    }
                ?>
            </aside>
            <section>
                <table>
                    <tr>
                        <th>Identyfikator</th>
                        <th>Państwo</th>
                        <th>Nazwa wodospadu</th>
                        <th>Wysokość</th>
                    </tr>
                    <?php
                        if (isset($_GET["id"])) {
                            $continent = $_GET["id"];
                        } else {
                            $continent = 6;
                        }
                    ?>
                </table>
                <h4>Wpisz osiągnięcie do bazy</h4>
                <form method="post">
                    <label for="waterfall">identyfikator wodospadu</label>
                    <input type="number" id="waterfall" name="waterfall">
                    <label for="tourist">turysta</label>
                    <select id="tourist" name="tourist">
                    </select>
                    <button type="submit">Wpisz</button>
                </form>
                <?php
                    mysqli_close($connection);
                ?>
            </section>
        </main>
        <article>
            <h3>Wodospady w Polsce</h3>
            <img src="kamienczyk.jpg" alt="wodospad">
            <img src="siklawica.jpg" alt="wodospad">
            <img src="siklawa.jpg" alt="wodospad">
            <img src="wilczki.jpg" alt="wodospad">
        </article>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  40. Krok 40: Skrypt 2: zapytanie 3 dla wybranego kontynentu

    Kryteria:

    R.5.5 Skrypt 2 zawiera instrukcję wysyłającą do bazy zapytanie 3, zmodyfikowane tak, że identyfikator kontynentu jest pobrany metodą GET, gdy $_GET istnieje

    ok. 2 min
    Polecenie z arkusza

    Wysyła do bazy danych zapytanie 3, zmodyfikowane tak, że sprawdzany jest identyfikator kontynentu, patrz poprzedni punkt

    Zapytanie 3, w którym zamiast 6 stoi zmienna $continent - PHP wstawi jej wartość do napisu w cudzysłowach. Identyfikator to liczba, więc w SQL bez apostrofów.

    index.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wodospady</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Łowcy wodospadów</h2>
        </header>
        <main>
            <aside>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "wodospady");
                    $query = "SELECT idKontynent, nazwa FROM kontynenty;";
                    $result = mysqli_query($connection, $query);
                    while ($row = mysqli_fetch_row($result)) {
                        echo "<a href=\"index.php?id=$row[0]\">$row[1]</a>";
                    }
                ?>
            </aside>
            <section>
                <table>
                    <tr>
                        <th>Identyfikator</th>
                        <th>Państwo</th>
                        <th>Nazwa wodospadu</th>
                        <th>Wysokość</th>
                    </tr>
                    <?php
                        if (isset($_GET["id"])) {
                            $continent = $_GET["id"];
                        } else {
                            $continent = 6;
                        }
                        $query = "SELECT idObiekt, panstwo, nazwa, wartoscCechy FROM obiekty WHERE idRodzaj = 10 AND idKontynent = $continent;";
                        $result = mysqli_query($connection, $query);
                    ?>
                </table>
                <h4>Wpisz osiągnięcie do bazy</h4>
                <form method="post">
                    <label for="waterfall">identyfikator wodospadu</label>
                    <input type="number" id="waterfall" name="waterfall">
                    <label for="tourist">turysta</label>
                    <select id="tourist" name="tourist">
                    </select>
                    <button type="submit">Wpisz</button>
                </form>
                <?php
                    mysqli_close($connection);
                ?>
            </section>
        </main>
        <article>
            <h3>Wodospady w Polsce</h3>
            <img src="kamienczyk.jpg" alt="wodospad">
            <img src="siklawica.jpg" alt="wodospad">
            <img src="siklawa.jpg" alt="wodospad">
            <img src="wilczki.jpg" alt="wodospad">
        </article>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>

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

  41. Krok 41: Skrypt 2: wiersz tabeli z identyfikatorem

    ok. 2 min
    Polecenie z arkusza

    Dla każdego zwróconego zapytaniem rekordu wstawia wiersz tabeli, wypełniając kolejne komórki zwróconymi polami (np. jeśli wybrano odnośnik Europa – tabela zawiera dane wodospadów z Europy)

    Na razie jedna komórka w wierszu, żeby zobaczyć, że pętla działa: osiem wierszy z identyfikatorami 42 - 54, tak jak w wyniku zapytania 3.

    index.php PHP zmienione: 5 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wodospady</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Łowcy wodospadów</h2>
        </header>
        <main>
            <aside>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "wodospady");
                    $query = "SELECT idKontynent, nazwa FROM kontynenty;";
                    $result = mysqli_query($connection, $query);
                    while ($row = mysqli_fetch_row($result)) {
                        echo "<a href=\"index.php?id=$row[0]\">$row[1]</a>";
                    }
                ?>
            </aside>
            <section>
                <table>
                    <tr>
                        <th>Identyfikator</th>
                        <th>Państwo</th>
                        <th>Nazwa wodospadu</th>
                        <th>Wysokość</th>
                    </tr>
                    <?php
                        if (isset($_GET["id"])) {
                            $continent = $_GET["id"];
                        } else {
                            $continent = 6;
                        }
                        $query = "SELECT idObiekt, panstwo, nazwa, wartoscCechy FROM obiekty WHERE idRodzaj = 10 AND idKontynent = $continent;";
                        $result = mysqli_query($connection, $query);
                        while ($row = mysqli_fetch_row($result)) {
                            echo "<tr>";
                            echo "<td>$row[0]</td>";
                            echo "</tr>";
                        }
                    ?>
                </table>
                <h4>Wpisz osiągnięcie do bazy</h4>
                <form method="post">
                    <label for="waterfall">identyfikator wodospadu</label>
                    <input type="number" id="waterfall" name="waterfall">
                    <label for="tourist">turysta</label>
                    <select id="tourist" name="tourist">
                    </select>
                    <button type="submit">Wpisz</button>
                </form>
                <?php
                    mysqli_close($connection);
                ?>
            </section>
        </main>
        <article>
            <h3>Wodospady w Polsce</h3>
            <img src="kamienczyk.jpg" alt="wodospad">
            <img src="siklawica.jpg" alt="wodospad">
            <img src="siklawa.jpg" alt="wodospad">
            <img src="wilczki.jpg" alt="wodospad">
        </article>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  42. Krok 42: Skrypt 2: państwo, nazwa i wysokość

    Kryteria:

    R.5.6 Skrypt 2: wszystkie rekordy zwrócone zapytaniem 3 wyświetla jako kolejne wiersze tabeli, pola są wstawione w odpowiednie komórki

    ok. 2 min
    Polecenie z arkusza

    Dla każdego zwróconego zapytaniem rekordu wstawia wiersz tabeli, wypełniając kolejne komórki zwróconymi polami

    Kolejne komórki w kolejności kolumn z SELECT: państwo, nazwa, wartość cechy. Podgląd wygląda jak tabela z ilustracji 2. Po kliknięciu „Ameryka Północna” (?id=3) w tabeli zostaje 1 wiersz (Yosemite), a „Antarktyda” (?id=5) zostawia sam nagłówek - w bazie nie ma tam żadnego wodospadu.

    index.php PHP zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wodospady</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Łowcy wodospadów</h2>
        </header>
        <main>
            <aside>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "wodospady");
                    $query = "SELECT idKontynent, nazwa FROM kontynenty;";
                    $result = mysqli_query($connection, $query);
                    while ($row = mysqli_fetch_row($result)) {
                        echo "<a href=\"index.php?id=$row[0]\">$row[1]</a>";
                    }
                ?>
            </aside>
            <section>
                <table>
                    <tr>
                        <th>Identyfikator</th>
                        <th>Państwo</th>
                        <th>Nazwa wodospadu</th>
                        <th>Wysokość</th>
                    </tr>
                    <?php
                        if (isset($_GET["id"])) {
                            $continent = $_GET["id"];
                        } else {
                            $continent = 6;
                        }
                        $query = "SELECT idObiekt, panstwo, nazwa, wartoscCechy FROM obiekty WHERE idRodzaj = 10 AND idKontynent = $continent;";
                        $result = mysqli_query($connection, $query);
                        while ($row = mysqli_fetch_row($result)) {
                            echo "<tr>";
                            echo "<td>$row[0]</td>";
                            echo "<td>$row[1]</td>";
                            echo "<td>$row[2]</td>";
                            echo "<td>$row[3]</td>";
                            echo "</tr>";
                        }
                    ?>
                </table>
                <h4>Wpisz osiągnięcie do bazy</h4>
                <form method="post">
                    <label for="waterfall">identyfikator wodospadu</label>
                    <input type="number" id="waterfall" name="waterfall">
                    <label for="tourist">turysta</label>
                    <select id="tourist" name="tourist">
                    </select>
                    <button type="submit">Wpisz</button>
                </form>
                <?php
                    mysqli_close($connection);
                ?>
            </section>
        </main>
        <article>
            <h3>Wodospady w Polsce</h3>
            <img src="kamienczyk.jpg" alt="wodospad">
            <img src="siklawica.jpg" alt="wodospad">
            <img src="siklawa.jpg" alt="wodospad">
            <img src="wilczki.jpg" alt="wodospad">
        </article>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  43. Krok 43: Skrypt 3: zapytanie 5

    ok. 1 min
    Polecenie z arkusza

    Wysyła do bazy danych zapytanie 5

    Skrypt 3 piszesz wewnątrz <select> - to, co wypisze, stanie się opcjami listy. Zmienne $query i $result używasz ponownie: wynik Skryptu 2 nie jest już potrzebny.

    index.php PHP zmienione: 4 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wodospady</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Łowcy wodospadów</h2>
        </header>
        <main>
            <aside>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "wodospady");
                    $query = "SELECT idKontynent, nazwa FROM kontynenty;";
                    $result = mysqli_query($connection, $query);
                    while ($row = mysqli_fetch_row($result)) {
                        echo "<a href=\"index.php?id=$row[0]\">$row[1]</a>";
                    }
                ?>
            </aside>
            <section>
                <table>
                    <tr>
                        <th>Identyfikator</th>
                        <th>Państwo</th>
                        <th>Nazwa wodospadu</th>
                        <th>Wysokość</th>
                    </tr>
                    <?php
                        if (isset($_GET["id"])) {
                            $continent = $_GET["id"];
                        } else {
                            $continent = 6;
                        }
                        $query = "SELECT idObiekt, panstwo, nazwa, wartoscCechy FROM obiekty WHERE idRodzaj = 10 AND idKontynent = $continent;";
                        $result = mysqli_query($connection, $query);
                        while ($row = mysqli_fetch_row($result)) {
                            echo "<tr>";
                            echo "<td>$row[0]</td>";
                            echo "<td>$row[1]</td>";
                            echo "<td>$row[2]</td>";
                            echo "<td>$row[3]</td>";
                            echo "</tr>";
                        }
                    ?>
                </table>
                <h4>Wpisz osiągnięcie do bazy</h4>
                <form method="post">
                    <label for="waterfall">identyfikator wodospadu</label>
                    <input type="number" id="waterfall" name="waterfall">
                    <label for="tourist">turysta</label>
                    <select id="tourist" name="tourist">
                        <?php
                            $query = "SELECT idTurysta, nick FROM turysci;";
                            $result = mysqli_query($connection, $query);
                        ?>
                    </select>
                    <button type="submit">Wpisz</button>
                </form>
                <?php
                    mysqli_close($connection);
                ?>
            </section>
        </main>
        <article>
            <h3>Wodospady w Polsce</h3>
            <img src="kamienczyk.jpg" alt="wodospad">
            <img src="siklawica.jpg" alt="wodospad">
            <img src="siklawa.jpg" alt="wodospad">
            <img src="wilczki.jpg" alt="wodospad">
        </article>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  44. Krok 44: Skrypt 3: opcje z identyfikatorem w value

    Kryteria: ,

    R.3.6 Pole edycyjne jest typu number. Lista rozwijana zawiera co najmniej jedno imię (<option> w skrypcie lub HTML )

    R.5.7 Skrypt 3: wszystkie zwrócone nicki są wyświetlane w liście rozwijanej jako opcje, a identyfikatory przypisane są do atrybutu value

    ok. 2 min
    Polecenie z arkusza

    Kolejne rekordy są opcjami listy rozwijanej tak, że atrybut wartości to pole idTurysta, a treść to nick

    Widać nick, a formularz wyśle value, czyli identyfikator - do tabeli osiagniecia trafia przecież idTurysta, nie imię. Rozwiń listę w podglądzie: 13 turystów, pierwsza Ewa, jak na ilustracji 2.

    index.php PHP zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wodospady</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Łowcy wodospadów</h2>
        </header>
        <main>
            <aside>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "wodospady");
                    $query = "SELECT idKontynent, nazwa FROM kontynenty;";
                    $result = mysqli_query($connection, $query);
                    while ($row = mysqli_fetch_row($result)) {
                        echo "<a href=\"index.php?id=$row[0]\">$row[1]</a>";
                    }
                ?>
            </aside>
            <section>
                <table>
                    <tr>
                        <th>Identyfikator</th>
                        <th>Państwo</th>
                        <th>Nazwa wodospadu</th>
                        <th>Wysokość</th>
                    </tr>
                    <?php
                        if (isset($_GET["id"])) {
                            $continent = $_GET["id"];
                        } else {
                            $continent = 6;
                        }
                        $query = "SELECT idObiekt, panstwo, nazwa, wartoscCechy FROM obiekty WHERE idRodzaj = 10 AND idKontynent = $continent;";
                        $result = mysqli_query($connection, $query);
                        while ($row = mysqli_fetch_row($result)) {
                            echo "<tr>";
                            echo "<td>$row[0]</td>";
                            echo "<td>$row[1]</td>";
                            echo "<td>$row[2]</td>";
                            echo "<td>$row[3]</td>";
                            echo "</tr>";
                        }
                    ?>
                </table>
                <h4>Wpisz osiągnięcie do bazy</h4>
                <form method="post">
                    <label for="waterfall">identyfikator wodospadu</label>
                    <input type="number" id="waterfall" name="waterfall">
                    <label for="tourist">turysta</label>
                    <select id="tourist" name="tourist">
                        <?php
                            $query = "SELECT idTurysta, nick FROM turysci;";
                            $result = mysqli_query($connection, $query);
                            while ($row = mysqli_fetch_row($result)) {
                                echo "<option value=\"$row[0]\">$row[1]</option>";
                            }
                        ?>
                    </select>
                    <button type="submit">Wpisz</button>
                </form>
                <?php
                    mysqli_close($connection);
                ?>
            </section>
        </main>
        <article>
            <h3>Wodospady w Polsce</h3>
            <img src="kamienczyk.jpg" alt="wodospad">
            <img src="siklawica.jpg" alt="wodospad">
            <img src="siklawa.jpg" alt="wodospad">
            <img src="wilczki.jpg" alt="wodospad">
        </article>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  45. Krok 45: Skrypt 4: tylko po wysłaniu formularza

    Kryteria:

    R.5.8 Skrypt 4 działa tylko wtedy, gdy dane zostały wysłane z formularza (wystarczy sprawdzenie jednej kontrolki )

    ok. 2 min
    Polecenie z arkusza

    Działa tylko w przypadku, gdy z formularza zostały przesłane dane

    Przy zwykłym wejściu na stronę tablica $_POST jest pusta, po kliknięciu „Wpisz” ma klucze waterfall i tourist. Warunek isset na jednym polu wystarczy (klucz: „wystarczy sprawdzenie jednej kontrolki”). Zamknięcie połączenia stoi pod blokiem if, poza nim - wykona się zawsze.

    index.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wodospady</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Łowcy wodospadów</h2>
        </header>
        <main>
            <aside>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "wodospady");
                    $query = "SELECT idKontynent, nazwa FROM kontynenty;";
                    $result = mysqli_query($connection, $query);
                    while ($row = mysqli_fetch_row($result)) {
                        echo "<a href=\"index.php?id=$row[0]\">$row[1]</a>";
                    }
                ?>
            </aside>
            <section>
                <table>
                    <tr>
                        <th>Identyfikator</th>
                        <th>Państwo</th>
                        <th>Nazwa wodospadu</th>
                        <th>Wysokość</th>
                    </tr>
                    <?php
                        if (isset($_GET["id"])) {
                            $continent = $_GET["id"];
                        } else {
                            $continent = 6;
                        }
                        $query = "SELECT idObiekt, panstwo, nazwa, wartoscCechy FROM obiekty WHERE idRodzaj = 10 AND idKontynent = $continent;";
                        $result = mysqli_query($connection, $query);
                        while ($row = mysqli_fetch_row($result)) {
                            echo "<tr>";
                            echo "<td>$row[0]</td>";
                            echo "<td>$row[1]</td>";
                            echo "<td>$row[2]</td>";
                            echo "<td>$row[3]</td>";
                            echo "</tr>";
                        }
                    ?>
                </table>
                <h4>Wpisz osiągnięcie do bazy</h4>
                <form method="post">
                    <label for="waterfall">identyfikator wodospadu</label>
                    <input type="number" id="waterfall" name="waterfall">
                    <label for="tourist">turysta</label>
                    <select id="tourist" name="tourist">
                        <?php
                            $query = "SELECT idTurysta, nick FROM turysci;";
                            $result = mysqli_query($connection, $query);
                            while ($row = mysqli_fetch_row($result)) {
                                echo "<option value=\"$row[0]\">$row[1]</option>";
                            }
                        ?>
                    </select>
                    <button type="submit">Wpisz</button>
                </form>
                <?php
                    if (isset($_POST["waterfall"])) {
                    }
                    mysqli_close($connection);
                ?>
            </section>
        </main>
        <article>
            <h3>Wodospady w Polsce</h3>
            <img src="kamienczyk.jpg" alt="wodospad">
            <img src="siklawica.jpg" alt="wodospad">
            <img src="siklawa.jpg" alt="wodospad">
            <img src="wilczki.jpg" alt="wodospad">
        </article>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>

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

  46. Krok 46: Skrypt 4: zapis osiągnięcia z formularza

    Kryteria:

    R.5.9 Skrypt 4 wysyła do bazy danych zapytanie 4, dane pobrane z formularza są wstawiane do bazy jako identyfikatory: obiektu i turysty (sprawdzić w phpMyAdmin dla dwóch wstawień, należy podawać tylko id z tabeli )

    ok. 3 min
    Polecenie z arkusza

    Wysyła do bazy danych zapytanie 4, zmodyfikowane w ten sposób, że do bazy wstawione są wartości pobrane z formularza (zakłada się że użytkownik wpisuje tylko identyfikatory wyświetlone w tabeli i nie trzeba sprawdzać poprawności identyfikatora)

    Wartości z $_POST w miejscu 34 i 2 z zapytania 4. Strona po wysłaniu wygląda tak samo, bo skrypt niczego nie wypisuje - efekt widać w phpMyAdmin. Sprawdzone tak jak w kluczu, dwoma wysłaniami (wodospad 42 z Ewą i 47 z Paulą): w tabeli osiagniecia przybyły rekordy 2 (42, 1) i 3 (47, 5).

    Typowe błędy

    Puste pole identyfikatora wodospadu daje zapytanie VALUES (, 1) - błąd składni SQL, wyjątek „Uncaught mysqli_sql_exception” i strona urwana w połowie (sprawdzone w PHP 8.2). Klucz tego nie sprawdza - zabezpieczenie jest w etapie „Dobre praktyki”.

    index.php PHP zmienione: 4 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wodospady</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Łowcy wodospadów</h2>
        </header>
        <main>
            <aside>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "wodospady");
                    $query = "SELECT idKontynent, nazwa FROM kontynenty;";
                    $result = mysqli_query($connection, $query);
                    while ($row = mysqli_fetch_row($result)) {
                        echo "<a href=\"index.php?id=$row[0]\">$row[1]</a>";
                    }
                ?>
            </aside>
            <section>
                <table>
                    <tr>
                        <th>Identyfikator</th>
                        <th>Państwo</th>
                        <th>Nazwa wodospadu</th>
                        <th>Wysokość</th>
                    </tr>
                    <?php
                        if (isset($_GET["id"])) {
                            $continent = $_GET["id"];
                        } else {
                            $continent = 6;
                        }
                        $query = "SELECT idObiekt, panstwo, nazwa, wartoscCechy FROM obiekty WHERE idRodzaj = 10 AND idKontynent = $continent;";
                        $result = mysqli_query($connection, $query);
                        while ($row = mysqli_fetch_row($result)) {
                            echo "<tr>";
                            echo "<td>$row[0]</td>";
                            echo "<td>$row[1]</td>";
                            echo "<td>$row[2]</td>";
                            echo "<td>$row[3]</td>";
                            echo "</tr>";
                        }
                    ?>
                </table>
                <h4>Wpisz osiągnięcie do bazy</h4>
                <form method="post">
                    <label for="waterfall">identyfikator wodospadu</label>
                    <input type="number" id="waterfall" name="waterfall">
                    <label for="tourist">turysta</label>
                    <select id="tourist" name="tourist">
                        <?php
                            $query = "SELECT idTurysta, nick FROM turysci;";
                            $result = mysqli_query($connection, $query);
                            while ($row = mysqli_fetch_row($result)) {
                                echo "<option value=\"$row[0]\">$row[1]</option>";
                            }
                        ?>
                    </select>
                    <button type="submit">Wpisz</button>
                </form>
                <?php
                    if (isset($_POST["waterfall"])) {
                        $waterfall = $_POST["waterfall"];
                        $tourist = $_POST["tourist"];
                        $query = "INSERT INTO osiagniecia (idObiekt, idTurysta) VALUES ($waterfall, $tourist);";
                        mysqli_query($connection, $query);
                    }
                    mysqli_close($connection);
                ?>
            </section>
        </main>
        <article>
            <h3>Wodospady w Polsce</h3>
            <img src="kamienczyk.jpg" alt="wodospad">
            <img src="siklawica.jpg" alt="wodospad">
            <img src="siklawa.jpg" alt="wodospad">
            <img src="wilczki.jpg" alt="wodospad">
        </article>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>

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

  47. Etap 5: Dobre praktyki (poza kluczem)

    Kroki 47-50 · po tym etapie masz 41 z 41 kryteriów (pkt)

    Krok 47: Identyfikator z adresu zamieniony na liczbę

    ok. 3 min
    Polecenie z arkusza

    Pobiera wartość przesłaną metodą GET, a w przypadku braku – wartością 6. Wartość ta jest identyfikatorem kontynentu

    W wersji z egzaminu tekst z adresu trafia do zapytania bez zmian. Sprawdzone na tej bazie: adres index.php?id=6 OR 1=1 daje zapytanie ... AND idKontynent = 6 OR 1=1, a tabela pokazuje 25 wierszy - wszystkie obiekty bazy, także szczyty, wulkany i jaskinie. Rzutowanie (int) zamienia parametr na liczbę (z „6 OR 1=1” zostaje 6), a operator ?? podstawia 6, gdy parametru nie ma - jedna linia zamiast czterech. Stara wersja zostaje w komentarzu. Na egzaminie wystarczy wersja wcześniejsza - klucz tego nie sprawdza.

    index.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wodospady</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Łowcy wodospadów</h2>
        </header>
        <main>
            <aside>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "wodospady");
                    $query = "SELECT idKontynent, nazwa FROM kontynenty;";
                    $result = mysqli_query($connection, $query);
                    while ($row = mysqli_fetch_row($result)) {
                        echo "<a href=\"index.php?id=$row[0]\">$row[1]</a>";
                    }
                ?>
            </aside>
            <section>
                <table>
                    <tr>
                        <th>Identyfikator</th>
                        <th>Państwo</th>
                        <th>Nazwa wodospadu</th>
                        <th>Wysokość</th>
                    </tr>
                    <?php
                        $continent = (int) ($_GET["id"] ?? 6);
                        // if (isset($_GET["id"])) { $continent = $_GET["id"]; } else { $continent = 6; }
                        $query = "SELECT idObiekt, panstwo, nazwa, wartoscCechy FROM obiekty WHERE idRodzaj = 10 AND idKontynent = $continent;";
                        $result = mysqli_query($connection, $query);
                        while ($row = mysqli_fetch_row($result)) {
                            echo "<tr>";
                            echo "<td>$row[0]</td>";
                            echo "<td>$row[1]</td>";
                            echo "<td>$row[2]</td>";
                            echo "<td>$row[3]</td>";
                            echo "</tr>";
                        }
                    ?>
                </table>
                <h4>Wpisz osiągnięcie do bazy</h4>
                <form method="post">
                    <label for="waterfall">identyfikator wodospadu</label>
                    <input type="number" id="waterfall" name="waterfall">
                    <label for="tourist">turysta</label>
                    <select id="tourist" name="tourist">
                        <?php
                            $query = "SELECT idTurysta, nick FROM turysci;";
                            $result = mysqli_query($connection, $query);
                            while ($row = mysqli_fetch_row($result)) {
                                echo "<option value=\"$row[0]\">$row[1]</option>";
                            }
                        ?>
                    </select>
                    <button type="submit">Wpisz</button>
                </form>
                <?php
                    if (isset($_POST["waterfall"])) {
                        $waterfall = $_POST["waterfall"];
                        $tourist = $_POST["tourist"];
                        $query = "INSERT INTO osiagniecia (idObiekt, idTurysta) VALUES ($waterfall, $tourist);";
                        mysqli_query($connection, $query);
                    }
                    mysqli_close($connection);
                ?>
            </section>
        </main>
        <article>
            <h3>Wodospady w Polsce</h3>
            <img src="kamienczyk.jpg" alt="wodospad">
            <img src="siklawica.jpg" alt="wodospad">
            <img src="siklawa.jpg" alt="wodospad">
            <img src="wilczki.jpg" alt="wodospad">
        </article>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>

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

  48. Krok 48: Zapis osiągnięcia: zapytanie przygotowane i obsługa błędu

    ok. 4 min
    Polecenie z arkusza

    Działa tylko w przypadku, gdy z formularza zostały przesłane dane, wysyła do bazy danych zapytanie 4, zmodyfikowane w ten sposób, że do bazy wstawione są wartości pobrane z formularza

    Wersja z egzaminu została sprawdzona dwoma „złośliwymi” wysłaniami: puste pole identyfikatora daje zapytanie VALUES (, 1) i stronę urwaną błędem „Uncaught mysqli_sql_exception”, a identyfikator 999 kończy się tym samym błędem z powodu klucza obcego („a foreign key constraint fails”). Poprawki: !empty zamiast isset (puste pole nie uruchamia zapisu), rzutowanie (int), zapytanie przygotowane (mysqli_prepare, znaki ?, mysqli_stmt_bind_param z typami "ii") i try/catch, który zamienia błąd bazy na komunikat. Podgląd pokazuje stan po wysłaniu identyfikatora 42 z turystą Ewa. Na egzaminie wystarczy wersja wcześniejsza - arkusz wprost zwalnia ze sprawdzania identyfikatora.

    index.php PHP zmienione: 15 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wodospady</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Łowcy wodospadów</h2>
        </header>
        <main>
            <aside>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "wodospady");
                    $query = "SELECT idKontynent, nazwa FROM kontynenty;";
                    $result = mysqli_query($connection, $query);
                    while ($row = mysqli_fetch_row($result)) {
                        echo "<a href=\"index.php?id=$row[0]\">$row[1]</a>";
                    }
                ?>
            </aside>
            <section>
                <table>
                    <tr>
                        <th>Identyfikator</th>
                        <th>Państwo</th>
                        <th>Nazwa wodospadu</th>
                        <th>Wysokość</th>
                    </tr>
                    <?php
                        $continent = (int) ($_GET["id"] ?? 6);
                        // if (isset($_GET["id"])) { $continent = $_GET["id"]; } else { $continent = 6; }
                        $query = "SELECT idObiekt, panstwo, nazwa, wartoscCechy FROM obiekty WHERE idRodzaj = 10 AND idKontynent = $continent;";
                        $result = mysqli_query($connection, $query);
                        while ($row = mysqli_fetch_row($result)) {
                            echo "<tr>";
                            echo "<td>$row[0]</td>";
                            echo "<td>$row[1]</td>";
                            echo "<td>$row[2]</td>";
                            echo "<td>$row[3]</td>";
                            echo "</tr>";
                        }
                    ?>
                </table>
                <h4>Wpisz osiągnięcie do bazy</h4>
                <form method="post">
                    <label for="waterfall">identyfikator wodospadu</label>
                    <input type="number" id="waterfall" name="waterfall">
                    <label for="tourist">turysta</label>
                    <select id="tourist" name="tourist">
                        <?php
                            $query = "SELECT idTurysta, nick FROM turysci;";
                            $result = mysqli_query($connection, $query);
                            while ($row = mysqli_fetch_row($result)) {
                                echo "<option value=\"$row[0]\">$row[1]</option>";
                            }
                        ?>
                    </select>
                    <button type="submit">Wpisz</button>
                </form>
                <?php
                    if (!empty($_POST["waterfall"]) && !empty($_POST["tourist"])) {
                        $waterfall = (int) $_POST["waterfall"];
                        $tourist = (int) $_POST["tourist"];
                        $statement = mysqli_prepare($connection, "INSERT INTO osiagniecia (idObiekt, idTurysta) VALUES (?, ?)");
                        mysqli_stmt_bind_param($statement, "ii", $waterfall, $tourist);
                        try {
                            mysqli_stmt_execute($statement);
                            echo "<p>Osiągnięcie zapisane.</p>";
                        } catch (mysqli_sql_exception $error) {
                            echo "<p>Nie ma obiektu o identyfikatorze $waterfall.</p>";
                        }
                    }
                    mysqli_close($connection);
                    /* Wersja z egzaminu:
                    if (isset($_POST["waterfall"])) {
                        $waterfall = $_POST["waterfall"];
                        $tourist = $_POST["tourist"];
                        $query = "INSERT INTO osiagniecia (idObiekt, idTurysta) VALUES ($waterfall, $tourist);";
                        mysqli_query($connection, $query);
                    }
                    */
                ?>
            </section>
        </main>
        <article>
            <h3>Wodospady w Polsce</h3>
            <img src="kamienczyk.jpg" alt="wodospad">
            <img src="siklawica.jpg" alt="wodospad">
            <img src="siklawa.jpg" alt="wodospad">
            <img src="wilczki.jpg" alt="wodospad">
        </article>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  49. Krok 49: Odnośniki i lista: pola po nazwach i htmlspecialchars

    ok. 3 min
    Polecenie z arkusza

    Dla każdego zwróconego zapytaniem rekordu wyświetla odnośnik, którego treścią jest nazwa kontynentu.

    mysqli_fetch_assoc oddaje wiersz z kluczami takimi jak nazwy kolumn: $continentRow["nazwa"] mówi więcej niż $row[1] i nie psuje się po zmianie kolejności pól w SELECT. Tekst z bazy (nazwy kontynentów, nicki) wypisujesz przez htmlspecialchars - turysta o nicku z < i > nie rozbije wtedy listy. Podgląd wygląda tak samo jak wcześniej, bo dane są te same. Na egzaminie wystarczy wersja wcześniejsza - klucz tego nie sprawdza.

    index.php PHP zmienione: 6 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wodospady</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Łowcy wodospadów</h2>
        </header>
        <main>
            <aside>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "wodospady");
                    $query = "SELECT idKontynent, nazwa FROM kontynenty;";
                    $result = mysqli_query($connection, $query);
                    while ($continentRow = mysqli_fetch_assoc($result)) {
                        echo "<a href=\"index.php?id=" . $continentRow["idKontynent"] . "\">" . htmlspecialchars($continentRow["nazwa"]) . "</a>";
                    }
                    // while ($row = mysqli_fetch_row($result)) { echo "<a href=\"index.php?id=$row[0]\">$row[1]</a>"; }
                ?>
            </aside>
            <section>
                <table>
                    <tr>
                        <th>Identyfikator</th>
                        <th>Państwo</th>
                        <th>Nazwa wodospadu</th>
                        <th>Wysokość</th>
                    </tr>
                    <?php
                        $continent = (int) ($_GET["id"] ?? 6);
                        // if (isset($_GET["id"])) { $continent = $_GET["id"]; } else { $continent = 6; }
                        $query = "SELECT idObiekt, panstwo, nazwa, wartoscCechy FROM obiekty WHERE idRodzaj = 10 AND idKontynent = $continent;";
                        $result = mysqli_query($connection, $query);
                        while ($row = mysqli_fetch_row($result)) {
                            echo "<tr>";
                            echo "<td>$row[0]</td>";
                            echo "<td>$row[1]</td>";
                            echo "<td>$row[2]</td>";
                            echo "<td>$row[3]</td>";
                            echo "</tr>";
                        }
                    ?>
                </table>
                <h4>Wpisz osiągnięcie do bazy</h4>
                <form method="post">
                    <label for="waterfall">identyfikator wodospadu</label>
                    <input type="number" id="waterfall" name="waterfall">
                    <label for="tourist">turysta</label>
                    <select id="tourist" name="tourist">
                        <?php
                            $query = "SELECT idTurysta, nick FROM turysci;";
                            $result = mysqli_query($connection, $query);
                            while ($touristRow = mysqli_fetch_assoc($result)) {
                                echo "<option value=\"" . $touristRow["idTurysta"] . "\">" . htmlspecialchars($touristRow["nick"]) . "</option>";
                            }
                            // while ($row = mysqli_fetch_row($result)) { echo "<option value=\"$row[0]\">$row[1]</option>"; }
                        ?>
                    </select>
                    <button type="submit">Wpisz</button>
                </form>
                <?php
                    if (!empty($_POST["waterfall"]) && !empty($_POST["tourist"])) {
                        $waterfall = (int) $_POST["waterfall"];
                        $tourist = (int) $_POST["tourist"];
                        $statement = mysqli_prepare($connection, "INSERT INTO osiagniecia (idObiekt, idTurysta) VALUES (?, ?)");
                        mysqli_stmt_bind_param($statement, "ii", $waterfall, $tourist);
                        try {
                            mysqli_stmt_execute($statement);
                            echo "<p>Osiągnięcie zapisane.</p>";
                        } catch (mysqli_sql_exception $error) {
                            echo "<p>Nie ma obiektu o identyfikatorze $waterfall.</p>";
                        }
                    }
                    mysqli_close($connection);
                    /* Wersja z egzaminu:
                    if (isset($_POST["waterfall"])) {
                        $waterfall = $_POST["waterfall"];
                        $tourist = $_POST["tourist"];
                        $query = "INSERT INTO osiagniecia (idObiekt, idTurysta) VALUES ($waterfall, $tourist);";
                        mysqli_query($connection, $query);
                    }
                    */
                ?>
            </section>
        </main>
        <article>
            <h3>Wodospady w Polsce</h3>
            <img src="kamienczyk.jpg" alt="wodospad">
            <img src="siklawica.jpg" alt="wodospad">
            <img src="siklawa.jpg" alt="wodospad">
            <img src="wilczki.jpg" alt="wodospad">
        </article>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  50. Krok 50: Kolumna „Wysokość”: dane, które nie są wysokością

    ok. 3 min
    Polecenie z arkusza

    Tabela o czterech kolumnach. Pierwszy wiersz jest wierszem nagłówkowym z komórkami: „Identyfikator”, „Państwo”, „Nazwa wodospadu”. „Wysokość”. Tabela jest wypełniona skryptem 2

    Baza z arkusza ma pułapkę: kolumna wartoscCechy znaczy co innego w każdym wierszu, a co - mówi pole nazwaCechy. Dla Dettifossu to przepustowość 193 m³/s, nie wysokość, więc w kolumnie „Wysokość” stoi wartość, która wprowadza w błąd. Dobierz nazwaCechy do zapytania i przy cesze innej niż „wysokość” dopisz jej nazwę: w podglądzie Dettifoss ma „193 (przepustowość metry sześcienne)”. Kodu nie da się jednak naprawić z błędu w samych danych: Godafoss ma wpisane 30, choć jego opis w bazie mówi o spadku z 12 m na szerokości 30 m. Na egzaminie wystarczy wersja wcześniejsza - klucz sprawdza dokładnie cztery pola z zapytania 3.

    index.php PHP zmienione: 10 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wodospady</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Łowcy wodospadów</h2>
        </header>
        <main>
            <aside>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "wodospady");
                    $query = "SELECT idKontynent, nazwa FROM kontynenty;";
                    $result = mysqli_query($connection, $query);
                    while ($continentRow = mysqli_fetch_assoc($result)) {
                        echo "<a href=\"index.php?id=" . $continentRow["idKontynent"] . "\">" . htmlspecialchars($continentRow["nazwa"]) . "</a>";
                    }
                    // while ($row = mysqli_fetch_row($result)) { echo "<a href=\"index.php?id=$row[0]\">$row[1]</a>"; }
                ?>
            </aside>
            <section>
                <table>
                    <tr>
                        <th>Identyfikator</th>
                        <th>Państwo</th>
                        <th>Nazwa wodospadu</th>
                        <th>Wysokość</th>
                    </tr>
                    <?php
                        $continent = (int) ($_GET["id"] ?? 6);
                        // if (isset($_GET["id"])) { $continent = $_GET["id"]; } else { $continent = 6; }
                        $query = "SELECT idObiekt, panstwo, nazwa, wartoscCechy, nazwaCechy FROM obiekty WHERE idRodzaj = 10 AND idKontynent = $continent;";
                        $result = mysqli_query($connection, $query);
                        while ($waterfallRow = mysqli_fetch_assoc($result)) {
                            $value = $waterfallRow["wartoscCechy"];
                            if ($waterfallRow["nazwaCechy"] != "wysokość") {
                                $value .= " (" . $waterfallRow["nazwaCechy"] . ")";
                            }
                            echo "<tr>";
                            echo "<td>" . $waterfallRow["idObiekt"] . "</td>";
                            echo "<td>" . htmlspecialchars($waterfallRow["panstwo"]) . "</td>";
                            echo "<td>" . htmlspecialchars($waterfallRow["nazwa"]) . "</td>";
                            echo "<td>" . htmlspecialchars($value) . "</td>";
                            echo "</tr>";
                        }
                    ?>
                </table>
                <h4>Wpisz osiągnięcie do bazy</h4>
                <form method="post">
                    <label for="waterfall">identyfikator wodospadu</label>
                    <input type="number" id="waterfall" name="waterfall">
                    <label for="tourist">turysta</label>
                    <select id="tourist" name="tourist">
                        <?php
                            $query = "SELECT idTurysta, nick FROM turysci;";
                            $result = mysqli_query($connection, $query);
                            while ($touristRow = mysqli_fetch_assoc($result)) {
                                echo "<option value=\"" . $touristRow["idTurysta"] . "\">" . htmlspecialchars($touristRow["nick"]) . "</option>";
                            }
                            // while ($row = mysqli_fetch_row($result)) { echo "<option value=\"$row[0]\">$row[1]</option>"; }
                        ?>
                    </select>
                    <button type="submit">Wpisz</button>
                </form>
                <?php
                    if (!empty($_POST["waterfall"]) && !empty($_POST["tourist"])) {
                        $waterfall = (int) $_POST["waterfall"];
                        $tourist = (int) $_POST["tourist"];
                        $statement = mysqli_prepare($connection, "INSERT INTO osiagniecia (idObiekt, idTurysta) VALUES (?, ?)");
                        mysqli_stmt_bind_param($statement, "ii", $waterfall, $tourist);
                        try {
                            mysqli_stmt_execute($statement);
                            echo "<p>Osiągnięcie zapisane.</p>";
                        } catch (mysqli_sql_exception $error) {
                            echo "<p>Nie ma obiektu o identyfikatorze $waterfall.</p>";
                        }
                    }
                    mysqli_close($connection);
                    /* Wersja z egzaminu:
                    if (isset($_POST["waterfall"])) {
                        $waterfall = $_POST["waterfall"];
                        $tourist = $_POST["tourist"];
                        $query = "INSERT INTO osiagniecia (idObiekt, idTurysta) VALUES ($waterfall, $tourist);";
                        mysqli_query($connection, $query);
                    }
                    */
                ?>
            </section>
        </main>
        <article>
            <h3>Wodospady w Polsce</h3>
            <img src="kamienczyk.jpg" alt="wodospad">
            <img src="siklawica.jpg" alt="wodospad">
            <img src="siklawa.jpg" alt="wodospad">
            <img src="wilczki.jpg" alt="wodospad">
        </article>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  51. Etap 6: Oddanie pracy

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

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

    ok. 5 min
    Polecenie z arkusza

    Po zakończeniu pracy utwórz plik tekstowy o nazwie przeglądarka.txt. Zapisz w nim nazwę przeglądarki internetowej, w której weryfikowana była poprawność działania witryny. Umieść go w folderze z numerem zdającego. Nagraj płytę z rezultatami pracy.

    W przeglądarka.txt wpisujesz nazwę przeglądarki, w której sprawdzasz stronę.

    W folderze z numerem zdającego: import.jpg, index.php, kamienczyk.jpg, kw1.png - kw5.png, kwerendy.txt, przeglądarka.txt, siklawa.jpg, siklawica.jpg, styl.css, wilczki.jpg. Nagraj płytę, sprawdź jej odczyt i opisz ją numerem zdającego.

    przeglądarka.txt Tekst nowy plik
    Google Chrome

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

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.