Przejdź do głównej treści
INF.03-01-26.06-SGCzerwiec 2026 · 50 kroków · ok. 95 min · 37 kryteriów z klucza

Rozwiązanie krok po kroku: Portal turystyczny Islandii (Wersja podstawowa)

Rozwiązanie buduje portal turystyczny o Islandii: baza islandia z trzema tabelami połączonymi relacją i czterema zapytaniami (SELECT z warunkiem, złączenie z tabelą rodzajów, warunek z AND, grupowanie z COUNT i aliasem), dwie strony PHP ze wspólnym nagłówkiem, blokiem bocznym i stopką - islandia.php z galerią miniatur i obiekty.php z opisem miejsca wybranego w galerii - oraz style w styl.css z zaokrągleniami, linią kreskową, paskami przewijania i płynną zmianą przezroczystości po najechaniu kursorem. Cztery skrypty PHP: dwie listy numerowane w bloku bocznym, galeria odnośników przekazujących identyfikator metodą GET i strona opisu, która ten identyfikator odczytuje z $_GET.

Kroki idą zdanie po zdaniu za treścią arkusza - każdy zaczyna się poleceniem z arkusza, a kod pokazuje dokładnie te linie, które je spełniają. Kod PHP jest najpierw pisany funkcjami z tabeli 1 arkusza (proceduralne mysqli), tak jak każe arkusz - a na końcu całość zostaje przerobiona na wersję z prawdziwych projektów: zapytanie przygotowane dla parametru z adresu (dziś obiekty.php?id=... jest furtką do SQL injection), escapowanie danych i wspólny blok boczny w jednym pliku zamiast w dwóch kopiach.

To jest wersja podstawowa. Obok są jeszcze dwie zgodne z kluczem: „Nowoczesny kod (grid, PDO)” - układ na siatce CSS i PHP na PDO z zapytaniami przygotowanymi od pierwszej linii, oraz „Wspólne pliki (include, mysqli)” - kod rozłożony na pliki jak w prawdziwym projekcie.

Baza i zdjęcia pochodzą z prawdziwego archiwum pliki1 (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 obiekty.php pokazuje obiekt z ilustracji 3 (Godafoss, obiekty.php?id=53).

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

  1. Etap 1: Baza danych

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

    Krok 1: Baza danych islandia

    Kryteria:

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

    ok. 3 min
    Polecenie z arkusza

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

    Najpierw rozpakuj archiwum pliki1.7z z pulpitu (hasło isLandi@ z treści zadania) - są w nim baza1.sql i dziewięć zdjęć. W phpMyAdmin (http://localhost/phpmyadmin) klikasz Nowa, wpisujesz islandia i z listy metod porównywania wybierasz utf8_unicode_ci. To ogólne porównywanie Unicode: sortuje polskie („siedlisko zwierząt”, „gorące źródło”) i islandzkie litery („Fuglaskoðunarhús”) według zasad Unicode, a przy porównaniach nie rozróżnia wielkości liter. Dziedziczą je jednak tylko tabele zakładane później bez własnego ustawienia - tabele z baza1.sql mają w definicji utf8_polish_ci i to ono działa w zapytaniach.

    Typowe błędy

    Nazwa bazy musi być dokładnie islandia - skrypty łączą się z bazą po nazwie (R.5.1).

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

    Kryteria:

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

    ok. 2 min
    Polecenie z arkusza

    Do utworzonej bazy zaimportuj tabele z pliku baza1.sql.

    Wejdź do bazy islandia (zaznaczona w lewym panelu), karta Import, Wybierz plik → baza1.sql, Wykonaj. Plik tworzy pięć tabel, ale arkusz każe korzystać tylko z trzech z ilustracji 1: kontynenty, rodzaje (9 rodzajów obiektów: wodospad, szczyt, siedlisko zwierząt...) i obiekty (25 obiektów; każdy ma klucz obcy idRodzaj wskazujący jego rodzaj i kolumnę panstwo). Uwaga na wielkość liter w nazwach kolumn: idObiekt, idRodzaj, nazwaCechy, wartoscCechy.

  3. Krok 3: Zrzut ekranu import.jpg

    Kryteria:

    R.1.1 Wykonany import tabel do bazy danych islandia - 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 (cały ekran), wklejasz do edytora grafiki i zapisujesz jako import.jpg - w tym arkuszu zrzut importu jest w JPEG, a zrzuty zapytań w PNG. Na zrzucie ma być komunikat o udanym imporcie albo lista tabel bazy.

    Typowe błędy

    Zły format (import.png) albo wykadrowany zrzut to strata punktu R.1.1 - klucz nie ocenia wykadrowanych zrzutów.

  4. Krok 4: Zapytanie 1: obiekty z Islandii

    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 jedynie pola idObiekt, plik i nazwa z tabeli obiekty dla Islandii. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT idObiekt, plik, nazwa FROM obiekty WHERE panstwo = "Islandia"; oraz na zrzucie widocznych jest dokładnie 9 rekordów o identyfikatorach 46 ÷ 54

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 1: wybierające jedynie pola idObiekt, plik i nazwa z tabeli obiekty dla Islandii.

    Karta SQL przy zaznaczonej bazie. SELECT idObiekt, plik, nazwa - trzy kolumny w kolejności z arkusza, FROM obiekty, a „dla Islandii” to warunek na kolumnie panstwo: WHERE panstwo = "Islandia". Wynik: dokładnie 9 wierszy o identyfikatorach 46-54 - jak w kluczu. Zapytanie kopiujesz do kwerendy.txt, zrzut zapisujesz jako kw1.png. To zapytanie wyśle skrypt 3, budując galerię.

    kwerendy.txt Tekst nowy plik
    -- Zapytanie 1
    SELECT idObiekt, plik, nazwa FROM obiekty WHERE panstwo = "Islandia";
    Podgląd strony po tym kroku
    Podgląd strony po kroku 4
  5. Krok 5: Zapytanie 2: dane obiektu 46 z rodzajem

    Kryteria:

    R.1.4 Wykonane zapytanie 2 wybierające jedynie pola plik, nazwa, nazwaCechy, wartoscCechy, opis z tabeli obiekty oraz odpowiadające im pole rodzaj z tabeli rodzaje dla obiektu o identyfikatorze 46. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT plik, nazwa, nazwaCechy, wartoscCechy, opis, rodzaj FROM obiekty JOIN rodzaje USING(idRodzaj) WHERE idObiekt = 46; (lub INNER JOIN lub porównanie kluczy po ON lub WHERE ) oraz na zrzucie widoczny jest dokładnie 1 rekord dla nazwy Strokkur

    ok. 3 min
    Polecenie z arkusza

    Zapytanie 2: wybierające jedynie pola plik, nazwa, nazwaCechy, wartoscCechy, opis z tabeli obiekty oraz odpowiadające im pole rodzaj z tabeli rodzaje dla obiektu o identyfikatorze 46. Należy posłużyć się relacją.

    Pole rodzaj jest w innej tabeli, więc łączysz tabele relacją:

    • SELECT plik, nazwa, nazwaCechy, wartoscCechy, opis, rodzaj - sześć kolumn, pięć z obiekty i jedna z rodzaje.
    • FROM obiekty JOIN rodzaje ON obiekty.idRodzaj = rodzaje.idRodzaj - do obiektu dokładasz wiersz jego rodzaju. Kolumna idRodzaj jest w obu tabelach, więc poprzedzasz ją nazwą tabeli (krócej: USING(idRodzaj)).
    • WHERE idObiekt = 46 - jeden obiekt.

    Wynik: dokładnie 1 wiersz, gejzer Strokkur - jak w kluczu. Zrzut: kw2.png. To zapytanie wyśle skrypt 4, podstawiając w miejsce 46 identyfikator z adresu strony.

    Typowe błędy

    WHERE idRodzaj = ... bez nazwy tabeli w warunku złączenia to błąd „column is ambiguous” - kolumna idRodzaj jest w obu tabelach.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT idObiekt, plik, nazwa FROM obiekty WHERE panstwo = "Islandia";
    
    -- Zapytanie 2
    SELECT plik, nazwa, nazwaCechy, wartoscCechy, opis, rodzaj FROM obiekty JOIN rodzaje ON obiekty.idRodzaj = rodzaje.idRodzaj WHERE idObiekt = 46;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 5
  6. Krok 6: Zapytanie 3: wodospady Islandii

    Kryteria:

    R.1.5 Wykonane zapytanie 3 wybierające jedynie nazwy obiektów z Islandii, których identyfikator rodzaju to 10. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT nazwa FROM obiekty WHERE idRodzaj = 10 AND Panstwo = "Islandia"; oraz na zrzucie widoczne są dokładnie 4 rekordy: Skogafoss, Seljalandsfoss, Godafoss, Dettifoss

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 3: wybierające jedynie nazwy obiektów z Islandii, których identyfikator rodzaju to 10.

    Dwa warunki naraz, więc AND: państwo to Islandia i rodzaj ma identyfikator 10 (w tabeli rodzaje to wodospad). Złączenia nie trzeba - identyfikator rodzaju jest w samej tabeli obiekty. Wynik: 4 wiersze - Skogafoss, Seljalandsfoss, Godafoss, Dettifoss, jak w kluczu. Zrzut: kw3.png. To zapytanie wyśle skrypt 1 do listy „Wodospady:”.

    Typowe błędy

    OR zamiast AND zwróci wszystko z Islandii plus wszystkie wodospady świata (w bazie jest ich 12).

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT idObiekt, plik, nazwa FROM obiekty WHERE panstwo = "Islandia";
    
    -- Zapytanie 2
    SELECT plik, nazwa, nazwaCechy, wartoscCechy, opis, rodzaj FROM obiekty JOIN rodzaje ON obiekty.idRodzaj = rodzaje.idRodzaj WHERE idObiekt = 46;
    
    -- Zapytanie 3
    SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 10;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 6
  7. Krok 7: Zapytanie 4: liczba obiektów każdego rodzaju

    Kryteria:

    R.1.6 Wykonane zapytanie 4 wybierające jedynie rodzaj z tabeli rodzaje oraz zliczające liczbę obiektów danego rodzaju. Kolumna z liczbą obiektów powinna mieć nadaną nazwę (alias) „Liczba obiektów”. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT rodzaj, COUNT(obiekty.idObiekt) AS "Liczba obiektów" FROM Rodzaje JOIN obiekty USING(idRodzaj) GROUP BY rodzaj; (Po COUNT dowolna nazwa pola tabeli obiekty, AS opcjonalnie, lub porównanie kluczy po ON lub WHERE ) oraz na zrzucie widocznych jest dokładnie 8 rekordów: gorące źródło 1, jaskinia 2, jezioro 1, park narodowy 1, siedlisko zwierząt 2, szczyt 4, wodospad 12, wulkan 2

    ok. 3 min
    Polecenie z arkusza

    Zapytanie 4: wybierające jedynie rodzaj z tabeli rodzaje oraz zliczające liczbę obiektów (wodospadów, szczytów itd.) danego rodzaju. Kolumna z liczbą obiektów powinna mieć nadaną nazwę (alias) „Liczba obiektów”. Należy posłużyć się grupowaniem i relacją.

    • FROM rodzaje JOIN obiekty ON ... - relacja: każdy obiekt dostaje swój rodzaj.
    • GROUP BY rodzaj - wiersze z tym samym rodzajem zlewają się w jeden.
    • COUNT(idObiekt) - w każdej grupie liczy obiekty. AS "Liczba obiektów" nadaje kolumnie alias; ma spację i polską literę, więc musi być w cudzysłowie.

    Zlicz obiekty z całej bazy, nie tylko z Islandii (arkusz nie podaje warunku). Wynik: 8 wierszy - gorące źródło 1, jaskinia 2, jezioro 1, park narodowy 1, siedlisko zwierząt 2, szczyt 4, wodospad 12, wulkan 2 - dokładnie jak w kluczu. Rodzaj bez żadnego obiektu nie pojawia się, bo JOIN pomija wiersze bez pary. Zrzut: kw4.png - plik kwerendy.txt ma komplet czterech zapytań.

    Typowe błędy

    Alias bez cudzysłowu (AS Liczba obiektów) to błąd składni - spacja kończy alias. Bez GROUP BY COUNT zliczy wszystkie 25 obiektów w jednym wierszu.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT idObiekt, plik, nazwa FROM obiekty WHERE panstwo = "Islandia";
    
    -- Zapytanie 2
    SELECT plik, nazwa, nazwaCechy, wartoscCechy, opis, rodzaj FROM obiekty JOIN rodzaje ON obiekty.idRodzaj = rodzaje.idRodzaj WHERE idObiekt = 46;
    
    -- Zapytanie 3
    SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 10;
    
    -- Zapytanie 4
    SELECT rodzaj, COUNT(idObiekt) AS "Liczba obiektów" FROM rodzaje JOIN obiekty ON rodzaje.idRodzaj = obiekty.idRodzaj GROUP BY rodzaj;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 7
  8. Etap 2: Strona HTML

    Kroki 8-20 · po tym etapie masz 16 z 37 kryteriów (pkt)

    Krok 8: Plik islandia.php w HTML5

    Kryteria:

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

    ok. 2 min
    Polecenie z arkusza

    Witryna składa się z podstron: islandia.php i obiekty.php. Cechy wspólne obu stron: Zapisane w języku HTML5.

    Najpierw skopiuj dziewięć zdjęć z rozpakowanego archiwum do folderu zdającego - skrypty będą je wskazywać samą nazwą pliku z bazy (kolumna plik). Arkusz nie wymaga ich obróbki.

    W edytorze tworzysz islandia.php. Obie strony mają wspólny nagłówek, blok boczny i stopkę - budujesz więc najpierw całą islandia.php, a potem obiekty.php powstanie z jej kopii. <!DOCTYPE html> deklaruje HTML5, dalej szkielet <html>, <head>, <body>.

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

    Kryteria:

    R.2.1 W pliku islandia.php lub obiekty.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 <html> - informacja dla czytników ekranu i przeglądarki. Klucz R.2.1 sprawdza go razem z deklaracją HTML5.

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

    Kryteria:

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

    ok. 1 min
    Polecenie z arkusza

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

    <meta charset="UTF-8"> jako pierwszy element <head>. W bazie są nie tylko polskie litery, ale też islandzkie: obiekt „Fuglaskoðunarhús” ma literę ð - UTF-8 obejmuje wszystkie alfabety, więc wyświetli się poprawnie.

    islandia.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 (islandia.php)
  11. Krok 11: Tytuł strony

    Kryteria:

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

    ok. 1 min
    Polecenie z arkusza

    Tytuł strony „Islandia”.

    <title> w <head> - napis na karcie przeglądarki. Klucz R.2.2 sprawdza go razem z kodowaniem.

    islandia.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Islandia</title>
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (islandia.php)
  12. Krok 12: 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.

    <link rel="stylesheet" href="styl.css"> - plik napiszesz po HTML. Nazwa dokładnie jak w arkuszu: styl.css.

    Typowe błędy

    Literówka w nazwie pliku stylów odcina cały rezultat R.4 - „formatowanie CSS pochodzi jedynie z tego arkusza”.

    islandia.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Islandia</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (islandia.php)
  13. Krok 13: Bloki semantyczne

    Kryteria:

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

    ok. 2 min
    Polecenie z arkusza

    Podział strony na bloki: nagłówkowy, boczny, główny, stopki. Blok główny zawiera 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ą 4.

    Tabela 4 arkusza podsuwa nazwy: <header>, <aside> (treść obok głównej - blok boczny), <main> z <section> w środku, <footer>. Klucz R.2.3 wymienia dokładnie ten zestaw.

    Kolejność w kodzie ma znaczenie dla układu z ilustracji 4: blok boczny stoi po prawej na wysokość nagłówka i bloku głównego razem. Dlatego <aside> piszesz zaraz po <header> - przy układzie opływanym (float) blok, który ma zacząć się przy górnej krawędzi strony, musi pojawić się w kodzie przed blokiem głównym.

    islandia.php PHP zmienione: 10 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Islandia</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
        </header>
        <aside>
        </aside>
        <main>
            <section>
            </section>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (islandia.php)
  14. Krok 14: Nagłówek pierwszego stopnia będący odnośnikiem

    Kryteria: ,

    R.2.4 W bloku nagłówkowym znajduje się <h1>: "Zwiedzaj Islandię", w bloku bocznym <h3>: "Do zwiedzania" w bloku głównym <h2>: "Galeria" lub "Opis miejsca" oraz <p> z numerem zdającego w stopce

    R.3.3 Przynajmniej na jednej stronie kliknięcie odnośnika z bloku nagłówkowego prowadzi do strony islandia.php

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku nagłówkowego: Nagłówek pierwszego stopnia o treści „Zwiedzaj Islandię”. Treść jest odnośnikiem do strony islandia.php.

    Odnośnik jest wewnątrz nagłówka: <h1><a href="islandia.php">...</a></h1> - nagłówek zostaje nagłówkiem, a jego treść da się kliknąć. Na stronie obiekty.php ten sam nagłówek zaprowadzi z powrotem do galerii (klucz R.3.3).

    islandia.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Islandia</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1><a href="islandia.php">Zwiedzaj Islandię</a></h1>
        </header>
        <aside>
        </aside>
        <main>
            <section>
            </section>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (islandia.php)
  15. Krok 15: Blok boczny: nagłówek trzeciego stopnia

    Kryteria:

    R.2.4 W bloku nagłówkowym znajduje się <h1>: "Zwiedzaj Islandię", w bloku bocznym <h3>: "Do zwiedzania" w bloku głównym <h2>: "Galeria" lub "Opis miejsca" oraz <p> z numerem zdającego w stopce

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku bocznego: Nagłówek trzeciego stopnia o treści „Do zwiedzania”.

    <h3> - trzeciego stopnia, choć na stronie nie ma jeszcze <h2> (pojawi się w bloku głównym). Arkusz decyduje o stopniu nagłówka, nie kolejność na stronie.

    islandia.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Islandia</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1><a href="islandia.php">Zwiedzaj Islandię</a></h1>
        </header>
        <aside>
            <h3>Do zwiedzania</h3>
        </aside>
        <main>
            <section>
            </section>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (islandia.php)
  16. Krok 16: Lista punktowana z dwoma elementami

    Kryteria:

    R.2.5 W bloku bocznym znajduje się jedna lista punktowana z dwoma elementami „Wodospady:” i „Siedliska zwierząt:” (znaczniki <ul>, <li> )

    ok. 1 min
    Polecenie z arkusza

    Lista punktowana (nieuporządkowana) z dwoma elementami: „Wodospady:” i „Siedliska zwierząt:”.

    Punktowana = <ul>, dwa elementy <li>. Znacznik zamykający </li> piszesz w osobnej linii, bo za chwilę w środku każdego elementu zagnieździsz drugą listę.

    islandia.php PHP zmienione: 6 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Islandia</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1><a href="islandia.php">Zwiedzaj Islandię</a></h1>
        </header>
        <aside>
            <h3>Do zwiedzania</h3>
            <ul>
                <li>Wodospady:
                </li>
                <li>Siedliska zwierząt:
                </li>
            </ul>
        </aside>
        <main>
            <section>
            </section>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (islandia.php)
  17. Krok 17: Zagnieżdżone listy numerowane

    Kryteria:

    R.2.6 Przynajmniej jeden element listy zawiera zagnieżdżoną jedną listę numerowaną (w skrypcie lub HTML, znaczniki <ol> i <li>, znacznik <ol> zawarto wewnątrz <li> listy z R.2.5)

    ok. 2 min
    Polecenie z arkusza

    Element „Wodospady:” zawiera listę numerowaną (uporządkowaną) wypełnioną skryptem 1. Element „Siedliska zwierząt:” zawiera listę numerowaną (uporządkowaną) wypełnioną skryptem 2.

    Lista zagnieżdżona to cała lista wewnątrz elementu <li> - <ol> stoi między tekstem „Wodospady:” a </li>. Numerowana = <ol>. Na razie listy są puste; elementy <li> dopiszą skrypty 1 i 2 (klucz R.2.6 przyjmuje <ol> w HTML albo w skrypcie).

    Typowe błędy

    <ol> między </li> a kolejnym <li> (zamiast wewnątrz elementu) to niepoprawny HTML - lista nie jest wtedy zagnieżdżona w elemencie, a klucz R.2.6 wymaga <ol> wewnątrz <li>.

    islandia.php PHP zmienione: 4 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Islandia</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1><a href="islandia.php">Zwiedzaj Islandię</a></h1>
        </header>
        <aside>
            <h3>Do zwiedzania</h3>
            <ul>
                <li>Wodospady:
                    <ol>
                    </ol>
                </li>
                <li>Siedliska zwierząt:
                    <ol>
                    </ol>
                </li>
            </ul>
        </aside>
        <main>
            <section>
            </section>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (islandia.php)
  18. Krok 18: Blok główny: nagłówek „Galeria” i blok sekcji

    Kryteria:

    R.2.4 W bloku nagłówkowym znajduje się <h1>: "Zwiedzaj Islandię", w bloku bocznym <h3>: "Do zwiedzania" w bloku głównym <h2>: "Galeria" lub "Opis miejsca" oraz <p> z numerem zdającego w stopce

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku głównego dla strony islandia.php: Nagłówek drugiego stopnia o treści: „Galeria”. Blok sekcji z efektem wykonania skryptu 3.

    <h2> przed <section> - sekcja jest na galerię, którą wypisze skrypt 3. Nagłówek stoi poza ramką sekcji, jak na ilustracji 2.

    islandia.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Islandia</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1><a href="islandia.php">Zwiedzaj Islandię</a></h1>
        </header>
        <aside>
            <h3>Do zwiedzania</h3>
            <ul>
                <li>Wodospady:
                    <ol>
                    </ol>
                </li>
                <li>Siedliska zwierząt:
                    <ol>
                    </ol>
                </li>
            </ul>
        </aside>
        <main>
            <h2>Galeria</h2>
            <section>
            </section>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (islandia.php)
  19. Krok 19: Stopka: linia pozioma i autor

    Kryteria: ,

    R.2.4 W bloku nagłówkowym znajduje się <h1>: "Zwiedzaj Islandię", w bloku bocznym <h3>: "Do zwiedzania" w bloku głównym <h2>: "Galeria" lub "Opis miejsca" oraz <p> z numerem zdającego w stopce

    R.2.9 Stopka zawiera linię poziomą (<hr> lub za pomocą obramowania w CSS )

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku stopki: Linia pozioma. Paragraf o treści „Autor: ”, dalej wstawiony numer zdającego.

    <hr> to linia pozioma (element pusty - bez znacznika zamykającego i bez ukośnika w HTML5), pod nią paragraf. W tym rozwiązaniu po „Autor:” stoi nazwisko autora - na egzaminie wpisujesz swój numer zdającego (PESEL).

    islandia.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Islandia</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1><a href="islandia.php">Zwiedzaj Islandię</a></h1>
        </header>
        <aside>
            <h3>Do zwiedzania</h3>
            <ul>
                <li>Wodospady:
                    <ol>
                    </ol>
                </li>
                <li>Siedliska zwierząt:
                    <ol>
                    </ol>
                </li>
            </ul>
        </aside>
        <main>
            <h2>Galeria</h2>
            <section>
            </section>
        </main>
        <footer>
            <hr>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (islandia.php)
  20. Krok 20: Strona obiekty.php z kopii

    Kryteria:

    R.2.8 Na stronie obiekty.php w bloku głównym lub bloku sekcji znajdują się elementy <h2>, <h3> i przynajmniej jeden <p> (w skrypcie lub HTML )

    ok. 2 min
    Polecenie z arkusza

    Zawartość bloku głównego dla strony obiekty.php: Nagłówek drugiego stopnia o treści: „Opis miejsca”. Blok sekcji z efektem działania skryptu 4.

    Wszystkie cechy wspólne są już w islandia.php, więc zapisujesz ją jako obiekty.php (Zapisz jako) i zmieniasz jedną linię: nagłówek bloku głównego to „Opis miejsca”. Sekcję wypełni skrypt 4, a nagłówek strony, blok boczny i stopka zostają takie same - obie strony wyglądają jak jedna witryna.

    obiekty.php PHP nowy plik
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Islandia</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1><a href="islandia.php">Zwiedzaj Islandię</a></h1>
        </header>
        <aside>
            <h3>Do zwiedzania</h3>
            <ul>
                <li>Wodospady:
                    <ol>
                    </ol>
                </li>
                <li>Siedliska zwierząt:
                    <ol>
                    </ol>
                </li>
            </ul>
        </aside>
        <main>
            <h2>Opis miejsca</h2>
            <section>
            </section>
        </main>
        <footer>
            <hr>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (obiekty.php)
  21. Etap 3: Styl CSS

    Kroki 21-30 · po tym etapie masz 27 z 37 kryteriów (pkt)

    Krok 21: Plik styl.css: krój czcionki

    Kryteria:

    R.4.1 domyślne formatowanie selektorów (*): krój czcionki "Comic Sans MS" - jako pierwszy, sans-serif - jako ostatni

    ok. 1 min
    Polecenie z arkusza

    Domyślnie, dla wszystkich selektorów: krój czcionki Comic Sans MS, w przypadku braku sans-serif.

    Utwórz styl.css. Selektor * obejmuje każdy element. Nazwa kroju ma spacje, więc bierzesz ją w cudzysłów: "Comic Sans MS"; po przecinku rodzina zastępcza sans-serif - przeglądarka użyje dowolnego kroju bezszeryfowego, gdy Comic Sans nie ma w systemie (klucz R.4.1: Comic Sans pierwszy, sans-serif ostatni).

    styl.css CSS nowy plik
    * {
        font-family: "Comic Sans MS", sans-serif;
    }
    Podgląd strony po tym kroku (islandia.php)
  22. Krok 22: Nagłówek i blok główny: szerokość i wyśrodkowanie

    Kryteria: ,

    R.4.3 szerokość: blok nagłówkowy, główny - 70%, boczny - 25% (width lub grid-template- columns lub flex ) wysokość: blok nagłówkowy - 100px, boczny - 700px, sekcja - 400px

    R.4.5 wyrównanie tekstu: blok nagłówkowy, główny - do środka

    ok. 1 min
    Polecenie z arkusza

    Dla bloku nagłówkowego i głównego: szerokość 70%, wyrównanie tekstu do środka.

    Wspólne cechy dwóch bloków piszesz raz: selektory po przecinku (header, main) dostają tę samą regułę. Procent liczy się od szerokości okna, więc układ dopasuje się do ekranu.

    styl.css CSS zmienione: 4 linie
    * {
        font-family: "Comic Sans MS", sans-serif;
    }
    header, main {
        width: 70%;
        text-align: center;
    }
    Podgląd strony po tym kroku (islandia.php)
  23. Krok 23: Nagłówek i blok boczny: tło i zaokrąglenie

    Kryteria: ,

    R.4.2 kolor tła: blok nagłówkowy i boczny - PaleTurquoise

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

    ok. 1 min
    Polecenie z arkusza

    Dla bloku nagłówkowego i bocznego: kolor tła PaleTurquoise, zaokrąglenie rogów 20 px.

    background-color przyjmuje nazwę koloru z arkusza wprost (PaleTurquoise, wielkość liter bez znaczenia), a border-radius: 20px zaokrągla wszystkie cztery rogi.

    styl.css CSS zmienione: 4 linie
    * {
        font-family: "Comic Sans MS", sans-serif;
    }
    header, main {
        width: 70%;
        text-align: center;
    }
    header, aside {
        background-color: PaleTurquoise;
        border-radius: 20px;
    }
    Podgląd strony po tym kroku (islandia.php)
  24. Krok 24: Nagłówek: wysokość i marginesy wewnętrzne

    Kryteria: ,

    R.4.3 szerokość: blok nagłówkowy, główny - 70%, boczny - 25% (width lub grid-template- columns lub flex ) wysokość: blok nagłówkowy - 100px, boczny - 700px, sekcja - 400px

    R.4.4 marginesy wewnętrzne (padding ): blok nagłówkowy - 2%, stopka jedynie padding-top: 10px; marginesy zewnętrzne (margin ): sekcja - górny i dolny - 10px, pozostałe - 50px

    ok. 1 min
    Polecenie z arkusza

    Dodatkowo dla bloku nagłówkowego: wysokość 100 px, marginesy wewnętrzne 2%.

    „Dodatkowo” - druga reguła dla header, uzupełniająca tę wspólną. Margines wewnętrzny to padding; procent liczy się od szerokości rodzica, także w pionie.

    styl.css CSS zmienione: 4 linie
    * {
        font-family: "Comic Sans MS", sans-serif;
    }
    header, main {
        width: 70%;
        text-align: center;
    }
    header, aside {
        background-color: PaleTurquoise;
        border-radius: 20px;
    }
    header {
        height: 100px;
        padding: 2%;
    }
    Podgląd strony po tym kroku (islandia.php)
  25. Krok 25: Blok boczny: wymiary i interlinia

    Kryteria: ,

    R.4.3 szerokość: blok nagłówkowy, główny - 70%, boczny - 25% (width lub grid-template- columns lub flex ) wysokość: blok nagłówkowy - 100px, boczny - 700px, sekcja - 400px

    R.4.8 wysokość linii (line-hight) : blok boczny - 2

    ok. 1 min
    Polecenie z arkusza

    Dodatkowo dla bloku bocznego: szerokość 25%, wysokość 700 px, wysokość linii (interlinia) 2.

    line-height: 2 bez jednostki to dwukrotność rozmiaru czcionki - podwójna interlinia, dzięki której lista w bloku bocznym jest luźna, jak na ilustracji 2.

    styl.css CSS zmienione: 5 linii
    * {
        font-family: "Comic Sans MS", sans-serif;
    }
    header, main {
        width: 70%;
        text-align: center;
    }
    header, aside {
        background-color: PaleTurquoise;
        border-radius: 20px;
    }
    header {
        height: 100px;
        padding: 2%;
    }
    aside {
        width: 25%;
        height: 700px;
        line-height: 2;
    }
    Podgląd strony po tym kroku (islandia.php)
  26. Krok 26: Stopka: margines wewnętrzny górny

    Kryteria:

    R.4.4 marginesy wewnętrzne (padding ): blok nagłówkowy - 2%, stopka jedynie padding-top: 10px; marginesy zewnętrzne (margin ): sekcja - górny i dolny - 10px, pozostałe - 50px

    ok. 1 min
    Polecenie z arkusza

    Dla bloku stopki: jedynie margines wewnętrzny górny 10 px.

    „Jedynie” - tylko padding-top, żadnych innych właściwości dla stopki (klucz R.4.4 sprawdza właśnie padding-top: 10px).

    styl.css CSS zmienione: 3 linie
    * {
        font-family: "Comic Sans MS", sans-serif;
    }
    header, main {
        width: 70%;
        text-align: center;
    }
    header, aside {
        background-color: PaleTurquoise;
        border-radius: 20px;
    }
    header {
        height: 100px;
        padding: 2%;
    }
    aside {
        width: 25%;
        height: 700px;
        line-height: 2;
    }
    footer {
        padding-top: 10px;
    }
    Podgląd strony po tym kroku (islandia.php)
  27. Krok 27: Blok sekcji: ramka, marginesy, wysokość, przewijanie

    Kryteria: , ,

    R.4.3 szerokość: blok nagłówkowy, główny - 70%, boczny - 25% (width lub grid-template- columns lub flex ) wysokość: blok nagłówkowy - 100px, boczny - 700px, sekcja - 400px

    R.4.4 marginesy wewnętrzne (padding ): blok nagłówkowy - 2%, stopka jedynie padding-top: 10px; marginesy zewnętrzne (margin ): sekcja - górny i dolny - 10px, pozostałe - 50px

    R.4.6 cechy sekcji: obramowanie 1px dashed DimGray, paski przewijania (overflow) auto

    ok. 2 min
    Polecenie z arkusza

    Dla bloku sekcji: obramowanie linią kreskową o szerokości 1 px i kolorze DimGray, marginesy zewnętrzne górny i dolny 10 px, pozostałe 50 px, wysokość 400 px, paski przewijania pojawiające się tylko w przypadku przepełnienia bloku.

    • border: 1px dashed DimGray - grubość, styl linii (kreskowa to dashed, kropkowa byłaby dotted) i kolor w jednej właściwości.
    • margin: 10px 50px - dwie wartości: pierwsza dla góry i dołu, druga dla lewej i prawej.
    • overflow: auto - paski przewijania tylko gdy treść się nie mieści (scroll pokazywałby je zawsze). Galeria ma 9 zdjęć po 200 px wysokości, więc w sekcji 400 px pojawi się pasek, jak na ilustracji 2.
    styl.css CSS zmienione: 6 linii
    * {
        font-family: "Comic Sans MS", sans-serif;
    }
    header, main {
        width: 70%;
        text-align: center;
    }
    header, aside {
        background-color: PaleTurquoise;
        border-radius: 20px;
    }
    header {
        height: 100px;
        padding: 2%;
    }
    aside {
        width: 25%;
        height: 700px;
        line-height: 2;
    }
    footer {
        padding-top: 10px;
    }
    section {
        border: 1px dashed DimGray;
        margin: 10px 50px;
        height: 400px;
        overflow: auto;
    }
    Podgląd strony po tym kroku (islandia.php)
  28. Krok 28: Klasa miniatury: wysokość, przezroczystość, tranzycja

    Kryteria:

    R.4.9 styl klasy .miniatury : wysokość - 200px, padding: 10px, przezroczystość (opacity) - 0.8, tranzycja trwająca 1s (transition lub transition-duration)

    ok. 2 min
    Polecenie z arkusza

    Dla klasy miniatury przypisanej do obrazów ze strony islandia.php, generowanych skryptem 3: wysokość 200 px, marginesy wewnętrzne 10 px, przezroczystość 0.8, dodana tranzycja trwająca 1 sekundę.

    Selektor klasy zaczyna się kropką: .miniatury. Podaj tylko wysokość - szerokość dopasuje się do proporcji zdjęcia. opacity: 0.8 to 80% krycia. transition: 1s (tabela 3 arkusza: wystarczy sam czas trwania) sprawia, że zmiana przezroczystości po najechaniu kursorem nie przeskoczy, tylko płynnie potrwa sekundę. Klasy nie ma jeszcze w HTML - przypisze ją skrypt 3 (klucz pozwala sprawdzić taką regułę w kodzie CSS).

    styl.css CSS zmienione: 6 linii
    * {
        font-family: "Comic Sans MS", sans-serif;
    }
    header, main {
        width: 70%;
        text-align: center;
    }
    header, aside {
        background-color: PaleTurquoise;
        border-radius: 20px;
    }
    header {
        height: 100px;
        padding: 2%;
    }
    aside {
        width: 25%;
        height: 700px;
        line-height: 2;
    }
    footer {
        padding-top: 10px;
    }
    section {
        border: 1px dashed DimGray;
        margin: 10px 50px;
        height: 400px;
        overflow: auto;
    }
    .miniatury {
        height: 200px;
        padding: 10px;
        opacity: 0.8;
        transition: 1s;
    }
    Podgląd strony po tym kroku (islandia.php)
  29. Krok 29: Miniatura pod kursorem: pełne krycie

    Kryteria:

    R.4.10 gdy kursor znajdzie się na elemencie z przypisaną klasą .miniatury , jego przezroczystość (opacity) zmienia się na wartość 1

    ok. 1 min
    Polecenie z arkusza

    W przypadku gdy kursor znajdzie się na elemencie z przypisaną klasą miniatury, jego przezroczystość zmienia się na wartość 1.

    Pseudoklasa :hover - stan „kursor nad elementem”. Ustaw tylko to, co się zmienia: opacity: 1. Tranzycja z poprzedniej reguły zadziała w obie strony - przy najechaniu i przy zjechaniu kursorem.

    styl.css CSS zmienione: 3 linie
    * {
        font-family: "Comic Sans MS", sans-serif;
    }
    header, main {
        width: 70%;
        text-align: center;
    }
    header, aside {
        background-color: PaleTurquoise;
        border-radius: 20px;
    }
    header {
        height: 100px;
        padding: 2%;
    }
    aside {
        width: 25%;
        height: 700px;
        line-height: 2;
    }
    footer {
        padding-top: 10px;
    }
    section {
        border: 1px dashed DimGray;
        margin: 10px 50px;
        height: 400px;
        overflow: auto;
    }
    .miniatury {
        height: 200px;
        padding: 10px;
        opacity: 0.8;
        transition: 1s;
    }
    .miniatury:hover {
        opacity: 1;
    }
    Podgląd strony po tym kroku (islandia.php)
  30. Krok 30: Układ bloków zgodny z ilustracją 4

    Kryteria:

    R.3.1 Układ bloków po uruchomieniu strony w przeglądarce jest zgodny z ilustracją 4 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. 3 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ą 4.

    Arkusz nie podaje właściwości układu - wybierasz float, bo trzy linie wystarczą:

    • header, main { float: left; } - nagłówek staje przy lewej krawędzi, blok główny też, a ponieważ obok nagłówka nie ma już miejsca, ląduje pod nim.
    • aside { float: right; } - blok boczny przy prawej krawędzi, od samej góry (stąd jego miejsce w kodzie przed <main>).
    • footer { clear: both; } - stopka nie opływa żadnego bloku, tylko schodzi pod najniższy z nich (blok boczny ma 700 px).

    Szerokości się mieszczą: nagłówek ma 70% plus 2 × 2% marginesu wewnętrznego, czyli 74%, do tego 25% bloku bocznego - razem 99%. Układ odpowiada ilustracji 4 (klucz R.3.1).

    Typowe błędy

    Bez clear: both stopka wsunie się pod pływające bloki, a linia pozioma przetnie stronę na wysokości nagłówka.

    styl.css CSS zmienione: 3 linie
    * {
        font-family: "Comic Sans MS", sans-serif;
    }
    header, main {
        float: left;
        width: 70%;
        text-align: center;
    }
    header, aside {
        background-color: PaleTurquoise;
        border-radius: 20px;
    }
    header {
        height: 100px;
        padding: 2%;
    }
    aside {
        float: right;
        width: 25%;
        height: 700px;
        line-height: 2;
    }
    footer {
        clear: both;
        padding-top: 10px;
    }
    section {
        border: 1px dashed DimGray;
        margin: 10px 50px;
        height: 400px;
        overflow: auto;
    }
    .miniatury {
        height: 200px;
        padding: 10px;
        opacity: 0.8;
        transition: 1s;
    }
    .miniatury:hover {
        opacity: 1;
    }
    Podgląd strony po tym kroku (islandia.php)
  31. Etap 4: Skrypty PHP

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

    Krok 31: Połączenie z bazą na obu stronach

    Kryteria: ,

    R.5.1 Skrypt realizuje połączenie z serwerem bazy danych i wybór bazy islandia oraz ostatnią operacją na bazie jest jej zamknięcie (wystarczy na jednej stronie )

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

    ok. 3 min
    Polecenie z arkusza

    Wymagania dotyczące skryptów: Napisane w języku PHP. Łączą się z serwerem bazodanowym na localhost, użytkownik root bez hasła, baza danych o nazwie islandia.

    Kod PHP stoi między <?php a ?> i wykonuje się na serwerze, zanim strona trafi do przeglądarki. Połączenie otwierasz raz, zaraz po <body>, i trzymasz w zmiennej $connection - korzystają z niego wszystkie skrypty strony. mysqli_connect z tabeli 1 przyjmuje kolejno: serwer, użytkownika, hasło (puste) i nazwę bazy. Ten sam blok wstawiasz w obu plikach - każda strona to osobne żądanie do serwera i potrzebuje własnego połączenia.

    Od tego kroku podgląd to wynik działania strony po stronie serwera.

    Typowe błędy

    mysqli_connect('localhost', 'root', 'islandia') podaje „islandia” jako HASŁO - nazwa bazy jest czwartym argumentem. Stronę otwierasz przez http://localhost/…, nie z dysku.

    islandia.php PHP zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Islandia</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'islandia');
    ?>
        <header>
            <h1><a href="islandia.php">Zwiedzaj Islandię</a></h1>
        </header>
        <aside>
            <h3>Do zwiedzania</h3>
            <ul>
                <li>Wodospady:
                    <ol>
                    </ol>
                </li>
                <li>Siedliska zwierząt:
                    <ol>
                    </ol>
                </li>
            </ul>
        </aside>
        <main>
            <h2>Galeria</h2>
            <section>
            </section>
        </main>
        <footer>
            <hr>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    obiekty.php PHP zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Islandia</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'islandia');
    ?>
        <header>
            <h1><a href="islandia.php">Zwiedzaj Islandię</a></h1>
        </header>
        <aside>
            <h3>Do zwiedzania</h3>
            <ul>
                <li>Wodospady:
                    <ol>
                    </ol>
                </li>
                <li>Siedliska zwierząt:
                    <ol>
                    </ol>
                </li>
            </ul>
        </aside>
        <main>
            <h2>Opis miejsca</h2>
            <section>
            </section>
        </main>
        <footer>
            <hr>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (islandia.php)
  32. Krok 32: Skrypt 1: zapytanie 3 do bazy

    Kryteria:

    R.5.3 Skrypty zawierają przynajmniej jedną instrukcję wysyłającą zapytanie do bazy danych: skrypt 2 zmodyfikowane zapytanie 3 - idRodzaj = 14 skrypt 1 zapytanie 3 skrypt 3 - zapytanie 1 skrypt 4 - zmodyfikowane zapytanie 2 - id pobrane z tablicy $_GET

    ok. 2 min
    Polecenie z arkusza

    Skrypt 1 na obu stronach: Wysyła do bazy danych zapytanie 3.

    Skrypt 1 piszesz wewnątrz <ol> przy „Wodospady:” - tam ma trafić jego wynik. mysqli_query($connection, ...) wysyła zapytanie i zwraca wynik, który zapisujesz w zmiennej $waterfalls (wodospady). Treść to zapytanie 3 z kwerendy.txt. Zapytanie zawiera cudzysłowy, więc cały napis w PHP bierzesz w apostrofy.

    islandia.php PHP zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Islandia</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'islandia');
    ?>
        <header>
            <h1><a href="islandia.php">Zwiedzaj Islandię</a></h1>
        </header>
        <aside>
            <h3>Do zwiedzania</h3>
            <ul>
                <li>Wodospady:
                    <ol>
    <?php
    $waterfalls = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 10;');
    ?>
                    </ol>
                </li>
                <li>Siedliska zwierząt:
                    <ol>
                    </ol>
                </li>
            </ul>
        </aside>
        <main>
            <h2>Galeria</h2>
            <section>
            </section>
        </main>
        <footer>
            <hr>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>

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

  33. Krok 33: Skrypt 1: nazwy jako elementy listy

    Kryteria:

    R.5.4 Skrypt 1 lub skrypt 2 wyświetla wszystkie zwrócone zapytaniem nazwy jako elementy listy

    ok. 2 min
    Polecenie z arkusza

    Każda zwrócona zapytaniem nazwa jest wyświetlana jako element listy.

    Pętla while z mysqli_fetch_row($waterfalls) (tabela 1) bierze kolejne wiersze jako tablice liczone od zera; gdy wierszy zabraknie, funkcja zwraca false i pętla się kończy. Zapytanie wybiera jedną kolumnę, więc nazwa to $row[0], a echo wypisuje ją w <li>. W podglądzie lista numerowana wypełnia się czterema wodospadami (klucz R.5.4).

    islandia.php PHP zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Islandia</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'islandia');
    ?>
        <header>
            <h1><a href="islandia.php">Zwiedzaj Islandię</a></h1>
        </header>
        <aside>
            <h3>Do zwiedzania</h3>
            <ul>
                <li>Wodospady:
                    <ol>
    <?php
    $waterfalls = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 10;');
    while ($row = mysqli_fetch_row($waterfalls)) {
        echo "<li>$row[0]</li>";
    }
    ?>
                    </ol>
                </li>
                <li>Siedliska zwierząt:
                    <ol>
                    </ol>
                </li>
            </ul>
        </aside>
        <main>
            <h2>Galeria</h2>
            <section>
            </section>
        </main>
        <footer>
            <hr>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (islandia.php)
  34. Krok 34: Skrypt 2: siedliska zwierząt

    Kryteria: ,

    R.5.3 Skrypty zawierają przynajmniej jedną instrukcję wysyłającą zapytanie do bazy danych: skrypt 2 zmodyfikowane zapytanie 3 - idRodzaj = 14 skrypt 1 zapytanie 3 skrypt 3 - zapytanie 1 skrypt 4 - zmodyfikowane zapytanie 2 - id pobrane z tablicy $_GET

    R.5.4 Skrypt 1 lub skrypt 2 wyświetla wszystkie zwrócone zapytaniem nazwy jako elementy listy

    ok. 2 min
    Polecenie z arkusza

    Skrypt 2 na obu stronach: Wysyła do bazy danych zapytanie 3, zmodyfikowane tak, że w warunku sprawdzane jest pole idRodzaj równe 14. Każda zwrócona zapytaniem nazwa jest wyświetlana jako element listy.

    Skopiuj skrypt 1 do drugiej <ol> i zmień dwie rzeczy: w zapytaniu idRodzaj = 14 (siedlisko zwierząt) i nazwę zmiennej na $habitats - nazwa ma mówić, co jest w środku. Wynik: dwa siedliska, w tym „Fuglaskoðunarhús” z islandzką literą ð.

    islandia.php PHP zmienione: 6 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Islandia</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'islandia');
    ?>
        <header>
            <h1><a href="islandia.php">Zwiedzaj Islandię</a></h1>
        </header>
        <aside>
            <h3>Do zwiedzania</h3>
            <ul>
                <li>Wodospady:
                    <ol>
    <?php
    $waterfalls = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 10;');
    while ($row = mysqli_fetch_row($waterfalls)) {
        echo "<li>$row[0]</li>";
    }
    ?>
                    </ol>
                </li>
                <li>Siedliska zwierząt:
                    <ol>
    <?php
    $habitats = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 14;');
    while ($row = mysqli_fetch_row($habitats)) {
        echo "<li>$row[0]</li>";
    }
    ?>
                    </ol>
                </li>
            </ul>
        </aside>
        <main>
            <h2>Galeria</h2>
            <section>
            </section>
        </main>
        <footer>
            <hr>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (islandia.php)
  35. Krok 35: Skrypty 1 i 2 również na stronie obiekty.php

    Kryteria:

    R.5.4 Skrypt 1 lub skrypt 2 wyświetla wszystkie zwrócone zapytaniem nazwy jako elementy listy

    ok. 2 min
    Polecenie z arkusza

    Skrypt 1 na obu stronach. Skrypt 2 na obu stronach.

    „Na obu stronach” - kopiujesz oba skrypty w te same miejsca w obiekty.php. Blok boczny wygląda teraz identycznie na obu stronach. (W etapie „Dobre praktyki” wyniesiesz go do jednego pliku, żeby nie trzymać dwóch kopii.)

    obiekty.php PHP zmienione: 12 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Islandia</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'islandia');
    ?>
        <header>
            <h1><a href="islandia.php">Zwiedzaj Islandię</a></h1>
        </header>
        <aside>
            <h3>Do zwiedzania</h3>
            <ul>
                <li>Wodospady:
                    <ol>
    <?php
    $waterfalls = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 10;');
    while ($row = mysqli_fetch_row($waterfalls)) {
        echo "<li>$row[0]</li>";
    }
    ?>
                    </ol>
                </li>
                <li>Siedliska zwierząt:
                    <ol>
    <?php
    $habitats = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 14;');
    while ($row = mysqli_fetch_row($habitats)) {
        echo "<li>$row[0]</li>";
    }
    ?>
                    </ol>
                </li>
            </ul>
        </aside>
        <main>
            <h2>Opis miejsca</h2>
            <section>
            </section>
        </main>
        <footer>
            <hr>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (obiekty.php)
  36. Krok 36: Skrypt 3: zapytanie 1 do bazy

    Kryteria:

    R.5.3 Skrypty zawierają przynajmniej jedną instrukcję wysyłającą zapytanie do bazy danych: skrypt 2 zmodyfikowane zapytanie 3 - idRodzaj = 14 skrypt 1 zapytanie 3 skrypt 3 - zapytanie 1 skrypt 4 - zmodyfikowane zapytanie 2 - id pobrane z tablicy $_GET

    ok. 1 min
    Polecenie z arkusza

    Skrypt 3 na stronie islandia.php: Wysyła do bazy danych zapytanie 1.

    Wróć do islandia.php. Skrypt 3 stoi w <section> bloku głównego. Zapytanie 1 zwraca identyfikator, plik i nazwę dziewięciu obiektów - wynik zapisujesz w $objects.

    islandia.php PHP zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Islandia</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'islandia');
    ?>
        <header>
            <h1><a href="islandia.php">Zwiedzaj Islandię</a></h1>
        </header>
        <aside>
            <h3>Do zwiedzania</h3>
            <ul>
                <li>Wodospady:
                    <ol>
    <?php
    $waterfalls = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 10;');
    while ($row = mysqli_fetch_row($waterfalls)) {
        echo "<li>$row[0]</li>";
    }
    ?>
                    </ol>
                </li>
                <li>Siedliska zwierząt:
                    <ol>
    <?php
    $habitats = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 14;');
    while ($row = mysqli_fetch_row($habitats)) {
        echo "<li>$row[0]</li>";
    }
    ?>
                    </ol>
                </li>
            </ul>
        </aside>
        <main>
            <h2>Galeria</h2>
            <section>
    <?php
    $objects = mysqli_query($connection, 'SELECT idObiekt, plik, nazwa FROM obiekty WHERE panstwo = "Islandia";');
    ?>
            </section>
        </main>
        <footer>
            <hr>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (islandia.php)
  37. Krok 37: Skrypt 3: obraz z każdego wiersza

    Kryteria: ,

    R.5.6 Skrypt 3 dla każdego zwróconego zapytaniem wiersza wyświetla obraz, którego źródłem jest zwrócone pole plik

    R.2.7 W bloku głównym lub bloku sekcji znajduje się przynajmniej jeden obraz wraz z tekstem alternatywnym (w skrypcie lub HTML )

    ok. 3 min
    Polecenie z arkusza

    Odnośnik jest obrazem, dla którego źródło to zwrócone pole plik, tekst alternatywny to zwrócone pole nazwa.

    Dla każdego wiersza <img>: źródło $row[1] (pole plik, np. Strokkur.jpg - zdjęcia leżą obok strony), tekst alternatywny $row[2] (pole nazwa). W napisie w cudzysłowie atrybuty HTML też potrzebują cudzysłowów - poprzedzasz je ukośnikiem \", żeby nie zakończyły napisu PHP. Galeria pokazuje zdjęcia w naturalnym rozmiarze - zmniejszy je klasa z CSS.

    Typowe błędy

    echo "<img src="$row[1]">"; bez ukośników kończy napis na drugim cudzysłowie - PHP zgłosi błąd składni i cała strona przestanie działać.

    islandia.php PHP zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Islandia</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'islandia');
    ?>
        <header>
            <h1><a href="islandia.php">Zwiedzaj Islandię</a></h1>
        </header>
        <aside>
            <h3>Do zwiedzania</h3>
            <ul>
                <li>Wodospady:
                    <ol>
    <?php
    $waterfalls = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 10;');
    while ($row = mysqli_fetch_row($waterfalls)) {
        echo "<li>$row[0]</li>";
    }
    ?>
                    </ol>
                </li>
                <li>Siedliska zwierząt:
                    <ol>
    <?php
    $habitats = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 14;');
    while ($row = mysqli_fetch_row($habitats)) {
        echo "<li>$row[0]</li>";
    }
    ?>
                    </ol>
                </li>
            </ul>
        </aside>
        <main>
            <h2>Galeria</h2>
            <section>
    <?php
    $objects = mysqli_query($connection, 'SELECT idObiekt, plik, nazwa FROM obiekty WHERE panstwo = "Islandia";');
    while ($row = mysqli_fetch_row($objects)) {
        echo "<img src=\"$row[1]\" alt=\"$row[2]\">";
    }
    ?>
            </section>
        </main>
        <footer>
            <hr>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (islandia.php)
  38. Krok 38: Skrypt 3: dymek z nazwą i klasa miniatury

    Kryteria:

    R.3.5 Przynajmniej jeden obraz ze strony islandia.php ma przypisaną klasę miniatury oraz atrybut title

    ok. 2 min
    Polecenie z arkusza

    Dodatkowo pole nazwa jest tekstem pojawiającym się w postaci dymka, gdy kursor znajdzie się na obrazie (ilustracja 2, czwarty obraz). Obraz ma przypisaną klasę miniatury.

    Dymek po najechaniu kursorem to atrybut title - ta sama nazwa co w alt. class="miniatury" podpina regułę z styl.css: zdjęcia mają po 200 px wysokości, lekko prześwitują, a po najechaniu kursorem płynnie nabierają pełnego koloru. Najedź na zdjęcie w podglądzie (klucz R.3.5).

    islandia.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Islandia</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'islandia');
    ?>
        <header>
            <h1><a href="islandia.php">Zwiedzaj Islandię</a></h1>
        </header>
        <aside>
            <h3>Do zwiedzania</h3>
            <ul>
                <li>Wodospady:
                    <ol>
    <?php
    $waterfalls = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 10;');
    while ($row = mysqli_fetch_row($waterfalls)) {
        echo "<li>$row[0]</li>";
    }
    ?>
                    </ol>
                </li>
                <li>Siedliska zwierząt:
                    <ol>
    <?php
    $habitats = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 14;');
    while ($row = mysqli_fetch_row($habitats)) {
        echo "<li>$row[0]</li>";
    }
    ?>
                    </ol>
                </li>
            </ul>
        </aside>
        <main>
            <h2>Galeria</h2>
            <section>
    <?php
    $objects = mysqli_query($connection, 'SELECT idObiekt, plik, nazwa FROM obiekty WHERE panstwo = "Islandia";');
    while ($row = mysqli_fetch_row($objects)) {
        echo "<img src=\"$row[1]\" alt=\"$row[2]\" title=\"$row[2]\" class=\"miniatury\">";
    }
    ?>
            </section>
        </main>
        <footer>
            <hr>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (islandia.php)
  39. Krok 39: Skrypt 3: odnośnik z parametrem GET

    Kryteria: ,

    R.3.4 Na stronie islandia.php umieszczono przynajmniej jeden odnośnik, którego kliknięcie powoduje otwarcie strony obiekty.php oraz zostaje wysłane żądanie metodą GET z jednym parametrem

    R.5.5 Skrypt 3 dla każdego zwróconego zapytaniem wiersza wstawia idObiekt jako wartość parametru przesłanego metodą GET

    ok. 3 min
    Polecenie z arkusza

    Dla każdego zwróconego zapytaniem wiersza wypisuje odnośnik prowadzący do strony obiekty.php oraz przekazujący do tej strony metodą GET parametr o wartości równej polu idObiekt.

    Obraz otaczasz odnośnikiem <a href="obiekty.php?id=...">. Parametr GET to część adresu po znaku zapytania (tabela 2 arkusza): id=46 dla Strokkura, id=53 dla Godafossu - wartość to $row[0], czyli pole idObiekt. Nazwę parametru (id) wybierasz sam; ważne, by skrypt 4 odczytał ją pod tą samą nazwą (klucz R.3.4, R.5.5). W podglądzie kliknięcia są zablokowane - po kliknięciu na egzaminie przeglądarka otworzy np. obiekty.php?id=53.

    islandia.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Islandia</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'islandia');
    ?>
        <header>
            <h1><a href="islandia.php">Zwiedzaj Islandię</a></h1>
        </header>
        <aside>
            <h3>Do zwiedzania</h3>
            <ul>
                <li>Wodospady:
                    <ol>
    <?php
    $waterfalls = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 10;');
    while ($row = mysqli_fetch_row($waterfalls)) {
        echo "<li>$row[0]</li>";
    }
    ?>
                    </ol>
                </li>
                <li>Siedliska zwierząt:
                    <ol>
    <?php
    $habitats = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 14;');
    while ($row = mysqli_fetch_row($habitats)) {
        echo "<li>$row[0]</li>";
    }
    ?>
                    </ol>
                </li>
            </ul>
        </aside>
        <main>
            <h2>Galeria</h2>
            <section>
    <?php
    $objects = mysqli_query($connection, 'SELECT idObiekt, plik, nazwa FROM obiekty WHERE panstwo = "Islandia";');
    while ($row = mysqli_fetch_row($objects)) {
        echo "<a href=\"obiekty.php?id=$row[0]\"><img src=\"$row[1]\" alt=\"$row[2]\" title=\"$row[2]\" class=\"miniatury\"></a>";
    }
    ?>
            </section>
        </main>
        <footer>
            <hr>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (islandia.php)
  40. Krok 40: Zamknięcie połączenia na stronie islandia.php

    Kryteria:

    R.5.1 Skrypt realizuje połączenie z serwerem bazy danych i wybór bazy islandia oraz ostatnią operacją na bazie jest jej zamknięcie (wystarczy na jednej stronie )

    ok. 1 min
    Polecenie z arkusza

    Na końcu należy zamknąć połączenie z bazą.

    mysqli_close($connection) po stopce, jako ostatnia operacja na bazie - po wszystkich trzech skryptach strony (klucz R.5.1). Strona islandia.php jest gotowa.

    Typowe błędy

    Zamknięcie przed skryptem 3 (np. zaraz po bloku bocznym) zostawi galerię pustą - zapytanie pójdzie po zamkniętym połączeniu.

    islandia.php PHP zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Islandia</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'islandia');
    ?>
        <header>
            <h1><a href="islandia.php">Zwiedzaj Islandię</a></h1>
        </header>
        <aside>
            <h3>Do zwiedzania</h3>
            <ul>
                <li>Wodospady:
                    <ol>
    <?php
    $waterfalls = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 10;');
    while ($row = mysqli_fetch_row($waterfalls)) {
        echo "<li>$row[0]</li>";
    }
    ?>
                    </ol>
                </li>
                <li>Siedliska zwierząt:
                    <ol>
    <?php
    $habitats = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 14;');
    while ($row = mysqli_fetch_row($habitats)) {
        echo "<li>$row[0]</li>";
    }
    ?>
                    </ol>
                </li>
            </ul>
        </aside>
        <main>
            <h2>Galeria</h2>
            <section>
    <?php
    $objects = mysqli_query($connection, 'SELECT idObiekt, plik, nazwa FROM obiekty WHERE panstwo = "Islandia";');
    while ($row = mysqli_fetch_row($objects)) {
        echo "<a href=\"obiekty.php?id=$row[0]\"><img src=\"$row[1]\" alt=\"$row[2]\" title=\"$row[2]\" class=\"miniatury\"></a>";
    }
    ?>
            </section>
        </main>
        <footer>
            <hr>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    <?php
    mysqli_close($connection);
    ?>
    </body>
    </html>

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

  41. Krok 41: Skrypt 4: parametr z adresu w zapytaniu 2

    Kryteria:

    R.5.3 Skrypty zawierają przynajmniej jedną instrukcję wysyłającą zapytanie do bazy danych: skrypt 2 zmodyfikowane zapytanie 3 - idRodzaj = 14 skrypt 1 zapytanie 3 skrypt 3 - zapytanie 1 skrypt 4 - zmodyfikowane zapytanie 2 - id pobrane z tablicy $_GET

    ok. 3 min
    Polecenie z arkusza

    Skrypt 4 na stronie obiekty.php: Wysyła do bazy danych zapytanie 2, zmodyfikowane w ten sposób, że w warunku jest sprawdzane id obiektu przesłane jako parametr metody GET ze strony islandia.php.

    Parametry z adresu PHP trzyma w tablicy $_GET (tabela 2): $_GET['id'] to wartość z obiekty.php?id=53. Zapisz ją w $id i wstaw w miejsce 46 z zapytania 2. Zapytanie bierzesz tym razem w cudzysłów, bo w cudzysłowie PHP podstawia wartości zmiennych (... WHERE idObiekt = $id), a jedyny tekst w środku zapytania nie ma już cudzysłowów. Zapytanie zwraca jeden wiersz, więc zamiast pętli wystarczy jedno mysqli_fetch_row.

    ⚠️ Tak zrobiona podstawa jest niebezpieczna: każdy może dopisać do adresu dowolny fragment SQL - poprawisz to w etapie „Dobre praktyki”. Na egzaminie wystarcza i spełnia R.5.3.

    Typowe błędy

    Stronę obiekty.php sprawdzaj, klikając zdjęcie w galerii. Otwarta wprost, bez ?id= w adresie, kończy się ostrzeżeniem „Undefined array key "id"” i błędem składni SQL (zapytanie kończy się na idObiekt =) - obsługę braku parametru dodaje etap „Dobre praktyki”.

    obiekty.php PHP zmienione: 5 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Islandia</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'islandia');
    ?>
        <header>
            <h1><a href="islandia.php">Zwiedzaj Islandię</a></h1>
        </header>
        <aside>
            <h3>Do zwiedzania</h3>
            <ul>
                <li>Wodospady:
                    <ol>
    <?php
    $waterfalls = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 10;');
    while ($row = mysqli_fetch_row($waterfalls)) {
        echo "<li>$row[0]</li>";
    }
    ?>
                    </ol>
                </li>
                <li>Siedliska zwierząt:
                    <ol>
    <?php
    $habitats = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 14;');
    while ($row = mysqli_fetch_row($habitats)) {
        echo "<li>$row[0]</li>";
    }
    ?>
                    </ol>
                </li>
            </ul>
        </aside>
        <main>
            <h2>Opis miejsca</h2>
            <section>
    <?php
    $id = $_GET['id'];
    $details = mysqli_query($connection, "SELECT plik, nazwa, nazwaCechy, wartoscCechy, opis, rodzaj FROM obiekty JOIN rodzaje ON obiekty.idRodzaj = rodzaje.idRodzaj WHERE idObiekt = $id;");
    $row = mysqli_fetch_row($details);
    ?>
            </section>
        </main>
        <footer>
            <hr>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (obiekty.php)
  42. Krok 42: Skrypt 4: obraz obiektu

    Kryteria:

    R.5.7 Skrypt 4 wyświetla obraz oraz dane których id zostało przesłane metodą GET

    ok. 1 min
    Polecenie z arkusza

    Na podstawie zwróconych zapytaniem danych: Wyświetla obraz, którego źródłem jest pole plik, a tekstem alternatywnym pole nazwa.

    Kolejność kolumn z zapytania 2: plik (0), nazwa (1), nazwaCechy (2), wartoscCechy (3), opis (4), rodzaj (5). Obraz: źródło $row[0], tekst alternatywny $row[1]. W podglądzie: Godafoss, czyli obiekty.php?id=53 - obiekt z ilustracji 3.

    obiekty.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Islandia</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'islandia');
    ?>
        <header>
            <h1><a href="islandia.php">Zwiedzaj Islandię</a></h1>
        </header>
        <aside>
            <h3>Do zwiedzania</h3>
            <ul>
                <li>Wodospady:
                    <ol>
    <?php
    $waterfalls = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 10;');
    while ($row = mysqli_fetch_row($waterfalls)) {
        echo "<li>$row[0]</li>";
    }
    ?>
                    </ol>
                </li>
                <li>Siedliska zwierząt:
                    <ol>
    <?php
    $habitats = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 14;');
    while ($row = mysqli_fetch_row($habitats)) {
        echo "<li>$row[0]</li>";
    }
    ?>
                    </ol>
                </li>
            </ul>
        </aside>
        <main>
            <h2>Opis miejsca</h2>
            <section>
    <?php
    $id = $_GET['id'];
    $details = mysqli_query($connection, "SELECT plik, nazwa, nazwaCechy, wartoscCechy, opis, rodzaj FROM obiekty JOIN rodzaje ON obiekty.idRodzaj = rodzaje.idRodzaj WHERE idObiekt = $id;");
    $row = mysqli_fetch_row($details);
    echo "<img src=\"$row[0]\" alt=\"$row[1]\">";
    ?>
            </section>
        </main>
        <footer>
            <hr>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (obiekty.php)
  43. Krok 43: Skrypt 4: nazwa w nagłówku drugiego stopnia

    Kryteria:

    R.2.8 Na stronie obiekty.php w bloku głównym lub bloku sekcji znajdują się elementy <h2>, <h3> i przynajmniej jeden <p> (w skrypcie lub HTML )

    ok. 1 min
    Polecenie z arkusza

    W nagłówku drugiego stopnia wyświetla wartość pola nazwa.

    <h2> z $row[1]. Na stronie są teraz dwa nagłówki drugiego stopnia: „Opis miejsca” bloku głównego i nazwa obiektu w sekcji - tak pokazuje ilustracja 3.

    obiekty.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Islandia</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'islandia');
    ?>
        <header>
            <h1><a href="islandia.php">Zwiedzaj Islandię</a></h1>
        </header>
        <aside>
            <h3>Do zwiedzania</h3>
            <ul>
                <li>Wodospady:
                    <ol>
    <?php
    $waterfalls = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 10;');
    while ($row = mysqli_fetch_row($waterfalls)) {
        echo "<li>$row[0]</li>";
    }
    ?>
                    </ol>
                </li>
                <li>Siedliska zwierząt:
                    <ol>
    <?php
    $habitats = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 14;');
    while ($row = mysqli_fetch_row($habitats)) {
        echo "<li>$row[0]</li>";
    }
    ?>
                    </ol>
                </li>
            </ul>
        </aside>
        <main>
            <h2>Opis miejsca</h2>
            <section>
    <?php
    $id = $_GET['id'];
    $details = mysqli_query($connection, "SELECT plik, nazwa, nazwaCechy, wartoscCechy, opis, rodzaj FROM obiekty JOIN rodzaje ON obiekty.idRodzaj = rodzaje.idRodzaj WHERE idObiekt = $id;");
    $row = mysqli_fetch_row($details);
    echo "<img src=\"$row[0]\" alt=\"$row[1]\">";
    echo "<h2>$row[1]</h2>";
    ?>
            </section>
        </main>
        <footer>
            <hr>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (obiekty.php)
  44. Krok 44: Skrypt 4: rodzaj w nagłówku trzeciego stopnia

    Kryteria:

    R.2.8 Na stronie obiekty.php w bloku głównym lub bloku sekcji znajdują się elementy <h2>, <h3> i przynajmniej jeden <p> (w skrypcie lub HTML )

    ok. 1 min
    Polecenie z arkusza

    W nagłówku trzeciego stopnia wyświetla wartość pola rodzaj.

    <h3> z $row[5] - pole rodzaj pochodzi z tabeli rodzaje, dołączonej relacją w zapytaniu 2.

    obiekty.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Islandia</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'islandia');
    ?>
        <header>
            <h1><a href="islandia.php">Zwiedzaj Islandię</a></h1>
        </header>
        <aside>
            <h3>Do zwiedzania</h3>
            <ul>
                <li>Wodospady:
                    <ol>
    <?php
    $waterfalls = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 10;');
    while ($row = mysqli_fetch_row($waterfalls)) {
        echo "<li>$row[0]</li>";
    }
    ?>
                    </ol>
                </li>
                <li>Siedliska zwierząt:
                    <ol>
    <?php
    $habitats = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 14;');
    while ($row = mysqli_fetch_row($habitats)) {
        echo "<li>$row[0]</li>";
    }
    ?>
                    </ol>
                </li>
            </ul>
        </aside>
        <main>
            <h2>Opis miejsca</h2>
            <section>
    <?php
    $id = $_GET['id'];
    $details = mysqli_query($connection, "SELECT plik, nazwa, nazwaCechy, wartoscCechy, opis, rodzaj FROM obiekty JOIN rodzaje ON obiekty.idRodzaj = rodzaje.idRodzaj WHERE idObiekt = $id;");
    $row = mysqli_fetch_row($details);
    echo "<img src=\"$row[0]\" alt=\"$row[1]\">";
    echo "<h2>$row[1]</h2>";
    echo "<h3>$row[5]</h3>";
    ?>
            </section>
        </main>
        <footer>
            <hr>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (obiekty.php)
  45. Krok 45: Skrypt 4: cecha i jej wartość w paragrafie

    Kryteria:

    R.2.8 Na stronie obiekty.php w bloku głównym lub bloku sekcji znajdują się elementy <h2>, <h3> i przynajmniej jeden <p> (w skrypcie lub HTML )

    ok. 1 min
    Polecenie z arkusza

    W paragrafie wyświetla tekst „<nazwaCechy>: <wartoscCechy>”, gdzie w <> umieszczono wartości zwrócone zapytaniem.

    Dwie kolumny w jednym napisie, oddzielone dwukropkiem i spacją: "<p>$row[2]: $row[3]</p>". Dla Godafossu: „wysokość: 30”.

    obiekty.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Islandia</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'islandia');
    ?>
        <header>
            <h1><a href="islandia.php">Zwiedzaj Islandię</a></h1>
        </header>
        <aside>
            <h3>Do zwiedzania</h3>
            <ul>
                <li>Wodospady:
                    <ol>
    <?php
    $waterfalls = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 10;');
    while ($row = mysqli_fetch_row($waterfalls)) {
        echo "<li>$row[0]</li>";
    }
    ?>
                    </ol>
                </li>
                <li>Siedliska zwierząt:
                    <ol>
    <?php
    $habitats = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 14;');
    while ($row = mysqli_fetch_row($habitats)) {
        echo "<li>$row[0]</li>";
    }
    ?>
                    </ol>
                </li>
            </ul>
        </aside>
        <main>
            <h2>Opis miejsca</h2>
            <section>
    <?php
    $id = $_GET['id'];
    $details = mysqli_query($connection, "SELECT plik, nazwa, nazwaCechy, wartoscCechy, opis, rodzaj FROM obiekty JOIN rodzaje ON obiekty.idRodzaj = rodzaje.idRodzaj WHERE idObiekt = $id;");
    $row = mysqli_fetch_row($details);
    echo "<img src=\"$row[0]\" alt=\"$row[1]\">";
    echo "<h2>$row[1]</h2>";
    echo "<h3>$row[5]</h3>";
    echo "<p>$row[2]: $row[3]</p>";
    ?>
            </section>
        </main>
        <footer>
            <hr>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (obiekty.php)
  46. Krok 46: Skrypt 4: opis i zamknięcie połączenia

    Kryteria: ,

    R.5.7 Skrypt 4 wyświetla obraz oraz dane których id zostało przesłane metodą GET

    R.5.1 Skrypt realizuje połączenie z serwerem bazy danych i wybór bazy islandia oraz ostatnią operacją na bazie jest jej zamknięcie (wystarczy na jednej stronie )

    ok. 2 min
    Polecenie z arkusza

    W paragrafie wyświetla pole opis. Na końcu należy zamknąć połączenie z bazą.

    Ostatni paragraf to $row[4] - opis miejsca. Długi opis razem ze zdjęciem nie mieści się w sekcji o wysokości 400 px, więc pojawia się pasek przewijania (ilustracja 3, „przewinięto suwak”). Na końcu pliku, po stopce, zamykasz połączenie - jak w islandia.php. Obie strony spełniają wszystkie kryteria arkusza (klucz R.5.7).

    obiekty.php PHP zmienione: 4 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Islandia</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'islandia');
    ?>
        <header>
            <h1><a href="islandia.php">Zwiedzaj Islandię</a></h1>
        </header>
        <aside>
            <h3>Do zwiedzania</h3>
            <ul>
                <li>Wodospady:
                    <ol>
    <?php
    $waterfalls = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 10;');
    while ($row = mysqli_fetch_row($waterfalls)) {
        echo "<li>$row[0]</li>";
    }
    ?>
                    </ol>
                </li>
                <li>Siedliska zwierząt:
                    <ol>
    <?php
    $habitats = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 14;');
    while ($row = mysqli_fetch_row($habitats)) {
        echo "<li>$row[0]</li>";
    }
    ?>
                    </ol>
                </li>
            </ul>
        </aside>
        <main>
            <h2>Opis miejsca</h2>
            <section>
    <?php
    $id = $_GET['id'];
    $details = mysqli_query($connection, "SELECT plik, nazwa, nazwaCechy, wartoscCechy, opis, rodzaj FROM obiekty JOIN rodzaje ON obiekty.idRodzaj = rodzaje.idRodzaj WHERE idObiekt = $id;");
    $row = mysqli_fetch_row($details);
    echo "<img src=\"$row[0]\" alt=\"$row[1]\">";
    echo "<h2>$row[1]</h2>";
    echo "<h3>$row[5]</h3>";
    echo "<p>$row[2]: $row[3]</p>";
    echo "<p>$row[4]</p>";
    ?>
            </section>
        </main>
        <footer>
            <hr>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    <?php
    mysqli_close($connection);
    ?>
    </body>
    </html>
    Podgląd strony po tym kroku (obiekty.php)
  47. Etap 5: Dobre praktyki (poza kluczem)

    Kroki 47-49 · po tym etapie masz 37 z 37 kryteriów (pkt)

    Krok 47: obiekty.php: zapytanie przygotowane zamiast wklejania $_GET do SQL

    ok. 5 min
    Polecenie z arkusza

    Skrypt 4 na stronie obiekty.php: Wysyła do bazy danych zapytanie 2, zmodyfikowane w ten sposób, że w warunku jest sprawdzane id obiektu przesłane jako parametr metody GET ze strony islandia.php.

    Wersja z egzaminu wkleja tekst z adresu wprost do zapytania. Adres obiekty.php?id=0 OR 1=1 zmienia sens warunku - to SQL injection, najczęstsza dziura w stronach z bazą danych. Napraw to dwiema warstwami:

    • (int) $_GET['id'] zamienia parametr na liczbę całkowitą (tekst daje 0), a isset obsługuje wejście bez parametru zamiast ostrzeżenia PHP,
    • zapytanie przygotowane: mysqli_prepare z ? w miejscu wartości, mysqli_stmt_bind_param z typem 'i' (integer) - baza dostaje SQL i wartość osobno, więc wartość nigdy nie stanie się kodem.

    Gdy obiektu nie ma ($row to null), strona mówi to wprost zamiast wypisywać puste znaczniki. Stare linie zostają w komentarzu. Na egzaminie wystarczy wersja wcześniejsza - klucz tego nie sprawdza.

    obiekty.php PHP zmienione: 17 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Islandia</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'islandia');
    ?>
        <header>
            <h1><a href="islandia.php">Zwiedzaj Islandię</a></h1>
        </header>
        <aside>
            <h3>Do zwiedzania</h3>
            <ul>
                <li>Wodospady:
                    <ol>
    <?php
    $waterfalls = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 10;');
    while ($row = mysqli_fetch_row($waterfalls)) {
        echo "<li>$row[0]</li>";
    }
    ?>
                    </ol>
                </li>
                <li>Siedliska zwierząt:
                    <ol>
    <?php
    $habitats = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 14;');
    while ($row = mysqli_fetch_row($habitats)) {
        echo "<li>$row[0]</li>";
    }
    ?>
                    </ol>
                </li>
            </ul>
        </aside>
        <main>
            <h2>Opis miejsca</h2>
            <section>
    <?php
    $id = isset($_GET['id']) ? (int) $_GET['id'] : 0;
    $statement = mysqli_prepare($connection, 'SELECT plik, nazwa, nazwaCechy, wartoscCechy, opis, rodzaj FROM obiekty JOIN rodzaje ON obiekty.idRodzaj = rodzaje.idRodzaj WHERE idObiekt = ?');
    mysqli_stmt_bind_param($statement, 'i', $id);
    mysqli_stmt_execute($statement);
    $row = mysqli_fetch_row(mysqli_stmt_get_result($statement));
    // $id = $_GET['id'];
    // $details = mysqli_query($connection, "SELECT plik, nazwa, nazwaCechy, wartoscCechy, opis, rodzaj FROM obiekty JOIN rodzaje ON obiekty.idRodzaj = rodzaje.idRodzaj WHERE idObiekt = $id;");
    // $row = mysqli_fetch_row($details);
    if ($row) {
        echo "<img src=\"$row[0]\" alt=\"$row[1]\">";
        echo "<h2>$row[1]</h2>";
        echo "<h3>$row[5]</h3>";
        echo "<p>$row[2]: $row[3]</p>";
        echo "<p>$row[4]</p>";
    } else {
        echo '<p>Nie znaleziono takiego miejsca - wybierz zdjęcie w galerii.</p>';
    }
    ?>
            </section>
        </main>
        <footer>
            <hr>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    <?php
    mysqli_close($connection);
    ?>
    </body>
    </html>

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

  48. Krok 48: islandia.php: escapowanie nazw w atrybutach

    ok. 3 min
    Polecenie z arkusza

    Odnośnik jest obrazem, dla którego źródło to zwrócone pole plik, tekst alternatywny to zwrócone pole nazwa.

    Nazwa obiektu trafia do atrybutów alt i title. Gdyby w bazie była nazwa z cudzysłowem (np. Wodospad "Złoty"), zamknęłaby atrybut i rozbiła znacznik - a nazwa z <script> wykonałaby się u każdego, kto otworzy galerię (XSS). htmlspecialchars() zamienia ", <, > i & na encje, więc tekst zawsze zostaje tekstem. Escapujesz przy wypisywaniu, nie przy zapisie do bazy. Podgląd bez zmian.

    Na egzaminie wystarczy wersja wcześniejsza - klucz tego nie sprawdza.

    islandia.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Islandia</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'islandia');
    ?>
        <header>
            <h1><a href="islandia.php">Zwiedzaj Islandię</a></h1>
        </header>
        <aside>
            <h3>Do zwiedzania</h3>
            <ul>
                <li>Wodospady:
                    <ol>
    <?php
    $waterfalls = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 10;');
    while ($row = mysqli_fetch_row($waterfalls)) {
        echo "<li>$row[0]</li>";
    }
    ?>
                    </ol>
                </li>
                <li>Siedliska zwierząt:
                    <ol>
    <?php
    $habitats = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 14;');
    while ($row = mysqli_fetch_row($habitats)) {
        echo "<li>$row[0]</li>";
    }
    ?>
                    </ol>
                </li>
            </ul>
        </aside>
        <main>
            <h2>Galeria</h2>
            <section>
    <?php
    $objects = mysqli_query($connection, 'SELECT idObiekt, plik, nazwa FROM obiekty WHERE panstwo = "Islandia";');
    while ($row = mysqli_fetch_row($objects)) {
        $name = htmlspecialchars($row[2]);
        echo "<a href=\"obiekty.php?id=$row[0]\"><img src=\"$row[1]\" alt=\"$name\" title=\"$name\" class=\"miniatury\"></a>";
    }
    ?>
            </section>
        </main>
        <footer>
            <hr>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    <?php
    mysqli_close($connection);
    ?>
    </body>
    </html>
    Podgląd strony po tym kroku (islandia.php)
  49. Krok 49: Wspólny blok boczny w pliku boczny.php

    ok. 4 min
    Polecenie z arkusza

    Skrypt 1 na obu stronach. Skrypt 2 na obu stronach.

    Blok boczny ze skryptami 1 i 2 stoi w dwóch plikach, znak w znak. Poprawka w jednej kopii łatwo omija drugą. Przenieś go do boczny.php i w obu stronach w jego miejscu napisz <?php include 'boczny.php'; ?> - PHP wkleja zawartość pliku przy każdym wyświetleniu. Dołączony plik widzi zmienne strony, więc korzysta z jej $connection. Tak samo w prawdziwych witrynach powstają wspólne nagłówki, menu i stopki. Wygląd stron się nie zmienia.

    Na egzaminie wystarczy wersja wcześniejsza - klucz sprawdza skrypty 1 i 2 na stronie i oba wymagania spełniają.

    boczny.php PHP nowy plik
        <aside>
            <h3>Do zwiedzania</h3>
            <ul>
                <li>Wodospady:
                    <ol>
    <?php
    $waterfalls = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 10;');
    while ($row = mysqli_fetch_row($waterfalls)) {
        echo "<li>$row[0]</li>";
    }
    ?>
                    </ol>
                </li>
                <li>Siedliska zwierząt:
                    <ol>
    <?php
    $habitats = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 14;');
    while ($row = mysqli_fetch_row($habitats)) {
        echo "<li>$row[0]</li>";
    }
    ?>
                    </ol>
                </li>
            </ul>
        </aside>
    islandia.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Islandia</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'islandia');
    ?>
        <header>
            <h1><a href="islandia.php">Zwiedzaj Islandię</a></h1>
        </header>
    <?php include 'boczny.php'; ?>
        <main>
            <h2>Galeria</h2>
            <section>
    <?php
    $objects = mysqli_query($connection, 'SELECT idObiekt, plik, nazwa FROM obiekty WHERE panstwo = "Islandia";');
    while ($row = mysqli_fetch_row($objects)) {
        $name = htmlspecialchars($row[2]);
        echo "<a href=\"obiekty.php?id=$row[0]\"><img src=\"$row[1]\" alt=\"$name\" title=\"$name\" class=\"miniatury\"></a>";
    }
    ?>
            </section>
        </main>
        <footer>
            <hr>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    <?php
    mysqli_close($connection);
    ?>
    </body>
    </html>
    obiekty.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Islandia</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'islandia');
    ?>
        <header>
            <h1><a href="islandia.php">Zwiedzaj Islandię</a></h1>
        </header>
    <?php include 'boczny.php'; ?>
        <main>
            <h2>Opis miejsca</h2>
            <section>
    <?php
    $id = isset($_GET['id']) ? (int) $_GET['id'] : 0;
    $statement = mysqli_prepare($connection, 'SELECT plik, nazwa, nazwaCechy, wartoscCechy, opis, rodzaj FROM obiekty JOIN rodzaje ON obiekty.idRodzaj = rodzaje.idRodzaj WHERE idObiekt = ?');
    mysqli_stmt_bind_param($statement, 'i', $id);
    mysqli_stmt_execute($statement);
    $row = mysqli_fetch_row(mysqli_stmt_get_result($statement));
    // $id = $_GET['id'];
    // $details = mysqli_query($connection, "SELECT plik, nazwa, nazwaCechy, wartoscCechy, opis, rodzaj FROM obiekty JOIN rodzaje ON obiekty.idRodzaj = rodzaje.idRodzaj WHERE idObiekt = $id;");
    // $row = mysqli_fetch_row($details);
    if ($row) {
        echo "<img src=\"$row[0]\" alt=\"$row[1]\">";
        echo "<h2>$row[1]</h2>";
        echo "<h3>$row[5]</h3>";
        echo "<p>$row[2]: $row[3]</p>";
        echo "<p>$row[4]</p>";
    } else {
        echo '<p>Nie znaleziono takiego miejsca - wybierz zdjęcie w galerii.</p>';
    }
    ?>
            </section>
        </main>
        <footer>
            <hr>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    <?php
    mysqli_close($connection);
    ?>
    </body>
    </html>

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

  50. Etap 6: Oddanie pracy

    Krok 50 · po tym etapie masz 37 z 37 kryteriów (pkt)

    Krok 50: 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 folderze z numerem zdającego, powinno znajdować się 9 plików z grafiką do strony oraz pliki: import.jpg, islandia.php, kw1.png, kw2.png, kw3.png, kw4.png, kwerendy.txt, obiekty.php, przeglądarka.txt, styl.css, ewentualnie inne przygotowane pliki.

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

    Sprawdź folder: dziewięć zdjęć z archiwum, import.jpg, islandia.php, obiekty.php, kw1.png - kw4.png, kwerendy.txt, przeglądarka.txt, styl.css (oraz boczny.php, jeśli powstał w refaktorze). Nagraj płytę, sprawdź jej odczyt i opisz numerem zdającego.

    przeglądarka.txt Tekst nowy plik
    Google Chrome

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

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.