Serwis używa plików cookies do analizy ruchu i poprawy działania. Szczegóły
EE.09-06-21.01-SGStyczeń 2021 · 42 kroki · ok. 77 min · 37 kryteriów z klucza
Rozwiązanie krok po kroku: Tablica odlotów z lotniska (Wersja podstawowa)
Aplikacja internetowa portu lotniczego - tablica odlotów: baza egzamin z tabelami odloty, samoloty i przyloty, cztery zapytania (sortowanie malejące, funkcja MIN w przedziale godzin, relacja JOIN i aktualizacja UPDATE), logotyp przeskalowany z zachowaniem przezroczystości oraz strona airport.php: dwa bloki banera, tablica odlotów wypełniana skryptem PHP z bazy i trzy bloki stopki, w których drugi skrypt na podstawie ciasteczka wita gościa przy pierwszej wizycie albo przy powrocie w ciągu godziny.
To arkusz EE.09 ze stycznia 2021 - kwalifikacji formuły 2017, którą zastąpiła INF.03. Jest pokrewny arkuszowi EE.09-05 z tej samej sesji (tablica przylotów, ta sama baza), ale ma inny podział strony, inne zapytania, ciasteczko na godzinę i odwrotne wyróżnienie komunikatów - ma własne rozwiązanie. Kroki idą zdanie po zdaniu za treścią arkusza; skrypty są najpierw napisane najprościej, funkcjami mysqli z tabeli 1 arkusza, a na końcu sprawdzone na prawdziwych błędach i zabezpieczone.
To jest wersja podstawowa. W zakładce „Nowoczesny kod (flex, PDO)” jest drugi sposób rozwiązania tego samego arkusza: znaczniki <header>, <main> i <footer> z układem flex, zmienne CSS, PDO z obsługą wyjątków i ciasteczko z flagami bezpieczeństwa - obie wersje są zgodne z kluczem.
Baza i grafika pochodzą z oryginalnego archiwum CKE z6.zip (załącznik na stronie arkusza, hasło w treści zadania). Zapytania i zrzuty są policzone na MariaDB 10.4 - tej samej, która jest w XAMPP. Podgląd od kroków z PHP to wynik prawdziwego uruchomienia kodu w PHP 8.2, także z ciasteczkiem zapamiętanym między dwoma wejściami na stronę.
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; egzaminator ocenia spełnienie kryteriów z klucza, nie zgodność z tym kodem.
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 z6.zip
ok. 2 min
Polecenie z arkusza
Aby wykonać zadanie, zaloguj się na konto Egzamin bez hasła. Na pulpicie znajdziesz archiwum ZIP o nazwie z6.zip zabezpieczone hasłem: @SaMolotY9% 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 z6.zip rozpakowujesz do tego folderu, podając hasło @SaMolotY9% (wielkość liter i znaki specjalne mają znaczenie). W środku są dwa pliki: egzamin.sql (baza do importu) i zad6.png (logotyp). Do tego folderu trafia wszystko, co powstanie.
Typowe błędy
Pliki zapisane poza folderem zdającego nie trafią na płytę - a ocenia się tylko to, co jest na płycie.
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
W XAMPP Control PanelStart przy Apache i MySQL, w phpMyAdmin (http://localhost/phpmyadmin) Nowa → nazwa egzamin → Utwórz. Potem przy zaznaczonej bazie karta Import, plik egzamin.sql, Wykonaj. Do zadania potrzebne są trzy tabele z obrazu 1: odloty (10 lotów), przyloty (8) i samoloty (4); pole samoloty_id w tabelach lotów wskazuje id samolotu.
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 PESEL, 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 pokazuje listę tabel z liczbą rekordów - to „elementy wskazujące na poprawnie wykonany import”. Zrzut całego ekranu z paskiem zadań zapisujesz jako import.png.
Typowe błędy
Ten zrzut jest w PNG, zrzuty kwerend w JPG - zły format albo wykadrowany zrzut nie jest oceniany.
Podgląd strony po tym kroku
Krok 4: Zapytanie 1: odloty od najpóźniejszego
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, nr_rejsu, czas, kierunek i status_lotu z tabeli odloty posortowane malejąco według czasu. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT id, nr_rejsu, czas, kierunek, status_lotu FROM odloty ORDER BY czas DESC; oraz wynik działania zapytania udokumentowano zrzutem, na którym jest widocznych dokładnie 10 rekordów, jedynie pola id, nr_rejsu, czas, kierunek, status_lotu. Rekordy są posortowane maleją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 PESEL. 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 id, nr_rejsu, czas, kierunek i status_lotu z tabeli odloty posortowane malejąco według czasu
SELECT id, nr_rejsu, czas, kierunek, status_lotu - „jedynie” te pięć pól, w kolejności kolumn tablicy na stronie (kolumna „lp.” to id),
FROM odloty,
ORDER BY czas DESC - DESC odwraca porządek: od najpóźniejszego odlotu.
Wynik: 10 odlotów. Zapytanie wklejasz do kwerendy.txt, zrzut całego ekranu z wynikiem - kw1.jpg. To samo zapytanie wyśle skrypt 1.
kwerendy.txtTekstnowy plik
-- Zapytanie 1SELECT id, nr_rejsu, czas, kierunek, status_lotu FROM odloty ORDER BY czas DESC;
Podgląd strony po tym kroku
Krok 5: Zapytanie 2: najwcześniejszy odlot między 10:10 a 10:19
Kryteria:
R.1.4 Utworzono zapytanie 2 wyznaczające najwcześniejszy (najmniejszy) czas odlotu dla lotów, których czas odlotu jest pomiędzy 10:10 – 10:19. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT MIN(czas) FROM odloty WHERE czas LIKE "10:1%"; możliwe również BETWEEN oraz wynik działania zapytania udokumentowano zrzutem, na którym jest widoczna jedynie wartość 10:13:00, wynikająca z zadanego zapytania
ok. 2 min
Polecenie z arkusza
Zapytanie 2: wyznaczające najwcześniejszy (najmniejszy) czas odlotu dla lotów, których czas odlotu jest pomiędzy 10:10 ÷ 10:19
SELECT MIN(czas) - funkcja agregująca zwraca najmniejszą wartość kolumny, czyli najwcześniejszą godzinę,
FROM odloty,
WHERE czas BETWEEN '10:10:00' AND '10:19:59' - oba końce przedziału wliczone; klucz przyjmuje też WHERE czas LIKE '10:1%'.
Wynik: 10:13:00. Zrzut: kw2.jpg.
Typowe błędy
ORDER BY czas LIMIT 1 też znajdzie ten odlot, ale arkusz każe „wyznaczyć najmniejszy czas” - do tego służy funkcja MIN, której oczekuje klucz.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT id, nr_rejsu, czas, kierunek, status_lotu FROM odloty ORDER BY czas DESC;-- Zapytanie 2SELECT MIN(czas) FROM odloty WHERE czas BETWEEN '10:10:00' AND '10:19:59';
Podgląd strony po tym kroku
Krok 6: Zapytanie 3: relacja odloty - samoloty
Kryteria:
R.1.5 Utworzono zapytanie 3 wybierające jedynie pola nr_rejsu z tabeli odloty oraz linie z tabeli samoloty dla lotów, dla których kierunkiem jest Malta. Zastosowano relację. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT nr_rejsu, samoloty.linie FROM odloty JOIN samoloty ON odloty.samoloty_id = samoloty.id WHERE kierunek = "Malta"; możliwe też 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: LX5673, SWISS
ok. 3 min
Polecenie z arkusza
Zapytanie 3: wybierające jedynie pola nr_rejsu z tabeli odloty oraz linie z tabeli samoloty, dla lotów których kierunkiem jest Malta; zapytanie wykorzystuje relację
SELECT nr_rejsu, linie - numer rejsu z tabeli odloty, linia lotnicza z tabeli samoloty,
FROM odloty JOIN samoloty ON odloty.samoloty_id = samoloty.id - relacja z obrazu 1,
WHERE kierunek = 'Malta'.
Wynik: jeden wiersz - LX5673, SWISS. Zrzut: kw3.jpg.
Typowe błędy
Bez warunku ON baza łączy lot z każdym samolotem - wynik ma 4 wiersze zamiast jednego.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT id, nr_rejsu, czas, kierunek, status_lotu FROM odloty ORDER BY czas DESC;-- Zapytanie 2SELECT MIN(czas) FROM odloty WHERE czas BETWEEN '10:10:00' AND '10:19:59';-- Zapytanie 3SELECT nr_rejsu, linie FROM odloty JOIN samoloty ON odloty.samoloty_id = samoloty.id WHERE kierunek = 'Malta';
Podgląd strony po tym kroku
Krok 7: Zapytanie 4: status przylotu LH9829
Kryteria:
R.1.6 Utworzono zapytanie 4 aktualizujące w tabeli przyloty pole status_lotu na: „planowy” dla lotu o numerze rejsu LH9829. W pliku z kwerendami lub na zrzucie istnieje zapis np.: UPDATE przyloty SET status_lotu="planowy" WHERE nr_rejsu="LH9829"; oraz wynik działania zapytania udokumentowano zrzutem, na którym widoczne jest poprawne zapytanie lub zmienione dane w tabeli
ok. 2 min
Polecenie z arkusza
Zapytanie 4: aktualizujące w tabeli przyloty pole status_lotu na: „planowy” dla lotu o numerze rejsu LH9829
Uwaga na tabelę: ta jedyna kwerenda dotyczy przylotów. UPDATE przyloty → SET status_lotu = 'planowy' → WHERE nr_rejsu = 'LH9829' (przylot z Frankfurtu). phpMyAdmin odpowiada „1 wiersz zmieniony” - zrzut kw4.jpg. Tablica odlotów na stronie się nie zmienia.
Typowe błędy
UPDATEbez WHERE zmieniłby status wszystkich ośmiu przylotów.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT id, nr_rejsu, czas, kierunek, status_lotu FROM odloty ORDER BY czas DESC;-- Zapytanie 2SELECT MIN(czas) FROM odloty WHERE czas BETWEEN '10:10:00' AND '10:19:59';-- Zapytanie 3SELECT nr_rejsu, linie FROM odloty JOIN samoloty ON odloty.samoloty_id = samoloty.id WHERE kierunek = 'Malta';-- Zapytanie 4UPDATE przyloty SET status_lotu = 'planowy' WHERE nr_rejsu = 'LH9829';
Podgląd strony po tym kroku
Etap 2: Grafika i strona HTML
Kroki 8-19 · po tym etapie masz 15 z 37 kryteriów (pkt)
Krok 8: Grafika: wysokość 150 px z przezroczystością
Kryteria:
R.2.1 Plik zad6.png przeskalowano z zachowaniem proporcji do wysokości 150 px, odpowiadająca temu szerokość wynosi 371 px (± 5 px); przezroczystość została zachowana
ok. 2 min
Polecenie z arkusza
Plik zad6.png, wypakowany z archiwum, należy przeskalować z zachowaniem proporcji tak, aby jego wysokość wynosiła dokładnie 150 px. Należy zachować przezroczystość obrazu
Oryginał ma 640 × 259 px i przezroczyste tło. W GIMP-ie Obraz → Skaluj obraz z zamkniętym łańcuchem proporcji, wysokość 150 px - szerokość: 640 × 150 / 259 = 370,7, czyli 371 px (klucz: 371 ±5). Zapis jako PNG - tylko ten format z dwóch używanych na stronie przechowuje przezroczystość.
Typowe błędy
Eksport do JPG zamienia przezroczyste tło na białe - na pomarańczowym tle strony pojawi się biały prostokąt.
Podgląd strony po tym kroku
Krok 9: Plik airport.php
ok. 1 min
Polecenie z arkusza
Składa się ze strony o nazwie airport.php
Plik airport.php w folderze zdającego, obok zad6.png. Rozszerzenie .php, bo dojdą skrypty - na razie to czysty HTML. <!DOCTYPE html> oznacza HTML5, a lang="pl" mówi przeglądarce i czytnikom ekranu, że treść jest po polsku (arkusz tego nie wymaga).
R.2.2 Witrynę internetową zapisano w pliku PHP o nazwie airport oraz zastosowano właściwy standard kodowania polskich znaków
ok. 1 min
Polecenie z arkusza
Zastosowany właściwy standard kodowania polskich znaków
<meta charset="UTF-8"> jako pierwsza rzecz w <head>, a plik zapisany w UTF-8 (w Notepad++ menu Kodowanie). Klucz ocenia nazwę pliku i kodowanie razem (R.2.2) - airport.html albo lotnisko.php to strata punktu.
R.3.4 Strona zawiera działające połączenie z zewnętrznym arkuszem stylów o nazwie styl6.css , formatowanie pochodzi jedynie z tego arkusza (poza pochyleniem i pogrubieniem) 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 styl6.css prawidłowo połączony z kodem strony
<link rel="stylesheet" href="styl6.css"> w <head>. Plik stylów powstanie po HTML-u.
Typowe błędy
Klucz uznaje R.3.4 tylko wtedy, gdy wszystkie selektory trafiają w bloki - kropka zamiast # odbiera punkt.
Krok 13: Sześć bloków: dwa banera, główny, trzy stopki
Kryteria:
R.2.4 Wygląd strony zdefiniowano dzieląc ją na bloki: dwa bloki banera, blok główny, trzy bloki stopki. Zastosowano znaczniki sekcji
ok. 2 min
Polecenie z arkusza
Podział strony na bloki: dwa bloki banera, poniżej blok główny, następnie trzy bloki stopki. Podział zrealizowany za pomocą znaczników sekcji, zgodnie z obrazem 2
Sześć znaczników <section> w kolejności z obrazu 2, każdy z identyfikatorem (nazwy po angielsku - arkusz ich nie narzuca): bloki banera title i logo, blok główny main, bloki stopki download (odnośnik do zrzutu), status (komunikat skryptu 2) i author. Obok siebie ustawi je CSS.
R.2.6 W drugim bloku banera umieszczono obraz zad6.png z tekstem alternatywnym: "logotyp", gdy obraz nie istnieje powinien wyświetlać się tekst alternatywny
ok. 1 min
Polecenie z arkusza
Zawartość drugiego bloku banera: obraz zad6.png z tekstem alternatywnym „logotyp”
<img> z przeskalowanym plikiem i atrybutem alt - tekstem, który zobaczy gość, gdy obraz się nie wczyta, i który przeczyta czytnik ekranu.
R.2.8 Umieszczono w tabeli wiersz nagłówkowy, zastosowano pięć znaczników <th> (opcjonalnie <thead> i <td>) oraz ich zamknięcia wewnątrz pierwszego wiersza tabeli
ok. 2 min
Polecenie z arkusza
Tabela o pięciu kolumnach. Nagłówki kolumn mają podpisy: „lp.”, „numer rejsu”, „czas”, „kierunek”, „status”
<table> z pierwszym wierszem <tr> i pięcioma komórkami nagłówkowymi <th>. Kolejność kolumn jest taka jak pól w zapytaniu 1 (id, nr_rejsu, czas, kierunek, status_lotu) - kolumnę „lp.” wypełni pole id. Kolejne wiersze („Zawartość tabeli jest wypełniana skryptem 1”) wstawi skrypt przed </table>.
Krok 18: Pierwszy blok stopki: odnośnik do kw1.jpg
Kryteria: ,
R.3.2 Na stronie umieszczono odnośnik, którego wybranie prowadzi do dowolnego pliku ze zrzutem
R.3.3 Odnośnik otwiera się w nowym oknie / karcie przeglądarki
ok. 1 min
Polecenie z arkusza
Zawartość pierwszego bloku stopki: Odnośnik o treści „Pobierz obraz” otwierający plik kw1.jpg w nowym oknie
<a href="kw1.jpg"> prowadzi do zrzutu wyniku zapytania 1 z tego samego folderu (R.3.2), a target="_blank" otwiera go w nowym oknie albo karcie (R.3.3).
Zawartość trzeciego bloku stopki: tekst: „Autor: ”, dalej wstawiony numer PESEL zdającego
Na egzaminie po „Autor: ” wpisujesz swój numer PESEL. W tym rozwiązaniu w jego miejscu stoi imię i nazwisko autora: Bartosz Bryniarski. Drugi blok stopki zostaje pusty - wypełni go skrypt 2.
Kroki 20-30 · po tym etapie masz 26 z 37 kryteriów (pkt)
Krok 20: Plik styl6.css: pierwszy blok banera
ok. 1 min
Polecenie z arkusza
Cechy formatowania CSS: Dla pierwszego bloku banera: wyrównanie tekstu do środka, szerokość 75%, wysokość 150 px, rozmiar czcionki 200%
Nowy plik styl6.css w folderze zdającego - od teraz każda reguła trafia tutaj. Selektor identyfikatora z krzyżykiem #title. font-size: 200% liczy się od czcionki rodzica, a nagłówek <h2> jest jeszcze półtora raza większy od tekstu swojego bloku.
R.4.4 Ustawiono wysokość wszystkich bloków banera na 150px
ok. 1 min
Polecenie z arkusza
Dla drugiego bloku banera: szerokość 25%, wysokość 150 px
Szerokości banera sumują się do 100% (75 + 25), oba bloki mają 150 px - tyle co logotyp (R.4.4). Logotyp ma 371 px szerokości, więc mieści się w bloku 25% dopiero w oknie szerszym niż ok. 1500 px (na monitorze Full HD); w węższym oknie wystaje poza blok - tak wynika z wymiarów podanych w arkuszu.
Krok 22: Blok główny: tło, marginesy wewnętrzne, wielkie litery
ok. 1 min
Polecenie z arkusza
Dla bloku głównego: tło koloru RGB 128, 0, 0; marginesy wewnętrzne 50 px, tekst wielkimi literami (niezależnie od tego jak tekst został zapisany w HTML, wymagana transformacja na wielkie litery)
rgb(128, 0, 0) to ciemna czerwień (#800000, nazwa maroon). text-transform: uppercase zmienia tylko wygląd - nagłówek, podpisy kolumn i dane z bazy wyświetlą się wielkimi literami, choć zapisane są małymi.
Dla pierwszego i trzeciego bloku stopki: szerokość 20%, margines wewnętrzny górny: 90 px (tylko górny)
Wspólna reguła dla dwóch bloków. „Tylko górny” to padding-top - margines od góry nie zmienia szerokości bloku, więc trzy bloki stopki zmieszczą się w rzędzie (20 + 60 + 20). Dzięki niemu odnośnik i autor stoją na wysokości dołu paragrafu ze środkowego bloku.
Reguła body na początku pliku - dziedziczą ją wszystkie bloki. rgb(244, 164, 96) to piaskowy pomarańcz (#F4A460, nazwa sandybrown), tekst biały. Tło bloku głównego już jest, więc R.4.2 ma oba kolory.
R.4.10 Ustawiono rozmiar czcionki 200% dla pierwszego bloku banera, 150% dla selektora p oraz tekst wielkimi literami (text-transform: uppercase;) dla bloku głównego
„Linia kropkowana” to dotted (dashed to kreski). rgb(169, 169, 169) to szary (#A9A9A9, darkgray). Rozmiary czcionek i wielkie litery bloku głównego są gotowe (R.4.10).
Krok 28: Tabela: szerokość i połączone obramowanie
Kryteria:
R.4.5 Ustawiono szerokość pierwszego bloku banera 75%, drugiego bloku banera na 25%, drugiego bloku stopki 60%, pierwszego i trzeciego bloku stopki 20% oraz szerokość tabeli na 100%
ok. 1 min
Polecenie z arkusza
Dla selektora tabeli: szerokość 100%, obramowanie tabeli i komórki ma być połączone (collapse)
Tabela na całą szerokość bloku głównego, border-collapse: collapse - jedna wspólna linia między sąsiednimi komórkami. Szerokości wszystkich bloków i tabeli są gotowe (R.4.5).
R.4.7 Ustawiono marginesy wewnętrzne (padding): 50px dla bloku głównego, 5px dla selektora td lub th oraz jedynie margines wewnętrzny górny (padding-top) 90px dla pierwszego i trzeciego bloku stopki
R.4.8 Ustawiono obramowanie selektora p 2px linią kropkowaną koloru rgb(169, 169, 169); dla td lub 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 komórki danych i komórki nagłówkowej tabeli: obramowanie 1 px, linią ciągłą o kolorze RGB 192, 192, 192; marginesy wewnętrzne 5 px
Jedna reguła dla td i th: linia ciągła (solid) w kolorze jasnoszarym (#C0C0C0) i 5 px marginesu wewnętrznego. Obramowania (R.4.8) i marginesy wewnętrzne (R.4.7) są gotowe.
R.3.1 Wygląd układu bloków po uruchomieniu strony w przeglądarce jest w pełni zgodny z obrazem 2 w arkuszu egzaminacyjnym
ok. 3 min
Polecenie z arkusza
Podział strony na bloki: dwa bloki banera, poniżej blok główny, następnie trzy bloki stopki. Podział zrealizowany za pomocą znaczników sekcji, zgodnie z obrazem 2
Pięć bloków o zadanej szerokości dostaje float: left: dwa bloki banera stają w jednym rzędzie (75% + 25%), trzy bloki stopki w drugim (20% + 60% + 20%). Blok główny ma clear: both - zaczyna się pod banerem i zajmuje całą szerokość, a bloki stopki ustawiają się pod nim. Klucz R.3.1 ocenia wygląd w przeglądarce - wersja nowoczesna pokazuje ten sam układ na flex.
Typowe błędy
Bloki o sumie szerokości 100% nie mogą mieć bocznych marginesów ani obramowań - ostatni blok rzędu spadłby niżej. Dlatego bloki stopki mają wyłącznie padding-top.
Kroki 31-38 · po tym etapie masz 37 z 37 kryteriów (pkt)
Krok 31: Skrypt 1: połączenie z bazą egzamin
Kryteria: ,
R.5.1 Skrypt napisano w języku PHP i zawiera on co najmniej jedną instrukcję poprawną składniowo
R.5.2 Skrypt1 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 airport.php. Działanie skryptu 1: Skrypt łączy się z serwerem bazodanowym na localhost, użytkownik root bez hasła, baza danych o nazwie egzamin
Skrypt 1 wypełnia tabelę, więc jego blok PHP stoi wewnątrz<table>, zaraz pod wierszem nagłówkowym - to, co wypisze, trafi dokładnie tam. Kod piszesz między <?php a ?>; serwer wykona go, zanim strona trafi do przeglądarki.
Pierwsza instrukcja: mysqli_connect z tabeli 1 arkusza - serwer localhost, użytkownik root, puste hasło '' i baza egzamin (połączenie i wybór bazy w jednej funkcji, R.5.1, R.5.2). Połączenie trafia do zmiennej $connection.
Od tego kroku podgląd to wynik działania strony na serwerze (prawdziwe uruchomienie w PHP 8.2). Stronę sprawdzasz przez http://localhost/… - przeglądarka sama nie wykona PHP.
mysqli_query wysyła zapytanie 1 przepisane z kwerendy.txt (R.5.4). Wynik - dziesięć wierszy - trafia do zmiennej $result; trzeba je jeszcze z niego pobrać.
Krok 33: Skrypt 1: pętla po wierszach i pierwsza komórka
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
mysqli_fetch_row($result) pobiera kolejny wiersz wyniku jako tablicę numerowaną od zera: $row[0] to id, $row[1] numer rejsu, $row[2] czas, $row[3] kierunek, $row[4] status,
while powtarza to, dopóki funkcja zwraca wiersz,
echo wypisuje wiersz <tr> z pierwszą komórką <td> - w napisie w cudzysłowie "…" PHP podstawia wartość $row[0], a \n kończy linię w źródle strony.
Podgląd: dziesięć wierszy z samą liczbą porządkową - kolejne kolumny dojdą w następnym kroku.
R.2.7 W bloku głównym umieszczono tabelę o pięciu kolumnach, zastosowano znaczniki <table>, <tr>, <td> i ich zamknięcia, generowane skryptem lub HTML
R.5.5 Dane otrzymane z bazy są wyświetlane w kolejnych wierszach tabeli, w odpowiednich komórkach, tak jak na Obrazie 2
ok. 2 min
Polecenie z arkusza
Dane otrzymane z bazy są umieszczane w kolejnych wierszach tabeli, w odpowiednich komórkach, tak jak na Obrazie 2
Do wiersza dochodzą cztery kolejne komórki. Każdy wiersz ma teraz pięć komórek <td> pod pięcioma nagłówkami (R.2.7), a dane stoją w odpowiednich kolumnach, od najpóźniejszego odlotu - jak na obrazie 2 (R.5.5).
R.5.7 Gdy odwiedzający jest na stronie pierwszy raz zakładane jest ciasteczko z czasem trwania 1 godzina od utworzenia, np. time() + 3600
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 1 godzina od utworzenia oraz wyświetlany jest w paragrafie, czcionką pochyloną, komunikat: „Dzień dobry! Sprawdź regulamin naszej strony”
Ciasteczko to porcja danych zapisana przez serwer w przeglądarce, którą przeglądarka odsyła przy każdym kolejnym wejściu - w PHP przysłane ciasteczka są w tablicy $_COOKIE.
isset($_COOKIE['odloty']) - prawdziwe, gdy gość już tu był; wykrzyknik ! odwraca warunek, więc blok wykona się przy pierwszej wizycie,
setcookie('odloty', 'odwiedzono', time() + 3600) - nazwa, wartość i czas wygaśnięcia: bieżący czas w sekundach plus godzina, czyli 60 × 60 = 3600 sekund (R.5.7).
Blok stoi na samej górze pliku, przed <!DOCTYPE html>: opis setcookie na ostatniej stronie arkusza mówi, że ciasteczko trzeba wysłać przed jakąkolwiek treścią strony. Komunikaty wypisze drugi blok, w stopce.
Typowe błędy
time() + 60 to minuta, nie godzina - czas w setcookie podaje się w sekundach.
Krok 37: Skrypt 2: komunikat przy pierwszej wizycie
Kryteria:
R.2.5 W pierwszym bloku banera zapisano nagłówek h2: "Odloty z lotniska", w bloku głównym nagłówek h4: "tabela odlotów" oraz w drugim bloku stopki zapisano paragraf (kodem HTML lub skryptem)
ok. 2 min
Polecenie z arkusza
Gdy odwiedzający wejdzie na stronę pierwszy raz zakładane jest ciasteczko z czasem trwania 1 godzina od utworzenia oraz wyświetlany jest w paragrafie, czcionką pochyloną, komunikat: „Dzień dobry! Sprawdź regulamin naszej strony”
W drugim bloku stopki drugi blok PHP z tym samym warunkiem: przy pierwszej wizycie echo wypisuje komunikat w paragrafie <p> (R.2.5), pochylony znacznikiem <i>. Warunek działa tak samo w obu blokach, bo setcookie nie zmienia $_COOKIE w bieżącym wykonaniu - ciasteczko wróci od przeglądarki dopiero przy następnym wejściu. Podgląd: pierwsza wizyta, „Dzień dobry! Sprawdź regulamin naszej strony” kursywą.
Krok 38: Skrypt 2: komunikat przy kolejnej wizycie
Kryteria: , ,
R.2.9 W drugim bloku stopki gdy wyświetlany jest tekst "Dzień dobry!..." czcionka jest pochylona lub gdy wyświetlony jest tekst "Miło nam..." czcionka jest pogrubiona (dowolną metodą)
R.5.6 Skrypt 2 wykorzystuje mechanizm ciasteczek, zastosowano funkcje setcookie, isset oraz 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! Sprawdź regulamin naszej strony” w przeciwnym wypadku komunikat „Miło nam że nas znowu odwiedziłeś"
ok. 3 min
Polecenie z arkusza
Jeżeli odwiedzający w ciągu godziny od poprzedniego wejścia wejdzie ponownie na stronę wyświetlany jest w paragrafie, czcionką pogrubioną, komunikat „Miło nam, że nas znowu odwiedziłeś”
Gałąź else - ciasteczko jest, czyli gość wrócił w ciągu godziny: komunikat w paragrafie, pogrubiony znacznikiem <b>. Skrypt korzysta z setcookie, isset i $_COOKIE (R.5.6), wypisuje oba komunikaty (R.5.8), jeden pochylony, drugi pogrubiony (R.2.9).
Sprawdzone na prawdziwym serwerze dwoma wejściami tej samej przeglądarki: pierwsze dało „Dzień dobry! Sprawdź regulamin naszej strony”, drugie - „Miło nam, że nas znowu odwiedziłeś”, a ciasteczko wygasa 3600 s po utworzeniu. Podgląd pokazuje drugą wizytę, jak na obrazie 2. W przeglądarce „pierwszą wizytę” powtórzysz, usuwając ciasteczko (F12, karta Aplikacja) albo w oknie prywatnym.
Typowe błędy
Formatowanie jest tu odwrotne niż w arkuszu z tablicą przylotów z tej samej sesji: pierwsza wizyta - pochylenie, kolejna - pogrubienie.
Kroki 39-41 · po tym etapie masz 37 z 37 kryteriów (pkt)
Krok 39: Zabezpieczenie: htmlspecialchars na danych z bazy
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
Skrypt wkleja do strony wszystko, co jest w bazie - także znaczniki HTML. Sprawdzone: status lotu LX5673 zmieniony na opoznienie <s>10</s> 20 min wersja z poprzednich kroków wyświetla z przekreśloną liczbą. Tak samo trafiłby na stronę znacznik <script> - kod JavaScript uruchomiony u każdego gościa tablicy odlotów (atak XSS).
htmlspecialchars zamienia <, >, & i cudzysłowy na encje, więc przeglądarka pokazuje je jako tekst; array_map przepuszcza przez nią wszystkie komórki wiersza naraz. Podgląd: ten sam status widać dosłownie. Stara linia zostaje w komentarzu; na egzaminie klucz tego nie sprawdza.
Krok 40: Zabezpieczenie: błąd bazy bez szczegółów serwera
ok. 3 min
Polecenie z arkusza
Skrypt łączy się z serwerem bazodanowym na localhost, użytkownik root bez hasła, baza danych o nazwie egzamin
Od PHP 8.1 funkcje mysqli przy błędzie rzucają wyjątek. Sprawdzone: bez bazy egzamin strona urywa się w połowie tabeli, a zamiast reszty pojawia się „Fatal error: Uncaught mysqli_sql_exception: Unknown database 'egzamin'” z pełną ścieżką do pliku na serwerze - informacja przydatna dla włamywacza, bezużyteczna dla gościa.
Skrypt 1 trafia do bloku try, a catch (mysqli_sql_exception $exception) wypisuje jeden wiersz tabeli z neutralnym komunikatem (colspan="5" - komórka na całą szerokość). Stopka i komunikat o ciasteczku działają dalej. Podgląd: strona uruchomiona bez bazy.
Gdy odwiedzający wejdzie na stronę pierwszy raz zakładane jest ciasteczko z czasem trwania 1 godzina od utworzenia
Opis setcookie w arkuszu wymienia parametr httponly: ciasteczka z tą flagą nie odczyta JavaScript na stronie, więc nie wykradnie go wstrzyknięty skrypt. Od PHP 7.3 parametry podaje się czytelniej, tablicą opcji: expires (to samo time() + 3600), httponly i samesite - Lax nie dołącza ciasteczka do żądań wysyłanych z obcych stron.
Sprawdzone w zapisie ciasteczek przeglądarki testowej: po zmianie wpis odloty ma oznaczenie HttpOnly. Wartości ciasteczka nie wolno ufać (gość może ją zmienić) i nie zapisuje się w nim danych poufnych - arkusz też to mówi. Podgląd: druga wizyta.
Krok 42 · po tym etapie masz 37 z 37 kryteriów (pkt)
Krok 42: 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 PESEL, jako przeglądarka.txt. Nagraj płytę z rezultatami pracy.
W przeglądarka.txt wpisujesz nazwę przeglądarki, w której sprawdzasz stronę przez http://localhost/…. W folderze zdającego muszą być: airport.php, import.png, kw1.jpg, kw2.jpg, kw3.jpg, kw4.jpg, kwerendy.txt, przeglądarka.txt, styl6.css i przeskalowany zad6.png. Nagraj płytę, sprawdź jej odczyt i opisz ją numerem PESEL.
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.