Przejdź do głównej treści
EE.09-02-20.06-SGCzerwiec 2020 · 37 kroków · ok. 63 min · 32 kryteria z klucza

Rozwiązanie krok po kroku: Biuro podróży z galerią zdjęć (Wersja podstawowa)

Biuro podróży: baza egzamin3 (import pliku egzamin3.sql - osiem tabel, w zadaniu potrzebne są dwie: wycieczki i zdjecia), cztery zapytania - dostępne wycieczki, zdjęcia posortowane po podpisie, zdjęcia połączone z wycieczkami droższymi niż 1000 zł (JOIN) i nowa kolumna w tabeli (ALTER TABLE). Do tego strona wycieczki.php z banerem, trzema blokami obok siebie (kontakt, galeria, promocje), listą wycieczek i stopką, style w styl3.css oraz skrypt PHP, który z bazy buduje galerię zdjęć i listę dostępnych wycieczek.

To arkusz EE.09 z czerwca 2020 - kwalifikacji formuły 2017, którą zastąpiła INF.03. Z tej samej bazy i tych samych zdjęć korzysta arkusz EE.09-06 z tej sesji (archiwum wycieczek) - polecenia i klucz są tam inne. Kroki idą zdanie po zdaniu za treścią arkusza: przy każdym jest polecenie z arkusza, a kod pokazuje dokładnie te linie, które je spełniają. Skrypt jest napisany najprościej, funkcjami mysqli z tabeli 1 arkusza, a na końcu sprawdzony na danych z cudzysłowem i zabezpieczony.

To jest wersja podstawowa. W zakładce „Nowoczesny kod (flex, PDO)” jest drugi sposób rozwiązania tego samego arkusza: semantyczne znaczniki, układ bez float, PDO na górze pliku i bezpieczne wypisywanie danych - obie wersje są zgodne z kluczem.

Baza i zdjęcia pochodzą z oryginalnego archiwum CKE egzamin3.zip (załącznik do pobrania na stronie arkusza, hasło w treści zadania). Zapytania i zrzuty są policzone na MariaDB 10.4 - tej samej, która jest w XAMPP, a podgląd od kroków z PHP to wynik prawdziwego uruchomienia kodu w PHP 8.2.

Jak liczą się punkty. Klucz ma 32 kryteria (R.1.1 - R.5.6), każde za 1 punkt. Próg zdania części praktycznej to 75%, czyli 24 punkty - można stracić 8 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 32 kryteriów (pkt)

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

    ok. 2 min
    Polecenie z arkusza

    Na pulpicie znajdziesz archiwum ZIP o nazwie egzamin3.zip zabezpieczone hasłem: &poDrozE$ Archiwum należy rozpakować. Na pulpicie konta Egzamin utwórz folder. Jako nazwy folderu użyj swojego numeru PESEL. Umieść w tym folderze rozpakowane pliki.

    Na pulpicie tworzysz folder nazwany numerem PESEL - w tym rozwiązaniu w jego miejscu stoi imię i nazwisko autora, Bartosz Bryniarski. Archiwum egzamin3.zip rozpakowujesz, podając hasło &poDrozE$ - wielkość liter i znaki & oraz $ mają znaczenie. W środku jest plik egzamin3.sql i dziewięć zdjęć 1.jpg - 9.jpg (każde 500 × 333 px). Zdjęć nie trzeba przerabiać - wysokość ustawi CSS.

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

    Typowe błędy

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

  2. Krok 2: XAMPP i pusta baza egzamin3

    ok. 2 min
    Polecenie z arkusza

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

    W XAMPP Control Panel klikasz Start przy Apache i MySQL, potem http://localhost/phpmyadmin. Nowa w lewym panelu, nazwa egzamin3, Utwórz.

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

    Kryteria:

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

    ok. 3 min
    Polecenie z arkusza

    Do bazy egzamin3 zaimportuj tabele z pliku egzamin3.sql z rozpakowanego archiwum. Wykonaj zrzut ekranu po imporcie. Zrzut zapisz w formacie PNG pod nazwą import w folderze z numerem PESEL. Nie kadruj zrzutu. Zrzut powinien obejmować cały ekran monitora, z widocznym paskiem zadań. Na zrzucie powinny być widoczne elementy wskazujące na poprawnie wykonany import tabel

    Zaznacz bazę egzamin3, karta Import, Wybierz plik → egzamin3.sql, Wykonaj. Plik tworzy osiem tabel - poza wycieczki i zdjecia także tabele z innych zadań (kadra, uslugi, wyniki...). W zadaniu używasz tylko dwóch z obrazu 1, pozostałe po prostu zostają. Po imporcie lista tabel w karcie Struktura - zrzut całego ekranu z paskiem zadań: import.png.

    W tabeli wycieczki pole dostepna ma wartość 1 (dostępna) albo 0, a zdjecia_id wskazuje id zdjęcia - to relacja między tabelami. Nazwy w danych są bez polskich liter (Wlochy, Paryz).

    Typowe błędy

    Zrzut importu w PNG (import.png), zrzuty kwerend w JPEG - zły format albo wykadrowany zrzut nie jest oceniany.

    Podgląd strony po tym kroku
    Podgląd strony po kroku 3
  4. Krok 4: Zapytanie 1: dostępne wycieczki

    Kryteria: ,

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

    R.1.3 Utworzono zapytanie 1 wybierające jedynie pola id, dataWyjazdu, cel i cena z tabeli wycieczki jedynie dla dostępnych wycieczek. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT id, dataWyjazdu, cel, cena FROM wycieczki WHERE dostepna = TRUE; (lub = 1) oraz wynik działania zapytania udokumentowano zrzutem, na którym widocznych jest dokładnie 6 rekordów dla id równego 1, 2, 3, 4, 6, 9; widoczne jedynie pola id, dataWyjazdu, cel i cena

    ok. 3 min
    Polecenie z arkusza

    Zapytanie 1: wybierające jedynie pola id, dataWyjazdu, cel i cena z tabeli wycieczki dla dostępnych wycieczek (pole dostepna)

    Karta SQL bazy egzamin3:

    • SELECT id, dataWyjazdu, cel, cena - cztery kolumny w kolejności, w której skrypt je wypisze,
    • FROM wycieczki,
    • WHERE dostepna = TRUE - w MySQL i MariaDB TRUE to po prostu 1 (klucz przyjmuje też = 1).

    Wynik: 6 wierszy o id 1, 2, 3, 4, 6 i 9 - dokładnie jak w kluczu. Zapytanie zapisujesz w pliku kwerendy.txt, a cały ekran - jako kw1.jpg.

    kwerendy.txt Tekst nowy plik
    -- Zapytanie 1
    SELECT id, dataWyjazdu, cel, cena FROM wycieczki WHERE dostepna = TRUE;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 4
  5. Krok 5: Zapytanie 2: zdjęcia posortowane po podpisie

    Kryteria:

    R.1.4 Utworzono zapytanie 2 wybierające jedynie pola nazwaPliku i podpis z tabeli zdjecia sortując je rosnąco alfabetycznie według pola podpis. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT nazwaPliku, podpis FROM zdjecia ORDER BY podpis; (opcjonalnie ASC) oraz wynik działania zapytania udokumentowano zrzutem, na którym widocznych jest dokładnie 9 rekordów posortowanych rosnąco alfabetycznie według kolumny podpis jedynie pola nazwaPliku i podpis

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 2: wybierające jedynie pola nazwaPliku i podpis z tabeli zdjecia, sortując je rosnąco alfabetycznie według kolumny podpis

    • SELECT nazwaPliku, podpis FROM zdjecia,
    • ORDER BY podpis - sortowanie; domyślny kierunek to rosnący (ASC), więc dopisywać go nie trzeba.

    Wynik: 9 wierszy od Barcelony do Wenecji. Zrzut: kw2.jpg. W tej kolejności skrypt ułoży zdjęcia w galerii - zgodnie z obrazem 2 (pierwsze jest 8.jpg, Barcelona).

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT id, dataWyjazdu, cel, cena FROM wycieczki WHERE dostepna = TRUE;
    
    -- Zapytanie 2
    SELECT nazwaPliku, podpis FROM zdjecia ORDER BY podpis;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 5
  6. Krok 6: Zapytanie 3: relacja zdjęć i drogich wycieczek

    Kryteria:

    R.1.5 Utworzono zapytanie 3 wykorzystujące relację i wybierające jedynie pola nazwaPliku i cel związany ze zdjęciem z tabel zdjecia i wycieczki , dla wycieczek, których cena jest wyższa niż 1000 zł. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT nazwaPliku, cel FROM zdjecia JOIN wycieczki ON zdjecia.id = wycieczki.zdjecia_id WHERE cena > 1000; możliwe też INNER JOIN lub SELECT nazwaPliku, cel FROM zdjecia, wycieczki WHERE zdjecia.id = wycieczki.zdjecia_id AND cena > 1000; oraz wynik działania zapytania udokumentowano zrzutem, na którym widocznych jest dokładnie 8 rekordów, jedynie pola nazwaPliku i cel z danymi: dwukrotnie Włochy, Wenecja; trzykrotnie Francja, Paryz; trzykrotnie Hiszpania, Barcelona

    ok. 3 min
    Polecenie z arkusza

    Zapytanie 3: wykorzystujące relację i wybierające jedynie pola nazwaPliku i cel związany ze zdjęciem z tabel zdjecia i wycieczki, dla wycieczek, których cena jest wyższa niż 1000 zł

    • SELECT nazwaPliku, cel - kolumny z dwóch tabel (nazwaPliku ze zdjęć, cel z wycieczek),
    • FROM zdjecia JOIN wycieczki ON zdjecia.id = wycieczki.zdjecia_id - relacja: każda wycieczka łączy się ze zdjęciem, którego id zapisano w jej polu zdjecia_id,
    • WHERE cena > 1000 - „wyższa niż” to ostre >.

    Wynik: 8 wierszy - dwa razy Wenecja (2.jpg), trzy razy Paryż (6.jpg) i trzy razy Barcelona (8.jpg), zgodnie z kluczem. Warszawa za 640 zł odpada. Zrzut: kw3.jpg.

    Typowe błędy

    FROM zdjecia, wycieczki bez warunku łączącego daje iloczyn kartezjański - każde zdjęcie z każdą wycieczką (dziesiątki wierszy). Klucz przyjmuje przecinek tylko razem z WHERE zdjecia.id = wycieczki.zdjecia_id.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT id, dataWyjazdu, cel, cena FROM wycieczki WHERE dostepna = TRUE;
    
    -- Zapytanie 2
    SELECT nazwaPliku, podpis FROM zdjecia ORDER BY podpis;
    
    -- Zapytanie 3
    SELECT nazwaPliku, cel FROM zdjecia JOIN wycieczki ON zdjecia.id = wycieczki.zdjecia_id WHERE cena > 1000;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 6
  7. Krok 7: Zapytanie 4: kolumna dataPrzyjazdu

    Kryteria:

    R.1.6 Utworzono zapytanie 4 dodające do tabeli wycieczki pole dataPrzyjazdu typu date, pole powinno być wstawione po polu dataWyjazdu. W pliku z kwerendami lub na zrzucie istnieje zapis np.: ALTER TABLE wycieczki ADD dataPrzyjazdu DATE AFTER dataWyjazdu; lub ADD COLUMN oraz wynik działania zapytania udokumentowano zrzutem wskazującym na dodanie kolumny dataPrzyjazdu z typem DATE po polu dataWyjazdu

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 4: dodające do tabeli wycieczki pole dataPrzyjazdu typu data, pole powinno być wstawione po polu dataWyjazdu

    • ALTER TABLE wycieczki - zmiana struktury tabeli, nie danych,
    • ADD dataPrzyjazdu DATE - nowa kolumna typu data,
    • AFTER dataWyjazdu - jej miejsce w tabeli; bez tego trafiłaby na koniec.

    phpMyAdmin odpowiada „MySQL zwrócił pusty wynik”, a karta Struktura tabeli pokazuje dataPrzyjazdu typu date zaraz po dataWyjazdu - zrzut tej karty to kw4.jpg (klucz wymaga widocznej nowej kolumny). Nowa kolumna jest pusta (NULL) i nie przeszkadza w zapytaniach skryptu.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT id, dataWyjazdu, cel, cena FROM wycieczki WHERE dostepna = TRUE;
    
    -- Zapytanie 2
    SELECT nazwaPliku, podpis FROM zdjecia ORDER BY podpis;
    
    -- Zapytanie 3
    SELECT nazwaPliku, cel FROM zdjecia JOIN wycieczki ON zdjecia.id = wycieczki.zdjecia_id WHERE cena > 1000;
    
    -- Zapytanie 4
    ALTER TABLE wycieczki ADD dataPrzyjazdu DATE AFTER dataWyjazdu;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 7
  8. Etap 2: Strona HTML

    Kroki 8-21 · po tym etapie masz 14 z 32 kryteriów (pkt)

    Krok 8: Plik wycieczki.php

    Kryteria:

    R.2.1 Witrynę internetową zapisano w pliku PHP o nazwie wycieczki

    ok. 1 min
    Polecenie z arkusza

    Składa się ze strony o nazwie wycieczki.php

    Plik wycieczki.php w folderze zdającego, obok zdjęć. Rozszerzenie .php, bo dojdzie skrypt - na razie szkielet HTML5: <!DOCTYPE html> i lang="pl" (R.2.1).

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

    Kryteria:

    R.2.2 Zastosowano właściwy standard kodowania polskich znaków dla witryny

    ok. 1 min
    Polecenie z arkusza

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

    <meta charset="UTF-8"> jako pierwszy element <head>, a plik zapisany w UTF-8 - inaczej „PODRÓŻY” wyświetli się z krzaczkami (R.2.2).

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

    Kryteria:

    R.2.3 Nadano tytuł strony: "Wycieczki i urlopy”

    ok. 1 min
    Polecenie z arkusza

    Tytuł strony widoczny na karcie przeglądarki: „Wycieczki i urlopy”

    <title>Wycieczki i urlopy</title> w <head> (R.2.3).

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

    Kryteria:

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

    ok. 1 min
    Polecenie z arkusza

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

    <link rel="stylesheet" href="styl3.css"> w <head>. Plik stylów powstanie po HTML-u (R.3.3).

    Typowe błędy

    Klucz uznaje R.3.3 tylko wtedy, gdy całe formatowanie pochodzi z tego pliku i każdy selektor trafia w swój blok (kropka zamiast # odbiera punkt).

    wycieczki.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wycieczki i urlopy</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (wycieczki.php)
  12. Krok 12: Bloki: baner, trzy bloki obok siebie, blok z danymi, stopka

    Kryteria:

    R.2.4 Wygląd strony zdefiniowano dzieląc ją na bloki: na górze baner, poniżej trzy bloki obok siebie: lewy, środkowy i prawy, poniżej blok z danymi, poniżej stopka. Zastosowano znaczniki sekcji

    ok. 2 min
    Polecenie z arkusza

    Podział strony na bloki: na górze baner, poniżej obok siebie trzy bloki: lewy, środkowy i prawy, poniżej blok z danymi, poniżej stopka.

    Sześć bloków w kolejności z obrazu 2: baner, bloki lewy, środkowy i prawy oraz blok z danymi jako <section> z identyfikatorami banner, left, center, right, data (po angielsku - arkusz nazw nie narzuca), na dole <footer>. Na razie stoją jeden pod drugim; trzy środkowe ustawi obok siebie CSS (R.2.4).

    wycieczki.php PHP zmienione: 12 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wycieczki i urlopy</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="banner">
        </section>
        <section id="left">
        </section>
        <section id="center">
        </section>
        <section id="right">
        </section>
        <section id="data">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wycieczki.php)
  13. Krok 13: Baner: nagłówek „BIURO PODRÓŻY”

    ok. 1 min
    Polecenie z arkusza

    Zawartość banera: nagłówek pierwszego stopnia o treści: „BIURO PODRÓŻY”

    <h1> - jedyny nagłówek pierwszego stopnia na stronie. Pozostałe bloki dostaną nagłówki drugiego stopnia.

    wycieczki.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wycieczki i urlopy</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="banner">
            <h1>BIURO PODRÓŻY</h1>
        </section>
        <section id="left">
        </section>
        <section id="center">
        </section>
        <section id="right">
        </section>
        <section id="data">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wycieczki.php)
  14. Krok 14: Blok lewy: nagłówek „KONTAKT”

    ok. 1 min
    Polecenie z arkusza

    Zawartość lewego bloku: Nagłówek drugiego stopnia o treści: „KONTAKT”

    <h2>KONTAKT</h2>. Na obrazie 2 pierwsza litera nagłówka jest większa - to zrobi pseudoelement w CSS, nie HTML.

    wycieczki.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wycieczki i urlopy</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="banner">
            <h1>BIURO PODRÓŻY</h1>
        </section>
        <section id="left">
            <h2>KONTAKT</h2>
        </section>
        <section id="center">
        </section>
        <section id="right">
        </section>
        <section id="data">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wycieczki.php)
  15. Krok 15: Odnośnik „napisz do nas”

    Kryteria:

    R.3.2 Na stronie umieszczono odnośnik "napisz do nas" łączący z adresem email (href="mailto:[email protected]")

    ok. 1 min
    Polecenie z arkusza

    Odnośnik do adresu e-mail [email protected] o treści: „napisz do nas”

    Odnośnik do poczty ma w href przedrostek mailto: - kliknięcie otwiera program pocztowy z wpisanym adresatem. Treścią odnośnika jest „napisz do nas”, a nie sam adres (R.3.2).

    Typowe błędy

    href="[email protected]" bez mailto: przeglądarka potraktuje jak plik na serwerze i pokaże błąd 404.

    wycieczki.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wycieczki i urlopy</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="banner">
            <h1>BIURO PODRÓŻY</h1>
        </section>
        <section id="left">
            <h2>KONTAKT</h2>
            <a href="mailto:[email protected]">napisz do nas</a>
        </section>
        <section id="center">
        </section>
        <section id="right">
        </section>
        <section id="data">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wycieczki.php)
  16. Krok 16: Paragraf z telefonem

    ok. 1 min
    Polecenie z arkusza

    Paragraf (akapit) o treści: „telefon: 555666777”

    <p> - akapit zaczyna się w nowej linii, dlatego telefon stoi pod odnośnikiem, jak na obrazie 2.

    wycieczki.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wycieczki i urlopy</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="banner">
            <h1>BIURO PODRÓŻY</h1>
        </section>
        <section id="left">
            <h2>KONTAKT</h2>
            <a href="mailto:[email protected]">napisz do nas</a>
            <p>telefon: 555666777</p>
        </section>
        <section id="center">
        </section>
        <section id="right">
        </section>
        <section id="data">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wycieczki.php)
  17. Krok 17: Blok środkowy: nagłówek „GALERIA”

    ok. 1 min
    Polecenie z arkusza

    Zawartość środkowego bloku: Nagłówek drugiego stopnia o treści: „GALERIA”

    Pod nagłówkiem stanie efekt skryptu 1 - zdjęcia z bazy.

    wycieczki.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wycieczki i urlopy</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="banner">
            <h1>BIURO PODRÓŻY</h1>
        </section>
        <section id="left">
            <h2>KONTAKT</h2>
            <a href="mailto:[email protected]">napisz do nas</a>
            <p>telefon: 555666777</p>
        </section>
        <section id="center">
            <h2>GALERIA</h2>
        </section>
        <section id="right">
        </section>
        <section id="data">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wycieczki.php)
  18. Krok 18: Blok prawy: nagłówek „PROMOCJE”

    ok. 1 min
    Polecenie z arkusza

    Zawartość prawego bloku: Nagłówek drugiego stopnia o treści: „PROMOCJE”

    <h2>PROMOCJE</h2> - pod nim tabela promocji.

    wycieczki.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wycieczki i urlopy</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="banner">
            <h1>BIURO PODRÓŻY</h1>
        </section>
        <section id="left">
            <h2>KONTAKT</h2>
            <a href="mailto:[email protected]">napisz do nas</a>
            <p>telefon: 555666777</p>
        </section>
        <section id="center">
            <h2>GALERIA</h2>
        </section>
        <section id="right">
            <h2>PROMOCJE</h2>
        </section>
        <section id="data">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wycieczki.php)
  19. Krok 19: Tabela promocji

    Kryteria:

    R.2.6 W bloku prawym umieszczono tabelę o 3 kolumnach i 2 wierszach. Kolejno pierwszy wiersz: Jesień, Grupa 4+, Grupa 10+; drugi wiersz: 5%, 10%, 15%; zastosowano znaczniki <table>, <tr>, <td> oraz ich zamknięcia

    ok. 2 min
    Polecenie z arkusza

    Tabela o trzech kolumnach i dwóch wierszach wypełniona danymi: Jesień, Grupa 4+, Grupa 10+, 5%, 10%, 15%

    • <table> - cała tabela,
    • <tr> - wiersz; są dwa,
    • <td> - komórka; w każdym wierszu trzy, czyli trzy kolumny.

    Pierwszy wiersz to nazwy promocji, drugi - rabaty pod nimi. Każdy znacznik ma zamknięcie - klucz to sprawdza (R.2.6). Tabela nie ma obramowania, bo arkusz go nie wymaga, a na obrazie 2 go nie ma.

    wycieczki.php PHP zmienione: 12 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wycieczki i urlopy</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="banner">
            <h1>BIURO PODRÓŻY</h1>
        </section>
        <section id="left">
            <h2>KONTAKT</h2>
            <a href="mailto:[email protected]">napisz do nas</a>
            <p>telefon: 555666777</p>
        </section>
        <section id="center">
            <h2>GALERIA</h2>
        </section>
        <section id="right">
            <h2>PROMOCJE</h2>
            <table>
                <tr>
                    <td>Jesień</td>
                    <td>Grupa 4+</td>
                    <td>Grupa 10+</td>
                </tr>
                <tr>
                    <td>5%</td>
                    <td>10%</td>
                    <td>15%</td>
                </tr>
            </table>
        </section>
        <section id="data">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wycieczki.php)
  20. Krok 20: Blok z danymi: nagłówek „LISTA WYCIECZEK”

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku z danymi: Nagłówek drugiego stopnia o treści „LISTA WYCIECZEK”

    Pod nim stanie efekt skryptu 2 - lista dostępnych wycieczek.

    wycieczki.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wycieczki i urlopy</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="banner">
            <h1>BIURO PODRÓŻY</h1>
        </section>
        <section id="left">
            <h2>KONTAKT</h2>
            <a href="mailto:[email protected]">napisz do nas</a>
            <p>telefon: 555666777</p>
        </section>
        <section id="center">
            <h2>GALERIA</h2>
        </section>
        <section id="right">
            <h2>PROMOCJE</h2>
            <table>
                <tr>
                    <td>Jesień</td>
                    <td>Grupa 4+</td>
                    <td>Grupa 10+</td>
                </tr>
                <tr>
                    <td>5%</td>
                    <td>10%</td>
                    <td>15%</td>
                </tr>
            </table>
        </section>
        <section id="data">
            <h2>LISTA WYCIECZEK</h2>
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wycieczki.php)
  21. Krok 21: Stopka: paragraf z autorem strony

    Kryteria:

    R.2.5 W bloku banera zapisano nagłówek h1: "BIURO PODRÓŻY" oraz w blokach lewym, środkowym i prawym nagłówki h2: "KONTAKT", "GALERIA", "PROMOCJE" oraz w bloku z danymi nagłówek h2: "LISTA WYCIECZEK" oraz przynajmniej jeden paragraf (znacznik <p>)

    ok. 1 min
    Polecenie z arkusza

    Zawartość stopki: akapit (paragraf) o treści: „Stronę wykonał: ”, dalej wstawiony numer PESEL zdającego

    Na egzaminie po dwukropku wpisujesz swój numer PESEL; w tym rozwiązaniu w jego miejscu stoi Bartosz Bryniarski. Strona ma teraz <h1> w banerze, cztery <h2> i paragrafy (R.2.5).

    wycieczki.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wycieczki i urlopy</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="banner">
            <h1>BIURO PODRÓŻY</h1>
        </section>
        <section id="left">
            <h2>KONTAKT</h2>
            <a href="mailto:[email protected]">napisz do nas</a>
            <p>telefon: 555666777</p>
        </section>
        <section id="center">
            <h2>GALERIA</h2>
        </section>
        <section id="right">
            <h2>PROMOCJE</h2>
            <table>
                <tr>
                    <td>Jesień</td>
                    <td>Grupa 4+</td>
                    <td>Grupa 10+</td>
                </tr>
                <tr>
                    <td>5%</td>
                    <td>10%</td>
                    <td>15%</td>
                </tr>
            </table>
        </section>
        <section id="data">
            <h2>LISTA WYCIECZEK</h2>
        </section>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wycieczki.php)
  22. Etap 3: Styl CSS

    Kroki 22-31 · po tym etapie masz 25 z 32 kryteriów (pkt)

    Krok 22: Plik styl3.css: krój Verdana dla całej strony

    Kryteria:

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

    ok. 1 min
    Polecenie z arkusza

    Domyślne dla całej strony: krój czcionki Verdana

    Nowy plik styl3.css. Selektor uniwersalny * obejmuje każdy element strony (R.4.1).

    styl3.css CSS nowy plik
    * {
        font-family: Verdana;
    }
    Podgląd strony po tym kroku (wycieczki.php)
  23. Krok 23: Baner i stopka

    ok. 2 min
    Polecenie z arkusza

    Wspólne dla banera i stopki: kolor tła RGB 205, 92, 92; biały kolor czcionki, wyrównanie tekstu do środka, marginesy wewnętrzne 5 px

    Dwa selektory po przecinku - jedna wspólna reguła. Kolor zapisany jako rgb(205, 92, 92), wprost z arkusza (to ten sam kolor co #CD5C5C). padding: 5px to margines wewnętrzny z czterech stron.

    styl3.css CSS zmienione: 6 linii
    * {
        font-family: Verdana;
    }
    #banner, footer {
        background-color: rgb(205, 92, 92);
        color: white;
        text-align: center;
        padding: 5px;
    }
    Podgląd strony po tym kroku (wycieczki.php)
  24. Krok 24: Bloki lewy i prawy

    ok. 1 min
    Polecenie z arkusza

    Dla bloku lewego i prawego: kolor tła RGB 250, 235, 215; szerokość 25%, wysokość 500 px

    Jasny, piaskowy kolor tła i 25% szerokości strony na każdy z dwóch bocznych bloków.

    styl3.css CSS zmienione: 5 linii
    * {
        font-family: Verdana;
    }
    #banner, footer {
        background-color: rgb(205, 92, 92);
        color: white;
        text-align: center;
        padding: 5px;
    }
    #left, #right {
        background-color: rgb(250, 235, 215);
        width: 25%;
        height: 500px;
    }
    Podgląd strony po tym kroku (wycieczki.php)
  25. Krok 25: Blok środkowy

    Kryteria: ,

    R.4.4 Ustawiono wysokość bloku lewego, środkowego i prawego 500px

    R.4.5 Ustawiono szerokość bloku lewego i prawego 25% oraz środkowego 50%

    ok. 1 min
    Polecenie z arkusza

    Dla bloku środkowego: kolor tła RGB 250, 235, 215; szerokość 50%, wysokość 500 px

    25% + 50% + 25% = 100% - trzy bloki zmieszczą się w jednym rzędzie, jeśli nie dostaną obramowań ani padding. Wysokość trzech bloków (R.4.4) i ich szerokości (R.4.5) są ustawione.

    styl3.css CSS zmienione: 5 linii
    * {
        font-family: Verdana;
    }
    #banner, footer {
        background-color: rgb(205, 92, 92);
        color: white;
        text-align: center;
        padding: 5px;
    }
    #left, #right {
        background-color: rgb(250, 235, 215);
        width: 25%;
        height: 500px;
    }
    #center {
        background-color: rgb(250, 235, 215);
        width: 50%;
        height: 500px;
    }
    Podgląd strony po tym kroku (wycieczki.php)
  26. Krok 26: Blok z danymi

    Kryteria: ,

    R.4.2 Ustawiono kolor tła rgb(205, 92, 92) dla bloków banera i stopki oraz rgb(250, 235, 215) dla bloków lewego, środkowego i prawego oraz rgb(210, 180, 140) dla bloku z danymi

    R.4.3 Ustawiono biały kolor czcionki dla banera, stopki i bloku z danymi

    ok. 1 min
    Polecenie z arkusza

    Dla bloku z danymi: kolor tła RGB 210, 180, 140; biały kolor czcionki

    Ciemniejszy, brązowy kolor tła. Kolory tła wszystkich bloków (R.4.2) i biały tekst w banerze, stopce i bloku z danymi (R.4.3) są ustawione.

    styl3.css CSS zmienione: 4 linie
    * {
        font-family: Verdana;
    }
    #banner, footer {
        background-color: rgb(205, 92, 92);
        color: white;
        text-align: center;
        padding: 5px;
    }
    #left, #right {
        background-color: rgb(250, 235, 215);
        width: 25%;
        height: 500px;
    }
    #center {
        background-color: rgb(250, 235, 215);
        width: 50%;
        height: 500px;
    }
    #data {
        background-color: rgb(210, 180, 140);
        color: white;
    }
    Podgląd strony po tym kroku (wycieczki.php)
  27. Krok 27: Nagłówki drugiego stopnia do środka

    Kryteria: ,

    R.4.6 Ustawiono wyrównanie tekstu do środka dla banera i stopki oraz znacznika h2

    R.4.7 Ustawiono marginesy wewnętrzne (padding) dla banera i stopki 5px

    ok. 1 min
    Polecenie z arkusza

    Dla znacznika nagłówka drugiego stopnia: wyrównanie tekstu do środka

    Selektor znacznika h2 obejmuje wszystkie cztery nagłówki bloków. Razem z wyśrodkowaniem banera i stopki daje R.4.6. Paddingi banera i stopki dają R.4.7.

    styl3.css CSS zmienione: 3 linie
    * {
        font-family: Verdana;
    }
    #banner, footer {
        background-color: rgb(205, 92, 92);
        color: white;
        text-align: center;
        padding: 5px;
    }
    #left, #right {
        background-color: rgb(250, 235, 215);
        width: 25%;
        height: 500px;
    }
    #center {
        background-color: rgb(250, 235, 215);
        width: 50%;
        height: 500px;
    }
    #data {
        background-color: rgb(210, 180, 140);
        color: white;
    }
    h2 {
        text-align: center;
    }
    Podgląd strony po tym kroku (wycieczki.php)
  28. Krok 28: Większa pierwsza litera nagłówków

    Kryteria:

    R.4.8 Ustawiono styl pierwszej litery znacznika h2 (pseudoelement first-letter): rozmiar czcionki 150%

    ok. 1 min
    Polecenie z arkusza

    Dla pierwszej litery nagłówka drugiego stopnia (pseudoelement): rozmiar czcionki 150%

    Pseudoelement ::first-letter wybiera tylko pierwszą literę elementu. Rozmiar 150% liczy się względem rozmiaru nagłówka - stąd „K” w „KONTAKT” wyraźnie wyższe od reszty, jak na obrazie 2 (R.4.8).

    Typowe błędy

    h2:first-letter z jednym dwukropkiem też działa (stary zapis), ale h2:first-child to coś innego - pierwszy element w rodzicu, nie pierwsza litera.

    styl3.css CSS zmienione: 3 linie
    * {
        font-family: Verdana;
    }
    #banner, footer {
        background-color: rgb(205, 92, 92);
        color: white;
        text-align: center;
        padding: 5px;
    }
    #left, #right {
        background-color: rgb(250, 235, 215);
        width: 25%;
        height: 500px;
    }
    #center {
        background-color: rgb(250, 235, 215);
        width: 50%;
        height: 500px;
    }
    #data {
        background-color: rgb(210, 180, 140);
        color: white;
    }
    h2 {
        text-align: center;
    }
    h2::first-letter {
        font-size: 150%;
    }
    Podgląd strony po tym kroku (wycieczki.php)
  29. Krok 29: Obrazy: wysokość i marginesy wewnętrzne

    Kryteria:

    R.4.9 Ustawiono styl obrazu: wysokość 100px, marginesy wewnętrzne (padding) 7px

    ok. 1 min
    Polecenie z arkusza

    Dla obrazu: wysokość 100 px, marginesy wewnętrzne 7 px

    Ustawiona sama wysokość - szerokość przeglądarka dobierze z proporcji zdjęcia (500 × 333 px), więc obraz ma ok. 150 × 100 px. padding: 7px tworzy ramkę wokół zdjęcia, w której za chwilę pojawi się tło (R.4.9).

    styl3.css CSS zmienione: 4 linie
    * {
        font-family: Verdana;
    }
    #banner, footer {
        background-color: rgb(205, 92, 92);
        color: white;
        text-align: center;
        padding: 5px;
    }
    #left, #right {
        background-color: rgb(250, 235, 215);
        width: 25%;
        height: 500px;
    }
    #center {
        background-color: rgb(250, 235, 215);
        width: 50%;
        height: 500px;
    }
    #data {
        background-color: rgb(210, 180, 140);
        color: white;
    }
    h2 {
        text-align: center;
    }
    h2::first-letter {
        font-size: 150%;
    }
    img {
        height: 100px;
        padding: 7px;
    }
    Podgląd strony po tym kroku (wycieczki.php)
  30. Krok 30: Tło obrazu pod kursorem

    Kryteria:

    R.4.10 Ustawiono styl obrazu z pseudoklasą hover: kolor tła rgb(210, 180, 140)

    ok. 1 min
    Polecenie z arkusza

    W momencie, gdy kursor znajduje się na obrazie, styl obrazu zmienia się na: kolor tła RGB 210, 180, 140

    Pseudoklasa :hover działa tylko wtedy, gdy kursor jest nad elementem. Tło obrazu widać wyłącznie w polu padding - zdjęcie zasłania resztę. Na obrazie 2 tak wyróżnione jest środkowe zdjęcie (R.4.10).

    styl3.css CSS zmienione: 3 linie
    * {
        font-family: Verdana;
    }
    #banner, footer {
        background-color: rgb(205, 92, 92);
        color: white;
        text-align: center;
        padding: 5px;
    }
    #left, #right {
        background-color: rgb(250, 235, 215);
        width: 25%;
        height: 500px;
    }
    #center {
        background-color: rgb(250, 235, 215);
        width: 50%;
        height: 500px;
    }
    #data {
        background-color: rgb(210, 180, 140);
        color: white;
    }
    h2 {
        text-align: center;
    }
    h2::first-letter {
        font-size: 150%;
    }
    img {
        height: 100px;
        padding: 7px;
    }
    img:hover {
        background-color: rgb(210, 180, 140);
    }
    Podgląd strony po tym kroku (wycieczki.php)
  31. Krok 31: Układ bloków zgodny z obrazem 2

    Kryteria:

    R.3.1 Układ bloków po uruchomieniu strony w przeglądarce jest w pełni zgodny z Obrazem 2 w arkuszu egzaminacyjnym

    ok. 2 min
    Polecenie z arkusza

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

    • trzy bloki float: left stają obok siebie: 25% + 50% + 25%,
    • blok z danymi z clear: both zaczyna się dopiero pod nimi - bez tego wsunąłby się pod pływające bloki,
    • stopka jest zwykłym blokiem pod blokiem z danymi.

    Na obrazie 2 bloki lewy, środkowy i prawy mają tę samą wysokość 500 px, więc tło tworzy jeden pas (R.3.1).

    styl3.css CSS zmienione: 6 linii
    * {
        font-family: Verdana;
    }
    #banner, footer {
        background-color: rgb(205, 92, 92);
        color: white;
        text-align: center;
        padding: 5px;
    }
    #left, #right {
        background-color: rgb(250, 235, 215);
        width: 25%;
        height: 500px;
    }
    #center {
        background-color: rgb(250, 235, 215);
        width: 50%;
        height: 500px;
    }
    #data {
        background-color: rgb(210, 180, 140);
        color: white;
    }
    h2 {
        text-align: center;
    }
    h2::first-letter {
        font-size: 150%;
    }
    img {
        height: 100px;
        padding: 7px;
    }
    img:hover {
        background-color: rgb(210, 180, 140);
    }
    #left, #center, #right {
        float: left;
    }
    #data {
        clear: both;
    }
    Podgląd strony po tym kroku (wycieczki.php)
  32. Etap 4: Skrypt PHP

    Kroki 32-35 · po tym etapie masz 32 z 32 kryteriów (pkt)

    Krok 32: Połączenie z bazą egzamin3

    Kryteria:

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

    ok. 2 min
    Polecenie z arkusza

    Łączy się z serwerem bazodanowym na localhost, użytkownik root bez hasła, baza danych o nazwie egzamin3

    Na samej górze wycieczki.php, przed <!DOCTYPE html>, pierwszy blok PHP. Funkcja mysqli_connect z tabeli 1 arkusza: serwer localhost, użytkownik root, puste hasło '' i nazwa bazy egzamin3 - czwarty argument od razu wybiera bazę (R.5.1). Połączenie trafia do zmiennej $connection, z której skorzystają oba skrypty: galeria w bloku środkowym i lista w bloku z danymi.

    Od tego kroku podgląd to wynik prawdziwego uruchomienia w PHP 8.2; stronę sprawdzasz przez http://localhost/…, a nie otwierając plik z dysku.

    wycieczki.php PHP zmienione: 3 linie
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'egzamin3');
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wycieczki i urlopy</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="banner">
            <h1>BIURO PODRÓŻY</h1>
        </section>
        <section id="left">
            <h2>KONTAKT</h2>
            <a href="mailto:[email protected]">napisz do nas</a>
            <p>telefon: 555666777</p>
        </section>
        <section id="center">
            <h2>GALERIA</h2>
        </section>
        <section id="right">
            <h2>PROMOCJE</h2>
            <table>
                <tr>
                    <td>Jesień</td>
                    <td>Grupa 4+</td>
                    <td>Grupa 10+</td>
                </tr>
                <tr>
                    <td>5%</td>
                    <td>10%</td>
                    <td>15%</td>
                </tr>
            </table>
        </section>
        <section id="data">
            <h2>LISTA WYCIECZEK</h2>
        </section>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wycieczki.php)
  33. Krok 33: Skrypt 1: zdjęcia z zapytania 2

    Kryteria: , ,

    R.5.3 Skrypt 1 wysyła do bazy danych zapytanie 2

    R.5.4 Skrypt 1 wyświetla obrazy na podstawie danych zwróconych zapytaniem, w ten sposób, że pole nazwaPliku jest źródłem obrazu, a pole podpis jest tekstem alternatywnym obrazu

    R.2.7 W bloku środkowym umieszczono przynajmniej jeden obraz z tekstem alternatywnym (w skrypcie lub HTML)

    ok. 4 min
    Polecenie z arkusza

    Skrypt 1: Wysyła do bazy danych zapytanie 2. Dane z każdego zwróconego zapytaniem wiersza są wykorzystane do wyświetlenia kolejnych obrazów, w ten sposób, że pole nazwaPliku jest źródłem obrazu, a pole podpis jest tekstem alternatywnym obrazu

    Blok PHP pod nagłówkiem „GALERIA”:

    • mysqli_query z zapytaniem 2 z kwerendy.txt (R.5.3),
    • while ($row = mysqli_fetch_row($result)) - kolejne wiersze jako tablice: $row[0] to nazwaPliku, $row[1] - podpis,
    • echo znacznika <img>: nazwa pliku w src, podpis w alt (R.5.4, R.2.7).

    Cudzysłowy atrybutów wewnątrz napisu w cudzysłowie trzeba poprzedzić ukośnikiem: \". Pliki 1.jpg - 9.jpg leżą obok strony, więc sama nazwa wystarczy jako ścieżka. Wynik: 9 zdjęć w kolejności podpisów - od Barcelony do Wenecji, po trzy w rzędzie, jak na obrazie 2.

    wycieczki.php PHP zmienione: 6 linii
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'egzamin3');
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wycieczki i urlopy</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="banner">
            <h1>BIURO PODRÓŻY</h1>
        </section>
        <section id="left">
            <h2>KONTAKT</h2>
            <a href="mailto:[email protected]">napisz do nas</a>
            <p>telefon: 555666777</p>
        </section>
        <section id="center">
            <h2>GALERIA</h2>
            <?php
            $result = mysqli_query($connection, "SELECT nazwaPliku, podpis FROM zdjecia ORDER BY podpis;");
            while ($row = mysqli_fetch_row($result)) {
                echo "<img src=\"$row[0]\" alt=\"$row[1]\">";
            }
            ?>
        </section>
        <section id="right">
            <h2>PROMOCJE</h2>
            <table>
                <tr>
                    <td>Jesień</td>
                    <td>Grupa 4+</td>
                    <td>Grupa 10+</td>
                </tr>
                <tr>
                    <td>5%</td>
                    <td>10%</td>
                    <td>15%</td>
                </tr>
            </table>
        </section>
        <section id="data">
            <h2>LISTA WYCIECZEK</h2>
        </section>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wycieczki.php)
  34. Krok 34: Skrypt 2: lista dostępnych wycieczek

    Kryteria: ,

    R.5.5 Skrypt 2 wysyła do bazy danych zapytanie 1

    R.5.6 Skrypt 2 wyświetla zwrócone zapytaniem wiersze w osobnej linii, według wzoru: „<id>. <dataWyjazdu>, <cel>, cena: <cena>”, gdzie w znakach < > zapisano pola zwracane zapytaniem

    ok. 3 min
    Polecenie z arkusza

    Skrypt 2: Wysyła do bazy danych zapytanie 1. Każdy zwrócony zapytaniem wiersz jest wyświetlany w osobnej linii, według wzoru: „<id>. <dataWyjazdu>, <cel>, cena: <cena>”, gdzie w znakach < > zapisano pola zwracane zapytaniem

    Blok PHP pod nagłówkiem „LISTA WYCIECZEK”:

    • mysqli_query z zapytaniem 1 (R.5.5),
    • w pętli echo jednej linii według wzoru: $row[0] (id), kropka, $row[1] (data wyjazdu), przecinek, $row[2] (cel - sam zawiera przecinek, np. „Wlochy, Wenecja”), przecinek i „cena: ” z $row[3],
    • na końcu <br> - złamanie wiersza, więc każda wycieczka stoi w osobnej linii (R.5.6).

    Wynik: sześć linii, od „1. 2019-09-08, Wlochy, Wenecja, cena: 1200” do „9. 2019-09-14, Hiszpania, Barcelona, cena: 1400” - tak samo jak na obrazie 2.

    wycieczki.php PHP zmienione: 6 linii
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'egzamin3');
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wycieczki i urlopy</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="banner">
            <h1>BIURO PODRÓŻY</h1>
        </section>
        <section id="left">
            <h2>KONTAKT</h2>
            <a href="mailto:[email protected]">napisz do nas</a>
            <p>telefon: 555666777</p>
        </section>
        <section id="center">
            <h2>GALERIA</h2>
            <?php
            $result = mysqli_query($connection, "SELECT nazwaPliku, podpis FROM zdjecia ORDER BY podpis;");
            while ($row = mysqli_fetch_row($result)) {
                echo "<img src=\"$row[0]\" alt=\"$row[1]\">";
            }
            ?>
        </section>
        <section id="right">
            <h2>PROMOCJE</h2>
            <table>
                <tr>
                    <td>Jesień</td>
                    <td>Grupa 4+</td>
                    <td>Grupa 10+</td>
                </tr>
                <tr>
                    <td>5%</td>
                    <td>10%</td>
                    <td>15%</td>
                </tr>
            </table>
        </section>
        <section id="data">
            <h2>LISTA WYCIECZEK</h2>
            <?php
            $result = mysqli_query($connection, "SELECT id, dataWyjazdu, cel, cena FROM wycieczki WHERE dostepna = TRUE;");
            while ($row = mysqli_fetch_row($result)) {
                echo "$row[0]. $row[1], $row[2], cena: $row[3]<br>";
            }
            ?>
        </section>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wycieczki.php)
  35. Krok 35: Zamknięcie połączenia z bazą

    Kryteria:

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

    ok. 1 min
    Polecenie z arkusza

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

    mysqli_close($connection) po pętli skryptu 2 - lista stoi niżej niż galeria, więc to ostatnie zapytanie na stronie (R.5.2). Strona spełnia wszystkie kryteria arkusza.

    Typowe błędy

    mysqli_close w bloku galerii, przed skryptem 2, sprawia, że lista dostaje zamknięte połączenie i PHP kończy się błędem.

    wycieczki.php PHP zmienione: 1 linia
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'egzamin3');
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wycieczki i urlopy</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="banner">
            <h1>BIURO PODRÓŻY</h1>
        </section>
        <section id="left">
            <h2>KONTAKT</h2>
            <a href="mailto:[email protected]">napisz do nas</a>
            <p>telefon: 555666777</p>
        </section>
        <section id="center">
            <h2>GALERIA</h2>
            <?php
            $result = mysqli_query($connection, "SELECT nazwaPliku, podpis FROM zdjecia ORDER BY podpis;");
            while ($row = mysqli_fetch_row($result)) {
                echo "<img src=\"$row[0]\" alt=\"$row[1]\">";
            }
            ?>
        </section>
        <section id="right">
            <h2>PROMOCJE</h2>
            <table>
                <tr>
                    <td>Jesień</td>
                    <td>Grupa 4+</td>
                    <td>Grupa 10+</td>
                </tr>
                <tr>
                    <td>5%</td>
                    <td>10%</td>
                    <td>15%</td>
                </tr>
            </table>
        </section>
        <section id="data">
            <h2>LISTA WYCIECZEK</h2>
            <?php
            $result = mysqli_query($connection, "SELECT id, dataWyjazdu, cel, cena FROM wycieczki WHERE dostepna = TRUE;");
            while ($row = mysqli_fetch_row($result)) {
                echo "$row[0]. $row[1], $row[2], cena: $row[3]<br>";
            }
            mysqli_close($connection);
            ?>
        </section>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>

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

  36. Etap 5: Dobre praktyki (poza kluczem)

    Krok 36 · po tym etapie masz 32 z 32 kryteriów (pkt)

    Krok 36: Zabezpieczenie: htmlspecialchars przy wypisywaniu danych z bazy

    ok. 3 min

    Strona nie ma formularza, więc zapytania nie zawierają danych od użytkownika i zapytania przygotowane nie są tu potrzebne. Słaby punkt jest gdzie indziej: dane z bazy trafiają wprost do HTML-u. Sprawdzone na prawdziwej stronie - wystarczy, że w tabeli zdjecia pojawi się podpis z cudzysłowem, np. Moskwa - "Plac Czerwony":

    • wersja z poprzednich kroków wypisała alt="Moskwa - "Plac Czerwony"" - pierwszy cudzysłów w danych zamknął atrybut, więc tekst alternatywny to tylko „Moskwa - ”, a reszta stała się śmieciowymi atrybutami,
    • w ten sam sposób ktoś, kto ma dostęp do tabeli (np. przez panel biura), mógłby dopisać do podpisu atrybut onerror z kodem JavaScript, który uruchamiałby się u każdego odwiedzającego.

    htmlspecialchars zamienia " na &quot;, < na &lt; i & na &amp;, więc przeglądarka pokazuje znaki, zamiast traktować je jak kod. Stosuje się ją przy każdym wypisaniu danych z bazy - tu w galerii i na liście wycieczek. Stare linie zostają w komentarzu. Podgląd: strona z tym podpisem - tekst alternatywny jest pełny.

    wycieczki.php PHP zmienione: 4 linie
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'egzamin3');
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wycieczki i urlopy</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="banner">
            <h1>BIURO PODRÓŻY</h1>
        </section>
        <section id="left">
            <h2>KONTAKT</h2>
            <a href="mailto:[email protected]">napisz do nas</a>
            <p>telefon: 555666777</p>
        </section>
        <section id="center">
            <h2>GALERIA</h2>
            <?php
            $result = mysqli_query($connection, "SELECT nazwaPliku, podpis FROM zdjecia ORDER BY podpis;");
            while ($row = mysqli_fetch_row($result)) {
                // echo "<img src=\"$row[0]\" alt=\"$row[1]\">";
                echo '<img src="' . htmlspecialchars($row[0]) . '" alt="' . htmlspecialchars($row[1]) . '">';
            }
            ?>
        </section>
        <section id="right">
            <h2>PROMOCJE</h2>
            <table>
                <tr>
                    <td>Jesień</td>
                    <td>Grupa 4+</td>
                    <td>Grupa 10+</td>
                </tr>
                <tr>
                    <td>5%</td>
                    <td>10%</td>
                    <td>15%</td>
                </tr>
            </table>
        </section>
        <section id="data">
            <h2>LISTA WYCIECZEK</h2>
            <?php
            $result = mysqli_query($connection, "SELECT id, dataWyjazdu, cel, cena FROM wycieczki WHERE dostepna = TRUE;");
            while ($row = mysqli_fetch_row($result)) {
                // echo "$row[0]. $row[1], $row[2], cena: $row[3]<br>";
                echo htmlspecialchars("$row[0]. $row[1], $row[2], cena: $row[3]") . '<br>';
            }
            mysqli_close($connection);
            ?>
        </section>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wycieczki.php)
  37. Etap 6: Oddanie pracy

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

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

    ok. 5 min
    Polecenie z arkusza

    Po zakończeniu pracy utwórz plik tekstowy. Zapisz w nim nazwę przeglądarki internetowej, w której weryfikowałeś poprawność działania witryny. Nazwij plik przeglądarka.txt i zapisz go w folderze z numerem PESEL. Nagraj płytę z rezultatami pracy.

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

    W folderze z numerem zdającego muszą być: import.png, kw1.jpg - kw4.jpg, kwerendy.txt, styl3.css, wycieczki.php, przeglądarka.txt oraz zdjęcia 1.jpg - 9.jpg (strona z nich korzysta). Nagraj płytę, sprawdź jej odczyt, opisz ją numerem PESEL i zostaw w pudełku na stanowisku razem z arkuszem.

    przeglądarka.txt Tekst nowy plik
    Google Chrome

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

Podgląd

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

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

Potwierdzenie

Informacja