Serwis używa plików cookies do analizy ruchu i poprawy działania. Szczegóły
EE.09-02-24.01-SGStyczeń 2024 · 29 kroków · ok. 59 min · 37 kryteriów z klucza
Rozwiązanie krok po kroku: Tablica przylotów portu lotniczego (Nowoczesny kod (flex, PDO))
To drugi sposób rozwiązania tego samego arkusza. Wynik jest ten sam - baza egzamin z czterema zapytaniami, przeskalowane logo z przezroczystością i strona lotnisko.php z tablicą przylotów oraz komunikatem zależnym od ciasteczka - i tak samo spełnia każde kryterium klucza. Inna jest droga:
znaczniki <header>, <main> i <footer>: bloki banera i stopki to sekcje w nagłówku i stopce strony, a w rząd ustawia je display: flex zamiast float i clear,
zmienne CSS dla trzech kolorów z arkusza,
PHP na PDO na górze pliku, przed HTML-em: ciasteczko, połączenie, zapytanie i obsługa błędów w jednym miejscu, a w tabeli i stopce zostaje tylko wypisanie,
funkcja e() (htmlspecialchars) przy każdej wartości z bazy, try/catch/finally z zamknięciem połączenia w każdym przypadku,
ciasteczko z flagamihttponly i samesite.
To arkusz EE.09 ze stycznia 2024 (kwalifikacja formuły 2017, którą zastąpiła INF.03) - powtórka zadania EE.09-05 ze stycznia 2021 z dwoma dodatkowymi wymaganiami: zapis w HTML5 i język strony. Klucz z 2024 każe sprawdzać skrypty w XAMPP 8.1.2 - użyte konstrukcje działają w PHP 8.1 i 8.2. Baza i grafika pochodzą z oryginalnego archiwum CKE dane1.7z (załącznik na stronie arkusza), zapytania i zrzuty są policzone na MariaDB 10.4, a podgląd od kroków z PHP to wynik prawdziwego uruchomienia kodu w PHP 8.2 - także dwóch kolejnych wejść tej samej przeglądarki z ciasteczkiem.
Jak liczą się punkty. Klucz ma 37 kryteriów (R.1.1 - R.5.8), każde za 1 punkt. Próg zdania części praktycznej to 75%, czyli 28 punktów. Przy każdym kroku jest napisane, które kryteria spełnia; klucz przyjmuje zarówno mysqli, jak i PDO.
Suwak i strzałki obok niego - albo ←→ na klawiaturze - przechodzą krok po kroku; wyjaśnienie, pliki i podgląd zmieniają się razem z krokiem.
Lista „Etap” przenosi od razu do wybranego etapu.
„Rozwiązuję samodzielnie” chowa rozwiązanie kroku - najpierw własna próba, potem odsłonięcie.
„Tryb prezentacji” pokazuje same kroki, bez menu strony - na rzutnik.
Etap 1: Baza danych
Kroki 1-7 · po tym etapie masz 6 z 37 kryteriów (pkt)
Krok 1: Folder zdającego i archiwum dane1.7z
ok. 2 min
Polecenie z arkusza
Aby wykonać zadanie, zaloguj się na konto Egzamin bez hasła. Na pulpicie znajdziesz archiwum ZIP o nazwie dane1.7z zabezpieczone hasłem: $@molot# Archiwum należy rozpakować. Na pulpicie konta Egzamin utwórz folder. Jako nazwy folderu należy użyć numeru zdającego. Umieść w tym folderze rozpakowane pliki.
Folder na pulpicie nazwany numerem zdającego (PESEL) - w tym rozwiązaniu Bartosz Bryniarski. Archiwum dane1.7z rozpakuj 7-Zipem do tego folderu, hasło $@molot#. W środku: egzamin.sql i zad5.png.
Krok 2: XAMPP, baza egzamin i import egzamin.sql
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 egzamin. Do bazy egzamin zaimportuj plik egzamin.sql z rozpakowanego archiwum
Start Apache i MySQL, w phpMyAdmin nowa baza egzamin, potem karta Import przy zaznaczonej bazie i plik egzamin.sql. Do zadania potrzebne są tabele przyloty (8 wierszy), odloty (10) i samoloty (4), połączone polem samoloty_id.
Krok 3: Zrzut import.png
Kryteria:
R.1.1 Wykonano import tabel do bazy danych egzamin , czynność udokumentowano plikiem o nazwie import w formacie PNG
ok. 2 min
Polecenie z arkusza
Wykonaj zrzut ekranu po imporcie. Zrzut zapisz w folderze z numerem zdającego, w formacie PNG i nazwij import. Nie kadruj zrzutu. Powinien on obejmować cały ekran monitora, z widocznym paskiem zadań. Na zrzucie powinny być widoczne elementy wskazujące na poprawnie wykonany import tabel
Karta Struktura bazy egzamin z listą tabel i liczbą rekordów - zrzut całego ekranu z paskiem zadań, format PNG, nazwa import.
Podgląd strony po tym kroku
Krok 4: Zapytanie 1: przyloty posortowane według czasu
Kryteria: ,
R.1.2 Zapisano plik tekstowy o nazwie kwerendy z zapytaniami SQL zawierający co najmniej jedno zapytanie SQL, wynikające z treści zadania
R.1.3 Wykonano zapytanie 1 wybierające jedynie pola czas, kierunek, nr_rejsu i status_lotu z tabeli przyloty posortowane rosnąco według czasu. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT czas, kierunek, nr_rejsu, status_lotu FROM przyloty ORDER BY czas; (też gdy zapisano ASC) oraz wynik działania zapytania udokumentowano zrzutem, na którym jest widocznych dokładnie 8 rekordów, jedynie pola czas, kierunek, nr_rejsu, status_lotu. Rekordy są posortowane rosnąco wg. czasu
ok. 3 min
Polecenie z arkusza
Zapisz i wykonaj zapytania SQL działające na bazie egzamin. Zapytania zapisz w pliku kwerendy.txt, w folderze z numerem zdającego. Wykonaj zrzuty ekranu przedstawiające wyniki działania kwerend. Zrzuty zapisz w formacie JPG i nadaj im nazwy kw1, kw2, kw3, kw4. Zrzuty powinny obejmować cały ekran monitora z widocznym paskiem zadań. Zapytanie 1: wybierające jedynie pola czas, kierunek, nr_rejsu i status_lotu z tabeli przyloty posortowane rosnąco według czasu
Cztery pola w kolejności kolumn przyszłej tablicy, ORDER BY czas sortuje rosnąco. Wynik: 8 przylotów od 09:45:00 (Warszawa) do 10:33:00 (Zurych). Zapytanie do kwerendy.txt, zrzut kw1.jpg - to samo zapytanie wyśle skrypt.
kwerendy.txtTekstnowy plik
-- Zapytanie 1SELECT czas, kierunek, nr_rejsu, status_lotu FROM przyloty ORDER BY czas;
Podgląd strony po tym kroku
Krok 5: Zapytanie 2: przyloty między 10:00 a 10:59
Kryteria:
R.1.4 Wykonano zapytanie 2 zliczające przyloty, które odbyły się w godzinach 10:00 – 10:59. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT COUNT(*) FROM przyloty WHERE czas LIKE "10%"; możliwe inne warianty, np. z BETWEEN oraz wynik działania zapytania udokumentowano zrzutem, na którym jest widoczna wartość 7, wynikająca z zadanego zapytania
ok. 2 min
Polecenie z arkusza
Zapytanie 2: zliczające przyloty, które odbyły się w godzinach 10:00 ÷ 10:59
COUNT(*) zlicza wiersze, BETWEEN '10:00:00' AND '10:59:59' obejmuje oba końce przedziału kolumny typu TIME. Wynik: 7. Zrzut kw2.jpg.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT czas, kierunek, nr_rejsu, status_lotu FROM przyloty ORDER BY czas;-- Zapytanie 2SELECT COUNT(*) FROM przyloty WHERE czas BETWEEN '10:00:00' AND '10:59:59';
Podgląd strony po tym kroku
Krok 6: Zapytanie 3: relacja przyloty - samoloty
Kryteria:
R.1.5 Wykonano zapytanie 3 wybierające jedynie pola nr_rejsu z tabeli przyloty oraz typ z tabeli samoloty , dla lotów których kierunkiem jest Warszawa. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT nr_rejsu, samoloty.typ FROM przyloty JOIN samoloty ON przyloty.samoloty_id = samoloty.id WHERE kierunek = "Warszawa"; możliwe INNER JOIN lub bez JOIN (porównanie kluczy w warunku) oraz wynik działania zapytania udokumentowano zrzutem, na którym widoczny jest dokładnie jeden rekord jedynie z danymi: W63454, Boening 737
ok. 3 min
Polecenie z arkusza
Zapytanie 3: wybierające jedynie pola nr_rejsu z tabeli przyloty oraz typ z tabeli samoloty dla lotów, których kierunkiem jest Warszawa; zapytanie wykorzystuje relację
JOIN samoloty ON przyloty.samoloty_id = samoloty.id łączy przylot z jego samolotem, WHERE kierunek = 'Warszawa' zostawia jeden wiersz: W63454, Boening 737 (pisownia z bazy CKE). Zrzut kw3.jpg.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT czas, kierunek, nr_rejsu, status_lotu FROM przyloty ORDER BY czas;-- Zapytanie 2SELECT COUNT(*) FROM przyloty WHERE czas BETWEEN '10:00:00' AND '10:59:59';-- Zapytanie 3SELECT nr_rejsu, typ FROM przyloty JOIN samoloty ON przyloty.samoloty_id = samoloty.id WHERE kierunek = 'Warszawa';
Podgląd strony po tym kroku
Krok 7: Zapytanie 4: zmiana statusu odlotu LX5673
Kryteria:
R.1.6 Wykonano zapytanie 4 aktualizujące w tabeli odloty pole status_lotu na: „opoznienie 20 min” dla lotu o numerze rejsu LX5673. W pliku z kwerendami lub na zrzucie istnieje zapis np.: UPDATE odloty SET status_lotu="opoznienie 20 min" WHERE nr_rejsu="LX5673"; oraz wynik działania zapytania udokumentowano zrzutem, dokumentującym poprawne wykonanie zapytania 4
ok. 2 min
Polecenie z arkusza
Zapytanie 4: aktualizujące w tabeli odloty pole status_lotu na: „opoznienie 20 min” dla lotu o numerze rejsu LX5673
To jedyna kwerenda na tabeli odloty. SET ustawia nowy status, WHERE nr_rejsu = 'LX5673' ogranicza zmianę do jednego wiersza - phpMyAdmin odpowiada „1 wiersz zmieniony”. Zrzut kw4.jpg.
Typowe błędy
UPDATE bez WHERE zmienia wszystkie dziesięć odlotów.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT czas, kierunek, nr_rejsu, status_lotu FROM przyloty ORDER BY czas;-- Zapytanie 2SELECT COUNT(*) FROM przyloty WHERE czas BETWEEN '10:00:00' AND '10:59:59';-- Zapytanie 3SELECT nr_rejsu, typ FROM przyloty JOIN samoloty ON przyloty.samoloty_id = samoloty.id WHERE kierunek = 'Warszawa';-- Zapytanie 4UPDATE odloty SET status_lotu = 'opoznienie 20 min' WHERE nr_rejsu = 'LX5673';
Podgląd strony po tym kroku
Etap 2: Grafika i strona HTML
Kroki 8-14 · po tym etapie masz 15 z 37 kryteriów (pkt)
Krok 8: Grafika: wysokość 200 px z przezroczystością
Kryteria:
R.2.1 Plik zad5.png przeskalowano z zachowaniem proporcji do wysokości 200 px, odpowiadająca temu szerokość wynosi 305 px (± 5 px); przezroczystość została zachowana
ok. 2 min
Polecenie z arkusza
Plik zad5.png, wypakowany z archiwum, należy przeskalować z zachowaniem proporcji tak, aby jego wysokość wynosiła dokładnie 200 px. Należy zachować przezroczystość obrazu
W GIMP-ie Obraz → Skaluj obraz z zamkniętym łańcuchem: 457 × 300 px → 305 × 200 px. Zapis jako PNG, który przechowuje kanał przezroczystości.
Podgląd strony po tym kroku
Krok 9: Plik lotnisko.php: nagłówek dokumentu
Kryteria: , ,
R.2.2 Witrynę internetową zapisano w pliku PHP o nazwie lotnisko oraz jawnie zastosowano właściwy standard kodowania polskich znaków
R.2.3 Nadano tytuł strony: "Port Lotniczy”
R.3.4 Strona zawiera działające połączenie z zewnętrznym arkuszem stylów o nazwie styl5.css , formatowanie CSS pochodzi jedynie z tego arkusza Uwaga: kryterium to nie jest spełnione również, gdy źle przypisano co najmniej jeden selektor do bloku (np. kropka zamiast #)
ok. 2 min
Polecenie z arkusza
Składa się ze strony o nazwie lotnisko.php. Zapisana w języku HTML 5. Jawnie zastosowany właściwy standard kodowania polskich znaków. Tytuł strony widoczny na karcie przeglądarki: „Port Lotniczy”. Arkusz stylów w pliku o nazwie styl5.css prawidłowo połączony z kodem strony. Ustawiony język zawartości strony na polski
Cała część <head> w jednym kroku - te same linie co w wersji podstawowej, plus jedna:
<!DOCTYPE html> - HTML5, lang="pl" - język treści,
<meta charset="UTF-8"> jako pierwszy element <head> (R.2.2 - razem z nazwą pliku lotnisko.php),
<title>Port Lotniczy</title> (R.2.3),
<meta name="viewport"> - przeglądarka telefonu pokazuje stronę w swojej szerokości, zamiast udawać szeroki ekran (arkusz tego nie wymaga),
<link rel="stylesheet" href="styl5.css"> (R.3.4 - punkt przyznawany razem z poprawnymi selektorami).
Krok 10: Bloki: nagłówek z trzema sekcjami, część główna, stopka z dwiema
Kryteria:
R.2.4 Wygląd strony zdefiniowano dzieląc ją na bloki: trzy bloki banera, poniżej blok główny, następnie dwa bloki stopki. Zastosowano znaczniki sekcji
ok. 2 min
Polecenie z arkusza
Podział strony na bloki: trzy bloki banera, poniżej blok główny, następnie dwa bloki stopki. Podział zrealizowany za pomocą znaczników sekcji, zgodnie z obrazem 2
Znaczniki sekcji HTML5 mówią, czym jest każda część strony:
<header> - nagłówek strony, w nim trzy bloki banera jako <section> z identyfikatorami logo, title i links,
<main> - blok główny z tablicą przylotów; na stronie jest jeden <main>, więc nie potrzebuje identyfikatora,
<footer> - stopka z dwoma blokami status (komunikat o ciasteczku) i author.
Kontenery <header> i <footer> przydadzą się w CSS: wystarczy im display: flex, żeby ich sekcje stanęły w rzędzie.
R.2.6 W pierwszym bloku banera umieszczono obraz zad5.png z tekstem alternatywnym: "logo lotnisko"
ok. 1 min
Polecenie z arkusza
Zawartość pierwszego bloku banera: obraz zad5.png z tekstem alternatywnym „logo lotnisko”. Zawartość drugiego bloku banera: nagłówek pierwszego stopnia o treści „Przyloty”
<img> z tekstem alternatywnym (R.2.6) i <h1> - jedyny nagłówek pierwszego stopnia na stronie.
Krok 12: Trzeci blok banera: nagłówek i odnośnik do kwerend
Kryteria: ,
R.3.2 Na stronie umieszczono odnośnik, którego wybranie prowadzi do pliku kwerendy.txt
R.3.3 Odnośnik otwiera się w nowym oknie
ok. 1 min
Polecenie z arkusza
Zawartość trzeciego bloku banera: Nagłówek trzeciego stopnia o treści: „przydatne linki”. Odnośnik o treści „Pobierz…” otwierający plik kwerendy.txt w nowym oknie
<h3> i odnośnik <a href="kwerendy.txt"> (R.3.2) z target="_blank" - nowe okno albo karta (R.3.3). Dodatkowy rel="noopener" odcina otwartą stronę od karty, z której ją otwarto (bez niego mogłaby przez window.opener podmienić adres pierwszej karty). Współczesne przeglądarki robią to już same, ale zapis pokazuje zamiar wprost.
R.2.8 Umieszczono w tabeli wiersz nagłówkowy, zastosowano cztery znaczniki <th> wewnątrz pierwszego wiersza tabeli
ok. 2 min
Polecenie z arkusza
Zawartość bloku głównego: Tabela o czterech kolumnach. Nagłówki kolumn mają podpisy: „czas”, „kierunek”, „numer rejsu”, „status”
Wiersz z czterema komórkami <th> trafia do <thead>, a miejsce na wiersze danych to <tbody> - przeglądarka i czytnik ekranu wiedzą, który wiersz opisuje kolumny (przy wydruku długiej tabeli <thead> powtarza się na każdej stronie). Klucz dopuszcza <thead> wprost (R.2.8). Wiersze danych wstawi skrypt w <tbody>.
Kroki 15-21 · po tym etapie masz 26 z 37 kryteriów (pkt)
Krok 15: Zmienne kolorów i selektor body
Kryteria: ,
R.4.1 Ustawiono krój czcionki Garamond dla body
R.4.3 Ustawiono biały kolor czcionki dla body
ok. 2 min
Polecenie z arkusza
Cechy formatowania CSS: Dla selektora body: krój czcionki Garamond, kolor tła RGB 30, 144, 255; biały kolor czcionki
Na początku pliku styl5.css reguła :root z trzema zmiennymi CSS - kolory z arkusza dostają nazwy (--sky, --navy, --silver), a reguły odwołują się do nich przez var(--sky). Szary 192, 192, 192 pojawia się w arkuszu trzy razy, więc zmiana odcienia to jedna linia.
Reguła body: krój Garamond z zapasowym serif (Garamond instaluje się w Windows z pakietem Office - na komputerze bez niego przeglądarka weźmie inny krój szeryfowy, a nie domyślny), tło var(--sky) i biały tekst (R.4.1, R.4.3).
R.3.1 Układ bloków po uruchomieniu strony w przeglądarce jest w pełni zgodny z obrazem 2 w arkuszu egzaminacyjnym (prawidłowo zastosowano właściwości CSS układające bloki na stronie, np. float i clear albo display flex albo grid albo position)
ok. 2 min
Polecenie z arkusza
Podział strony na bloki: trzy bloki banera, poniżej blok główny, następnie dwa bloki stopki. Podział zrealizowany za pomocą znaczników sekcji, zgodnie z obrazem 2
display: flex na <header> i <footer> ustawia ich sekcje w jednym rzędzie, od lewej. <main> stoi między nimi zwykłym blokiem na całą szerokość - nie trzeba ani float, ani clear. Szerokości bloków ustawią kolejne reguły.
Klucz wymienia flex wprost wśród sposobów ułożenia bloków (R.3.1); szerokości 25%, 50% i 50% stoją na samych blokach, tak jak oczekuje R.4.5.
R.4.4 Ustawiono wysokość wszystkich bloków banera na 200px
ok. 1 min
Polecenie z arkusza
Dla pierwszego i trzeciego bloku banera: szerokość 25%, wysokość 200 px. Dla drugiego bloku banera: wyrównanie tekstu do środka, szerokość 50%, wysokość 200 px, rozmiar czcionki 250%
Szerokości banera sumują się do 100%, każdy blok ma 200 px wysokości (R.4.4). Elementy flex domyślnie mogą się kurczyć, ale tu nie muszą - bez marginesów i obramowań nic nie przekracza szerokości rzędu.
Krok 18: Blok główny: tło, marginesy wewnętrzne, wielkie litery
Kryteria:
R.4.2 Ustawiono kolor tła rgb(30, 144, 255) dla body, oraz kolor tła rgb(0, 0, 128) dla bloku głównego
ok. 1 min
Polecenie z arkusza
Dla bloku głównego: tło koloru RGB 0, 0, 128; marginesy wewnętrzne 60 px, tekst wielkimi literami (niezależnie od tego jak tekst został zapisany w HTML, wymagana transformacja na wielkie litery)
Selektor znacznika main, tło var(--navy) - granat 0, 0, 128 (R.4.2 razem z tłem strony). text-transform: uppercase zmienia tylko wygląd, dane w HTML-u i w bazie zostają bez zmian.
R.4.6 Ustawiono wyrównanie tekstu do środka dla drugiego bloku banera, pierwszego bloku stopki oraz wyrównanie do prawej strony dla drugiego bloku stopki
ok. 1 min
Polecenie z arkusza
Dla pierwszego bloku stopki: wyrównanie tekstu do środka, szerokość 50%. Dla drugiego bloku stopki: wyrównanie tekstu do prawej strony, szerokość 50%, margines wewnętrzny górny: 100 px (tylko górny)
Dwa bloki po 50% w rzędzie stopki. padding-top to margines tylko od góry - dodaje wysokości, a nie szerokości, więc blok dalej mieści się obok pierwszego. Wyrównania tekstu banera i stopki są gotowe (R.4.6).
Krok 20: Paragraf i jego wygląd po najechaniu kursorem
Kryteria: ,
R.4.9 W momencie najechania kursorem na paragraf, jego kolor tła zmienia się na rgb(192, 192, 192)
R.4.10 Ustawiono rozmiar czcionki 250% dla drugiego bloku banera, 200% dla paragrafu p oraz tekst wielkimi literami (text-transform: uppercase;) dla bloku głównego
ok. 1 min
Polecenie z arkusza
Dla selektora paragrafu (akapitu): marginesy wewnętrzne 20 px, rozmiar czcionki 200%, obramowanie 1 px, linią ciągłą koloru RGB 192, 192, 192. W momencie najechania kursorem na paragraf, jego kolor tła zmienia się na RGB 192, 192, 192
Obramowanie i tło po najechaniu korzystają z tej samej zmiennej --silver. Pseudoklasa :hover działa, dopóki kursor jest nad paragrafem (R.4.9). Rozmiary czcionek są ustawione (R.4.10).
R.4.5 Ustawiono szerokość pierwszego i trzeciego bloku banera na 25%, drugiego bloku banera oraz obu bloków stopki na 50% oraz szerokość tabeli na 100%
R.4.7 Ustawiono marginesy wewnętrzne (padding) na: 60px dla bloku głównego, 20px dla paragrafu, 10px dla komórki tabeli i komórki nagłówkowej oraz jedynie margines wewnętrzny górny (padding-top) 100px dla drugiego bloku stopki
R.4.8 Ustawiono obramowanie selektora p, td, th: 1px linią ciągłą rgb(192, 192, 192) oraz połączone obramowanie dla selektora tabeli (border-collapse: collapse;)
ok. 1 min
Polecenie z arkusza
Dla selektora tabeli: szerokość 100%, obramowanie tabeli i komórki ma być połączone (collapse). Dla selektora komórki danych i komórki nagłówkowej tabeli: obramowanie 1px, linią ciągłą o kolorze RGB 192, 192, 192; marginesy wewnętrzne 10 px
Tabela na całą szerokość bloku głównego (R.4.5), jedna wspólna linia między komórkami dzięki border-collapse i obramowanie komórek w kolorze --silver (R.4.8). Marginesy wewnętrzne wszystkich elementów są gotowe (R.4.7).
Kroki 22-27 · po tym etapie masz 37 z 37 kryteriów (pkt)
Krok 22: Połączenie PDO z bazą egzamin
Kryteria: ,
R.5.1 Skrypt napisano w języku PHP oraz zawiera przynajmniej jedną poprawną składniowo instrukcję, wynikającą z treści zadania
R.5.2 Skrypt 1 realizuje połączenie z serwerem bazy danych i wybór bazy egzamin
ok. 3 min
Polecenie z arkusza
Oba skrypty napisane w języku PHP, w pliku lotnisko.php. Działanie skryptu 1: Skrypt łączy się z serwerem bazodanowym na localhost, użytkownik root bez hasła, baza danych o nazwie egzamin
Logika PHP stoi na samej górze pliku, przed <!DOCTYPE html> - najpierw skrypt zbiera dane, potem HTML je wypisuje. W tabeli i w stopce zostaną tylko krótkie wstawki.
funkcja e() - skrót od escape: przepuszcza tekst przez htmlspecialchars, więc znaki <, >, & i cudzysłowy z bazy pokażą się jako tekst, a nie jako kod strony. Typ ?string przyjmuje też null (puste pole w bazie),
new PDO(...) - serwer localhost, baza egzamin w adresie DSN, użytkownik root, puste hasło (R.5.1, R.5.2); charset=utf8mb4 ustala kodowanie połączenia,
PDO::ERRMODE_EXCEPTION - każdy błąd bazy rzuca wyjątek, który łapie catch i zapisuje neutralny komunikat zamiast pokazywać szczegóły serwera.
Podgląd to wynik prawdziwego uruchomienia - strona wygląda jak przed dodaniem PHP.
$pdo->query(...) wysyła zapytanie 1 z kwerendy.txt (R.5.4) - nie ma w nim żadnych danych od użytkownika, więc nie trzeba go przygotowywać (prepare). fetchAll(PDO::FETCH_ASSOC) od razu pobiera wszystkie osiem wierszy do tablicy $flights; każdy wiersz to tablica z kluczami jak nazwy pól: $flight['czas'], $flight['kierunek']… Czytelniej niż numery $row[0].
Gdy baza nie odpowiada, $flights zostaje pustą tablicą i strona nadal się wyświetli. Podgląd bez zmian - wiersze wypisze następny krok.
R.2.7 W bloku głównym umieszczono tabelę o czterech kolumnach, zastosowano znaczniki <table>, <tr>, <td>, tabela generowana skryptem lub HTML
R.5.5 Dane otrzymane z bazy są umieszczane w kolejnych wierszach tabeli, w odpowiednich komórkach, tak jak na Obrazie 2
ok. 3 min
Polecenie z arkusza
Dane otrzymane z bazy są umieszczane w kolejnych wierszach tabeli, w odpowiednich komórkach, tak jak na Obrazie 2
W <tbody> pętla w składni alternatywnej - foreach (...): i endforeach; w osobnych wstawkach PHP. Między nimi stoi zwykły HTML wiersza, a w komórkach skrócone <?= ... ?> (to samo co <?php echo ... ?>) z funkcją e(). HTML zostaje czytelny - nie trzeba sklejać znaczników w napisach echo.
Każdy przylot to wiersz z czterema komórkami w kolejności nagłówków (R.2.7, R.5.5). Pod pętlą warunek if ($error !== null) - przy awarii bazy tabela dostaje jeden wiersz z komunikatem na całą szerokość. Podgląd: osiem przylotów, jak na obrazie 2.
R.5.3 Po wykonaniu operacji na bazie zastosowano funkcję zamknięcia bazy
ok. 1 min
Polecenie z arkusza
Po wykonaniu operacji na bazie skrypt zamyka połączenie z serwerem
Połączenie PDO zamyka się, gdy znika ostatnie odwołanie do obiektu - stąd $pdo = null (R.5.3). Blok finally wykonuje się zawsze: po udanym zapytaniu i po błędzie. Gdy połączenie się nie udało, $pdo nie istnieje - przypisanie null niczego wtedy nie psuje.
R.5.7 Gdy odwiedzający jest na stronie pierwszy raz zakładane jest ciasteczko z czasem trwania 2 godziny od utworzenia
ok. 3 min
Polecenie z arkusza
Działanie skryptu 2: W oparciu o mechanizm ciasteczek skrypt wypisuje na stronie komunikaty: Gdy odwiedzający wejdzie na stronę pierwszy raz zakładane jest ciasteczko z czasem trwania 2 godziny od utworzenia oraz wyświetlany jest w paragrafie, czcionką pogrubioną, komunikat: „Dzień dobry! Strona lotniska używa ciasteczek”
Ciasteczko jest nagłówkiem odpowiedzi HTTP, więc setcookie musi się wykonać, zanim serwer wyśle pierwszy znak strony - kod na górze pliku spełnia to z natury.
isset($_COOKIE[COOKIE_NAME]) - czy przeglądarka przysłała ciasteczko, czyli czy to kolejna wizyta; wynik trafia do zmiennej $isReturning, z której skorzysta stopka,
setcookie z tablicą opcji (PHP 7.3+): expires = teraz + 2 × 60 × 60 = 7200 s (R.5.7), httponly - skrypty JavaScript nie odczytają ciasteczka, samesite: Lax - przeglądarka nie dołączy go do żądań z obcych stron,
nazwa i czas życia jako stałe (const) na górze pliku - liczba 7200 ma opisaną nazwę.
R.2.5 W drugim bloku banera zapisano nagłówek h1: "Przyloty", w trzecim bloku banera nagłówek h3: "przydatne linki" oraz w pierwszym bloku stopki zapisano paragraf (w kodzie HTML lub skrypcie)
R.2.9 W pierwszym bloku stopki zastosowano znaczniki <i> </i> lub <em> </em> do pochylenia oraz <b>, </b> lub <strong> </strong> do pogrubienia tekstu (w skrypcie lub w kodzie HTML). Możliwe alternatywne rozwiązanie za pomocą stylów CSS
R.5.6 Strona wykorzystuje mechanizm ciasteczek, zastosowano funkcję PHP setcookie, sprawdzono czy ciasteczko jest ustawione (np. isset, empty) oraz zastosowano tablicę $_COOKIE, zapis musi być poprawny składniowo i logicznie
R.5.8 Gdy odwiedzający jest na stronie pierwszy raz wyświetlany jest komunikat "Dzień dobry! Strona lotniska używa ciasteczek” w przeciwnym wypadku wyświetlany jest komunikat „Witaj ponownie na stronie lotniska"
ok. 3 min
Polecenie z arkusza
Gdy odwiedzający wejdzie na stronę pierwszy raz zakładane jest ciasteczko z czasem trwania 2 godziny od utworzenia oraz wyświetlany jest w paragrafie, czcionką pogrubioną, komunikat: „Dzień dobry! Strona lotniska używa ciasteczek”. Jeżeli odwiedzający w ciągu 2 godzin od poprzedniego wejścia wejdzie ponownie na stronę wyświetlany jest w paragrafie, czcionką pochyloną, komunikat „Witaj ponownie na stronie lotniska”
W bloku status składnia alternatywna if (...): / else: / endif; z gotowym HTML-em obu komunikatów, każdy w paragrafie (R.2.5): pierwsza wizyta - <strong> (pogrubienie, „ważne”), kolejna - <em> (pochylenie, „z naciskiem”) (R.2.9). Strona korzysta z setcookie, isset i $_COOKIE (R.5.6) i wypisuje właściwy komunikat (R.5.8).
Sprawdzone na prawdziwym serwerze dwoma wejściami tej samej przeglądarki: pierwsze dało „Dzień dobry! Strona lotniska używa ciasteczek”, drugie „Witaj ponownie na stronie lotniska”; ciasteczko ma flagę HttpOnly i wygasa 7200 s po utworzeniu. Podgląd: druga wizyta, jak na obrazie 2.
Krok 28 · po tym etapie masz 37 z 37 kryteriów (pkt)
Krok 28: Co jest inaczej i którą wersję wybrać na egzaminie
ok. 3 min
Obie wersje dają komplet 37 punktów. Różnice:
wersja podstawowa
wersja nowoczesna
bloki
sześć <section> jedna pod drugą
<header>, <main>, <footer> z sekcjami w środku
układ
float: left i clear: both
display: flex na <header> i <footer>
kolory
wpisane w każdej regule
zmienne --sky, --navy, --silver
tabela
wiersze sklejane w echo
<thead> i <tbody>, HTML wiersza z <?= ?>
biblioteka
mysqli (tabela 1 arkusza)
PDO z wyjątkami
gdzie jest skrypt
skrypt 1 w tabeli, skrypt 2 na górze i w stopce
logika na górze pliku, w HTML-u tylko wypisanie
wiersz wyniku
mysqli_fetch_row, $row[0]
fetchAll, $flight['czas']
dane z bazy
wprost (zabezpieczone w Dobrych praktykach)
zawsze przez e()
błąd bazy
„Fatal error” ze ścieżką pliku (naprawione w Dobrych praktykach)
catch i wiersz z komunikatem
zamknięcie
mysqli_close po pętli
$pdo = null w finally
ciasteczko
setcookie(nazwa, wartość, time() + 7200)
tablica opcji z httponly i samesite
wyróżnienie
<b> i <i> (wygląd)
<strong> i <em> (znaczenie)
Sprawdzone na prawdziwym PHP: status z wpisanym znacznikiem <s> ta wersja pokazuje dosłownie, a strona uruchomiona bez bazy egzamin wyświetla tablicę z komunikatem „Tablica przylotów jest chwilowo niedostępna” i działającą stopką.
Na egzaminie wersja podstawowa trzyma się funkcji z tabeli 1 arkusza i łatwiej ją napisać bez dokumentacji. Nowoczesna oddziela logikę od wyglądu, nie wpuszcza kodu z bazy na stronę i nie wywraca się przy awarii serwera - a klucz przyjmuje obie.
Krok 29 · po tym etapie masz 37 z 37 kryteriów (pkt)
Krok 29: 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, zapisz go w folderze z numerem zdającego, jako przeglądarka.txt. Nagraj płytę z rezultatami pracy.
W przeglądarka.txt nazwa przeglądarki, w której sprawdzana była strona. W folderze zdającego: import.png, kw1.jpg - kw4.jpg, kwerendy.txt, lotnisko.php, przeglądarka.txt, styl5.css i przeskalowany zad5.png. Nagraj płytę, sprawdź jej odczyt i opisz ją numerem zdającego.
Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.
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: Bartosz Bryniarski. 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.