Serwis używa plików cookies do analizy ruchu i poprawy działania. Szczegóły
EE.09-02-22.01-SGStyczeń 2022 · 39 kroków · ok. 76 min · 33 kryteria z klucza
Rozwiązanie krok po kroku: Prognoza pogody dla Wrocławia (Wersja podstawowa)
Portal prognozy pogody: baza prognoza z tabelami miast i prognoz (import z pliku baza2.sql), cztery zapytania - prognozy dla miasta o id 1 posortowane według daty, rekordy z opadami powyżej 30 mm/h, zimne noce z nazwą miasta wybraną przez relację (JOIN) i dodanie kolumny do tabeli miast (ALTER TABLE). Do tego logo przeskalowane do 80 px z zachowaniem przezroczystości, mapa przeskalowana do 200 px, strona pogoda.php z trzema blokami banera, tabelą prognoz, mapą, odnośnikiem i stopką, style w styl2.css oraz skrypt, który wypełnia tabelę danymi z bazy.
To arkusz EE.09 ze stycznia 2022 - kwalifikacji formuły 2017, którą zastąpiła INF.03. 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 najpierw napisany najprościej, funkcjami mysqli z tabeli 1 arkusza, a na końcu sprawdzony na prawdziwej awarii bazy 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 we flex, PDO z obsługą błędów, skrypt na górze pliku i tabela z sekcjami <thead> i <tbody> - obie wersje są zgodne z kluczem.
Baza i grafiki pochodzą z oryginalnego archiwum CKE pliki2.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. Podgląd od kroków ze skryptem to wynik prawdziwego uruchomienia kodu w PHP 8.2 (klucz każe sprawdzać w XAMPP 8.0.7 - użyte funkcje działają w obu wersjach tak samo).
Jak liczą się punkty. Klucz ma 33 kryteria (R.1.1 - R.5.4), każde za 1 punkt. Próg zdania części praktycznej to 75%, czyli 25 punktów (75% z 33 to 24,75, zaokrąglone w górę) - można stracić 8 kryteriów i nadal zdać. Przy każdym kroku jest napisane, które kryteria spełnia.
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 33 kryteriów (pkt)
Krok 1: Folder zdającego i archiwum pliki2.zip
ok. 2 min
Polecenie z arkusza
Należy utworzyć folder o nazwie odpowiadającej numerowi PESEL zdającego lub w przypadku jego braku innemu numerowi, którym został podpisany arkusz. Archiwum należy rozpakować do tego folderu.
Na pulpicie tworzysz folder nazwany numerem PESEL - w tym rozwiązaniu w jego miejscu stoi imię i nazwisko autora, Bartosz Bryniarski. Archiwum pliki2.zip rozpakowujesz do tego folderu, podając hasło 3MeTeo# (wielkość liter ma znaczenie). W środku są trzy pliki: baza2.sql, logo.png i obraz.jpg.
Do tego folderu trafia wszystko, co powstanie: zrzuty, kwerendy.txt, plik strony i plik stylów.
Krok 2: XAMPP i baza prognoza
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 prognoza
W XAMPP Control PanelStart przy Apache i MySQL, w przeglądarce http://localhost/phpmyadmin. Nowa, nazwa prognoza, porównywanie np. utf8mb4_polish_ci, Utwórz.
Typowe błędy
Skrypt łączy się z bazą po nazwie - literówka w nazwie bazy to brak danych w tabeli strony.
Krok 3: Import pliku baza2.sql i zrzut import.png
Kryteria:
R.1.1 Wykonano import tabel do bazy danych prognoza , 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 prognoza zaimportuj tabele z pliku baza2.sql z rozpakowanego archiwum. Wykonaj zrzut ekranu po imporcie. Zrzut zapisz w folderze z numerem PESEL lub w przypadku jego braku w folderze z innym numerem, którym został podpisany arkusz, 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
Zaznacz bazę prognoza, karta Import, Wybierz plik → baza2.sql, Wykonaj. Po komunikacie „Import zakończył się sukcesem” w lewym panelu jest 12 tabel - zadanie używa dwóch: miasta (15 miast) i pogoda (17 prognoz). Zrzut całego ekranu z komunikatem i listą tabel: import.png.
Typowe błędy
Ten zrzut ma format PNG, zrzuty zapytań - JPEG. Wykadrowany zrzut albo zrzut bez paska zadań nie jest oceniany.
Podgląd strony po tym kroku
Krok 4: Zapytanie 1: prognozy dla miasta o id 1 według daty
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 wszystkie pola z tabeli pogoda dla miast o id równym 1, posortowane rosnąco według daty prognozy. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT * FROM pogoda WHERE miasta_id=1 ORDER BY data_prognozy; (lub po SELECT wymienione wszystkie pola) oraz wynik działania zapytania udokumentowano zrzutem, na którym widocznych jest dokładnie 9 rekordów, kolejno z id 2, 3, 4, 5, 6, 7, 8, 9, 1; wyświetlone wszystkie kolumny
ok. 3 min
Polecenie z arkusza
Zapytanie 1: wybierające wszystkie pola z tabeli pogoda dla miast o id równym 1, posortowane rosnąco według daty prognozy
Karta SQL bazy prognoza. Zapytanie klauzula po klauzuli:
SELECT * - wszystkie pola,
FROM pogoda,
WHERE miasta_id = 1 - „miasta o id równym 1” to w tabeli pogoda kolumna miasta_id (klucz obcy do tabeli miasta), a nie kolumna id prognozy,
ORDER BY data_prognozy - sortowanie rosnąco jest domyślne, więc ASC można pominąć.
Wynik: 9 rekordów, kolejno z id 2, 3, 4, 5, 6, 7, 8, 9 i 1 - rekord 1 ma najpóźniejszą datę (31 maja), więc trafia na koniec. To jest dokładnie kolejność z klucza i z tabeli na obrazie 2. Zapytanie kopiujesz do kwerendy.txt (R.1.2), zrzut zapisujesz jako kw1.jpg.
Typowe błędy
WHERE id = 1 zwraca jeden rekord - prognozę o numerze 1, a nie prognozy miasta o numerze 1.
kwerendy.txtTekstnowy plik
-- Zapytanie 1SELECT * FROM pogoda WHERE miasta_id = 1 ORDER BY data_prognozy;
Podgląd strony po tym kroku
Krok 5: Zapytanie 2: opady powyżej 30 mm/h
Kryteria:
R.1.4 Utworzono zapytanie 2 wybierające jedynie pola id oraz data_prognozy z tabeli pogoda dla tych rekordów, dla których opady przekraczają 30 mm/h. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT id, data_prognozy FROM pogoda WHERE opady > 30; oraz wynik działania zapytania udokumentowano zrzutem, na którym widoczne są dokładnie 3 rekordy o id 1, 7, 8; jedynie pola id, data_prognozy
ok. 2 min
Polecenie z arkusza
Zapytanie 2: wybierające jedynie pola id oraz data_prognozy z tabeli pogoda dla tych rekordów, dla których opady przekraczają 30 mm/h
SELECT id, data_prognozy - tylko dwie kolumny,
WHERE opady > 30 - „przekraczają” to ostro większe; kolumna przechowuje same liczby, jednostka mm/h jest tylko w opisie.
Wynik: 3 rekordy o id 1, 7 i 8 (33, 33 i 32 mm/h). Trzy prognozy dla Poznania mają dokładnie 30 mm/h i do wyniku nie wchodzą. Zrzut: kw2.jpg.
Typowe błędy
opady >= 30 dołoży trzy rekordy z wartością 30 - razem 6 zamiast 3.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT * FROM pogoda WHERE miasta_id = 1 ORDER BY data_prognozy;-- Zapytanie 2SELECT id, data_prognozy FROM pogoda WHERE opady > 30;
Podgląd strony po tym kroku
Krok 6: Zapytanie 3: zimne noce z nazwą miasta
Kryteria:
R.1.5 Utworzono zapytanie 3 wybierające jedynie pola data_prognozy, temperatura_noc z tabeli pogoda oraz nazwa z tabeli miasta dla temperatur nocnych poniżej 6 stopni. Zapytanie wykorzystuje relację. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT data_prognozy, temperatura_noc, nazwa FROM pogoda JOIN miasta ON miasta.id = pogoda.miasta_id WHERE temperatura_noc < 6; możliwe też INNER JOIN lub SELECT data_prognozy, temperatura_noc, nazwa FROM pogoda, miasta WHERE miasta.id = pogoda.miasta_id AND temperatura_noc < 6; oraz wynik działania zapytania udokumentowano zrzutem, na którym widoczne są dokładnie 3 rekordy z danymi: 2019-05-14 5 Wrocław; 2019-05-12 5 Poznań; 2019-05-13 5 Poznań
ok. 4 min
Polecenie z arkusza
Zapytanie 3: wybierające jedynie pola data_prognozy, temperatura_noc z tabeli pogoda oraz nazwa z tabeli miasta dla temperatur nocnych poniżej 6 stopni. Zapytanie wykorzystuje relację
Nazwa miasta jest w innej tabeli niż prognoza, więc potrzebna jest relacja:
SELECT data_prognozy, temperatura_noc, nazwa - trzy kolumny z dwóch tabel; nazwy są jednoznaczne, więc nie trzeba ich poprzedzać nazwą tabeli,
FROM pogoda JOIN miasta - złączenie tabel,
ON miasta.id = pogoda.miasta_id - prognoza łączy się z miastem, którego numer ma w kolumnie miasta_id,
WHERE temperatura_noc < 6 - „poniżej 6” to ostro mniejsze.
Wynik: 3 rekordy - 2019-05-14, 5 stopni, Wrocław oraz 2019-05-12 i 2019-05-13, 5 stopni, Poznań. Zrzut: kw3.jpg. Klucz przyjmuje też zapis z tabelami po przecinku i warunkiem relacji w WHERE.
⚠️ Rozbieżność arkusz-klucz: klucz podaje w wyniku „Wrocław” i „Poznań”, a w pliku baza2.sql nazwy tych miast są zapisane bez polskich liter - Wroclaw i Poznan (inne miasta, np. Kraków, mają je poprawnie). Wynik na zrzucie pokazuje to, co jest w bazie, i jest zgodny z kluczem - liczy się zestaw rekordów, a nie pisownia nazwy.
Typowe błędy
temperatura_noc <= 6 dokłada cztery noce z temperaturą 6 stopni. Bez warunku relacji każda prognoza łączy się z każdym z 15 miast.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT * FROM pogoda WHERE miasta_id = 1 ORDER BY data_prognozy;-- Zapytanie 2SELECT id, data_prognozy FROM pogoda WHERE opady > 30;-- Zapytanie 3SELECT data_prognozy, temperatura_noc, nazwa FROM pogoda JOIN miasta ON miasta.id = pogoda.miasta_id WHERE temperatura_noc < 6;
Podgląd strony po tym kroku
Krok 7: Zapytanie 4: kolumna wojewodztwo w tabeli miasta
Kryteria:
R.1.6 Utworzono zapytanie 4 dodające do tabeli miasta kolumnę wojewodztwo typu tekstowego. W pliku z kwerendami lub na zrzucie istnieje zapis np.: ALTER TABLE miasta ADD COLUMN wojewodztwo text; możliwe inne dowolne typy napisowe oraz wynik działania zapytania udokumentowano zrzutem, na którym widoczne jest poprawnie wykonane zapytanie lub tabela z dodaną kolumną
ok. 3 min
Polecenie z arkusza
Zapytanie 4: dodające do tabeli miasta kolumnę wojewodztwo dowolnego typu tekstowego
ALTER TABLE miasta - zmiana struktury istniejącej tabeli,
ADD COLUMN wojewodztwo TEXT - nowa kolumna typu tekstowego. Klucz przyjmuje dowolny typ napisowy, np. VARCHAR(50). Nazwa bez polskiej litery, tak jak w arkuszu.
phpMyAdmin odpowiada „MySQL zwrócił pusty wynik”. Żeby zrzut kw4.jpg pokazywał efekt, pod zapytaniem 4 dopisz w tej samej karcie SQLSHOW COLUMNS FROM miasta; - widać trzy kolumny, ostatnia to wojewodztwo typu text. Klucz przyjmuje też zrzut samej struktury tabeli z karty Struktura. Do kwerendy.txt trafia tylko zapytanie 4.
Typowe błędy
Drugie wykonanie tego samego zapytania kończy się błędem #1060 „Zduplikowana nazwa kolumny” - kolumna już istnieje, a pierwszy zrzut z poprawnym wykonaniem wystarcza.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT * FROM pogoda WHERE miasta_id = 1 ORDER BY data_prognozy;-- Zapytanie 2SELECT id, data_prognozy FROM pogoda WHERE opady > 30;-- Zapytanie 3SELECT data_prognozy, temperatura_noc, nazwa FROM pogoda JOIN miasta ON miasta.id = pogoda.miasta_id WHERE temperatura_noc < 6;-- Zapytanie 4ALTER TABLE miasta ADD COLUMN wojewodztwo TEXT;
Podgląd strony po tym kroku
Etap 2: Grafika i strona HTML
Kroki 8-21 · po tym etapie masz 17 z 33 kryteriów (pkt)
Krok 8: Logo: wysokość 80 px z zachowaniem przezroczystości
Kryteria: ,
R.2.1 Plik logo.png przeskalowano z zachowaniem proporcji tak, że jego wysokość wynosi dokładnie 80 px, odpowiadająca temu szerokość wynosi 84 px ±5 px
R.2.3 Plik logo.png ma przezroczyste tło
ok. 2 min
Polecenie z arkusza
Plik logo.png, wypakowany z archiwum, należy przeskalować z zachowaniem proporcji tak, aby jego wysokość wynosiła dokładnie 80 px; plik ma zachować przezroczystość
Oryginał ma 315 × 300 px i przezroczyste tło (kanał alfa). W GIMP-ie Obraz → Skaluj obraz, łańcuch zamknięty, wysokość 80 px - szerokość przelicza się na 315 × 80 / 300 = 84 px (klucz: 84 px ±5). Zapis: Plik → Nadpisz logo.png.
Przezroczystość zostaje, bo plik nadal jest w formacie PNG z kanałem alfa - na stronie słońce stoi wprost na niebieskim tle banera, bez białego prostokąta (R.2.3).
Typowe błędy
Eksport do JPEG albo spłaszczenie obrazu (Obraz → Spłaszcz obraz) zamienia przezroczyste tło na białe - brak punktu R.2.3.
Podgląd strony po tym kroku
Krok 9: Mapa: wysokość 200 px
Kryteria:
R.2.2 Plik obraz.jpg przeskalowano z zachowaniem proporcji tak, że jego wysokość wynosi dokładnie 200 px, odpowiadająca temu szerokość wynosi 200 px ±5 px
ok. 2 min
Polecenie z arkusza
Plik obraz.jpg, wypakowany z archiwum, należy przeskalować z zachowaniem proporcji tak, aby jego wysokość wynosiła dokładnie 200 px
Obraz jest kwadratowy (358 × 358 px), więc przy wysokości 200 px szerokość też wynosi 200 px (klucz: 200 px ±5). Obraz → Skaluj obraz, łańcuch zamknięty, potem Plik → Nadpisz obraz.jpg. Wysokość równa wysokości dolnych bloków (200 px) - mapa wypełni blok od góry do dołu.
Podgląd strony po tym kroku
Krok 10: Plik pogoda.php i kodowanie polskich znaków
Kryteria:
R.2.4 Witrynę internetową zapisano w pliku o nazwie pogoda.php oraz zastosowano właściwy standard kodowania polskich znaków
ok. 2 min
Polecenie z arkusza
Składa się ze strony o nazwie pogoda.php. Zastosowany właściwy standard kodowania polskich znaków
Strona od razu ma rozszerzenie .php - wiersze tabeli wypełni skrypt w tym samym pliku. Dopóki w pliku nie ma kodu PHP, serwer odda go jak zwykły HTML. <meta charset="UTF-8"> w <head> i plik zapisany w UTF-8 - nazwa pliku i kodowanie to razem R.2.4.
Stronę sprawdzasz przez http://localhost/…/pogoda.php - po otwarciu z dysku przeglądarka pokazałaby kod PHP zamiast go wykonać.
R.3.3 Strona zawiera działające połączenie z zewnętrznym arkuszem stylów o nazwie styl2.css , formatowanie 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. 1 min
Polecenie z arkusza
Arkusz stylów w pliku o nazwie styl2.css prawidłowo połączony z kodem strony
<link rel="stylesheet" href="styl2.css"> - w nazwie nie ma podkreślenia (R.3.3). Plik stylów powstanie po HTML-u.
Typowe błędy
Klucz odbiera R.3.3 także wtedy, gdy choć jeden selektor nie trafia w blok - np. kropka w CSS zamiast # przy bloku z identyfikatorem.
Krok 13: Bloki: trzy banera, główny, lewy, prawy i stopka
Kryteria:
R.2.6 Wygląd strony zdefiniowano dzieląc ją na bloki: trzy bloki banera (lewy, środkowy i prawy), blok główny, bloki lewy i prawy, blok stopki. Zastosowano znaczniki sekcji
ok. 2 min
Polecenie z arkusza
Podział strony na bloki: na górze trzy bloki banera: lewy, środkowy, prawy, poniżej blok główny, poniżej dwa bloki: lewy i prawy, na dole blok stopki. 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
Siedem bloków w kolejności z obrazu 2: sześć znaczników <section> i <footer> na stopkę. Każda sekcja ma identyfikator, bo w CSS dostaną różne szerokości: banner-left, banner-middle, banner-right, main, left i right (nazwy po angielsku - arkusz ich nie narzuca). Stopka jest na stronie jedna, więc wystarczy selektor znacznika footer (R.2.6). Ułożenie bloków obok siebie zrobi CSS.
R.2.9 W tabeli umieszczono wiersz nagłówkowy zawierający wpisy: „DATA”, „TEMPERATURA W NOCY”, „TEMPERATURA W DZIEŃ”, „OPADY [mm/h]”, „CIŚNIENIE [hPa]”. zastosowano znaczniki <tr>, <th> oraz ich zamknięcia (możliwe zastosowanie <thead>)
ok. 2 min
Polecenie z arkusza
Wiersz nagłówkowy tabeli zawiera wpisy: „DATA”, „TEMPERATURA W NOCY”, „TEMPERATURA W DZIEŃ”, „OPADY [mm/h]”, „CIŚNIENIE [hPa]”
Jeden wiersz <tr> z pięcioma komórkami nagłówka <th> - przeglądarka pogrubia je i wyśrodkowuje, a czytnik ekranu odczytuje jako nazwy kolumn (R.2.9). Kolejność kolumn decyduje o tym, w jakiej kolejności skrypt wypisze dane.
Typowe błędy
<td> zamiast <th> w pierwszym wierszu - klucz wymaga znaczników <th> (albo sekcji <thead>), a styl komórek nagłówka z R.4.10 nie trafi w zwykłe komórki.
R.2.10 W bloku lewym banera umieszczono obraz logo.png wraz z tekstem alternatywnym "meteo" oraz w bloku lewym umieszczono obraz.jpg z tekstem alternatywnym "Polska, Wrocław"
ok. 1 min
Polecenie z arkusza
Zawartość bloku lewego: obraz.jpg z tekstem alternatywnym o treści „Polska, Wrocław”
Drugi obraz strony: alt="Polska, Wrocław". Oba obrazy z właściwymi tekstami alternatywnymi - R.2.10.
Krok 20: Blok prawy: odnośnik do pliku kwerendy.txt
Kryteria:
R.3.2 Po wybraniu odnośnika "Pobierz kwerendy" otwiera się lub pobiera plik kwerendy
ok. 1 min
Polecenie z arkusza
Zawartość bloku prawego: odnośnik do pliku kwerendy.txt z treścią: „Pobierz kwerendy”
href="kwerendy.txt" - ścieżka względna: plik leży w tym samym folderze co strona. Przeglądarka otworzy go jako tekst albo zaproponuje pobranie (R.3.2). Dlatego kwerendy.txt musi być w folderze strony.
R.2.7 W bloku środkowym banera zapisano nagłówek h1: "Prognoza dla Wrocławia" oraz w bloku prawym banera paragraf: "maj, 2019 r." oraz w stopce paragraf o treści: „Stronę wykonał: ”, dalej wstawiony numer PESEL zdającego lub w przypadku jego braku inny numer, którym został podpisany arkusz
ok. 1 min
Polecenie z arkusza
Zawartość bloku stopki: akapit (paragraf) o treści: „Stronę wykonał: ”, dalej wstawiony numer PESEL zdającego lub w przypadku jego braku inny numer, którym został podpisany arkusz
Na egzaminie po dwukropku wpisujesz PESEL; tu w jego miejscu stoi Bartosz Bryniarski. Z nagłówkiem <h1> i paragrafem w prawym bloku banera daje to R.2.7.
Kroki 22-31 · po tym etapie masz 28 z 33 kryteriów (pkt)
Krok 22: Plik styl2.css: krój Helvetica dla całej strony
Kryteria:
R.4.1 Ustawiono domyślny krój czcionki dla całej strony na Helvetica (dla selektora * lub body lub html lub kontenera całej strony)
ok. 1 min
Polecenie z arkusza
Cechy formatowania CSS: Są zawarte wyłącznie w zewnętrznym arkuszu stylów. Domyślne dla całej strony: krój czcionki Helvetica
Nowy plik styl2.css w folderze zdającego - każda reguła tylko tutaj. Selektor * z font-family: Helvetica obejmuje wszystkie elementy (R.4.1). Helvetica jest fontem komputerów Apple - na Windows przeglądarka zastąpi ją krojem bezszeryfowym, np. Arialem, który wygląda niemal tak samo.
styl2.cssCSSnowy plik
* {font-family: Helvetica;}
Podgląd strony po tym kroku (pogoda.php)
Krok 23: Lewy i prawy blok banera: wspólna reguła
ok. 2 min
Polecenie z arkusza
Wspólne dla lewego i prawego bloku banera: kolor tła RGB 70, 130, 180; biały kolor czcionki, szerokość 25%, wysokość 80 px
Dwa selektory identyfikatorów po przecinku, jedna reguła. Kolor podany jako rgb(70, 130, 180) - trzy składowe z arkusza w kolejności czerwony, zielony, niebieski (to odcień nazywany SteelBlue). Wysokość 80 px - tyle co logo.
R.4.4 Ustawiono wysokość wszystkich bloków banera 80px oraz bloku lewego i prawego 200px
R.4.5 Ustawiono szerokość bloku lewego i prawego banera 25% oraz bloku środkowego banera, bloku lewego i prawego 50%
R.4.6 Ustawiono wyrównanie tekstu do środka dla środkowego bloku banera, bloku lewego i prawego
ok. 2 min
Polecenie z arkusza
Dla bloku lewego i bloku prawego: kolor tła RGB 70, 130, 180; szerokość 50%, wysokość 200 px, wyrównanie tekstu do środka
Wspólna reguła dla dwóch dolnych bloków. Arkusz nie podaje tu koloru czcionki - odnośnik zostaje w domyślnym kolorze odnośnika, jak na obrazie 2. Komplet: wysokości 80 i 200 px (R.4.4), szerokości 25, 50 i 50% (R.4.5) i wyśrodkowanie środkowego bloku banera oraz bloków lewego i prawego (R.4.6) - dlatego mapa i odnośnik stoją pośrodku swoich bloków.
R.3.1 Układ bloków po uruchomieniu strony w przeglądarce jest 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)
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
Pięć bloków, które stoją obok siebie, dostaje float: left: trzy bloki banera (razem 100%) i dwa dolne (razem 100%) - każda trójka i para wypełnia jeden rząd.
Blok główny i stopka zajmują całą szerokość i muszą zacząć się pod pływającymi blokami - stąd clear: both. Bez niego blok główny wsunąłby się pod baner, a stopka pod mapę (R.3.1). Klucz przyjmuje też flex albo grid - wersja nowoczesna pokazuje układ we flex.
Typowe błędy
Bez clear na stopce jej tło przykryje dolne bloki, a tekst ułoży się obok mapy.
Krok 29: Tabela: obramowanie, szerokość, połączone linie
Kryteria:
R.4.8 Ustawiono styl znacznika tabeli: szerokość 100%, border-collapse: collapse; obramowanie 1px solid koloru niebieskiego (selektor table lub klasa lub identyfikator)
ok. 2 min
Polecenie z arkusza
Dla znacznika tabeli: obramowanie 1 px, linią ciągłą o niebieskim kolorze, szerokość 100%, obramowanie połączone za pomocą jednej linii, jak na Obrazie 2
border: 1px solid blue - szerokość, linia ciągła, kolor. border-collapse: collapse - sąsiednie komórki mają jedną wspólną linię zamiast dwóch równoległych (R.4.8).
R.4.10 Ustawiono styl znacznika komórki nagłówka tabeli: niebieski kolor tła, biały kolor czcionki, obramowanie 1px solid; kolor obramowania niebieski (selektor th lub klasa); możliwe alternatywne rozwiązanie, np. przypisanie tego stylu tylko do pierwszego wiersza tabeli lub do thead
ok. 1 min
Polecenie z arkusza
Dla znacznika komórki nagłówka tabeli: obramowanie 1 px, linią ciągłą o niebieskim kolorze, kolor tła niebieski, kolor czcionki biały
Selektor th - białe napisy na niebieskim tle, jak na obrazie 2 (R.4.10). Arkusz stylów jest kompletny.
Kroki 32-36 · po tym etapie masz 33 z 33 kryteriów (pkt)
Krok 32: Miejsce skryptu i połączenie z bazą prognoza
Kryteria:
R.5.1 Skrypt realizuje połączenie z serwerem bazy danych i wybór bazy prognoza
ok. 3 min
Polecenie z arkusza
Napisany w języku PHP. Skrypt łączy się z serwerem bazodanowym na localhost, użytkownik root bez hasła, baza danych o nazwie prognoza
Wiersze danych mają się pojawić w tabeli, pod wierszem nagłówkowym - dlatego skrypt stoi w <table>, między zamknięciem pierwszego </tr> a </table>. Wszystko, co wypisze, trafi w to miejsce strony.
Pierwsza instrukcja: mysqli_connect z tabeli 1 - serwer localhost, użytkownik root, puste hasło '' i baza prognoza (R.5.1). Od tego kroku podgląd to wynik prawdziwego uruchomienia pogoda.php - tabela ma na razie sam nagłówek.
mysqli_query wysyła zapytanie 1 z kwerendy.txt, przepisane bez zmian (R.5.3). Wynik - dziewięć prognoz Wrocławia - czeka w zmiennej $result; na stronie jeszcze nic się nie zmienia.
Typowe błędy
Zapytanie jest w apostrofach '…', więc w środku nie może być apostrofów - tu ich nie ma, bo warunek porównuje liczby.
pogoda.phpPHPzmienione: 1 linia
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Prognoza pogody Wrocław</title> <linkrel="stylesheet"href="styl2.css"></head><body> <sectionid="banner-left"> <imgsrc="logo.png"alt="meteo"> </section> <sectionid="banner-middle"> <h1>Prognoza dla Wrocławia</h1> </section> <sectionid="banner-right"> <p>maj, 2019 r.</p> </section> <sectionid="main"> <table> <tr> <th>DATA</th> <th>TEMPERATURA W NOCY</th> <th>TEMPERATURA W DZIEŃ</th> <th>OPADY [mm/h]</th> <th>CIŚNIENIE [hPa]</th> </tr><?php$connection = mysqli_connect('localhost', 'root', '', 'prognoza');$result = mysqli_query($connection, 'SELECT * FROM pogoda WHERE miasta_id = 1 ORDER BY data_prognozy;');?> </table> </section> <sectionid="left"> <imgsrc="obraz.jpg"alt="Polska, Wrocław"> </section> <sectionid="right"> <ahref="kwerendy.txt">Pobierz kwerendy</a> </section> <footer> <p>Stronę wykonał: Bartosz Bryniarski</p> </footer></body></html>
Każdy zwrócony zapytaniem wiersz jest wyświetlany w osobnym wierszu tabeli w bloku głównym. Dane pobrane z bazy należy umieścić w odpowiednich kolumnach tabeli zgodnie z Obrazem 2
mysqli_fetch_row pobiera kolejny wiersz wyniku jako tablicę numerowaną od 0, a gdy wierszy już nie ma, zwraca null - wtedy pętla while się kończy,
każdy wiersz wyniku to jeden wiersz tabeli: echo '<tr>' na początku i echo '</tr>' na końcu.
SELECT * zwraca kolumny w kolejności z tabeli: [0] id, [1] miasta_id, [2] data_prognozy, [3] temperatura_noc, [4] temperatura_dzien, [5] opady, [6] cisnienie. Tabela na obrazie 2 nie pokazuje dwóch pierwszych, więc pierwsza komórka to $row[2] - data. Podgląd: dziewięć wierszy z samymi datami, od 10 do 31 maja.
Krok 35: Pozostałe kolumny: temperatury, opady, ciśnienie
Kryteria: ,
R.5.4 Skrypt wyświetla każdy zwrócony zapytaniem rekord w osobnym wierszu tabeli w bloku głównym. Dane pobrane z bazy umieszczono w odpowiednich kolumnach tabeli
R.2.8 W bloku głównym umieszczono tabelę o 5 kolumnach oraz zastosowano znaczniki <table>, <tr>, <td> oraz ich zamknięcia (w kodzie HTML lub skrypcie)
ok. 3 min
Polecenie z arkusza
Każdy zwrócony zapytaniem wiersz jest wyświetlany w osobnym wierszu tabeli w bloku głównym. Dane pobrane z bazy należy umieścić w odpowiednich kolumnach tabeli zgodnie z Obrazem 2
Cztery kolejne komórki <td> z indeksami 3, 4, 5 i 6 - w tej samej kolejności co nagłówki: noc, dzień, opady, ciśnienie. Każdy rekord jest w osobnym wierszu, a dane w swoich kolumnach (R.5.4); tabela ma pięć kolumn ze znacznikami <table>, <tr>, <td> i ich zamknięciami (R.2.8).
Podgląd odpowiada obrazowi 2: pierwszy wiersz to 2019-05-10, 15, 23, 0, 1020, a ostatni - 2019-05-31, 15, 23, 33, 1020.
Typowe błędy
mysqli_fetch_array zamiast fetch_row też działa z indeksami liczbowymi. Indeksy przesunięte o jeden ($row[1] jako data) wpisują numer miasta w kolumnę DATA - wiersze są, ale dane nie w swoich kolumnach.
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 - ostatnia operacja na bazie (R.5.2). Skrypt spełnia wszystkie kryteria arkusza. Dalej dwa kroki o zabezpieczeniach - klucz ich nie wymaga.
Kroki 37-38 · po tym etapie masz 33 z 33 kryteriów (pkt)
Krok 37: Zabezpieczenie: awaria bazy bez komunikatu PHP
ok. 4 min
Polecenie z arkusza
Skrypt łączy się z serwerem bazodanowym na localhost, użytkownik root bez hasła, baza danych o nazwie prognoza
Sprawdzone na wersji z poprzednich kroków: wystarczy literówka w nazwie bazy (prognoz) albo zatrzymany serwer MySQL, żeby PHP przerwał stronę komunikatem „Fatal error: Uncaught mysqli_sql_exception: Unknown database”. Komunikat zawiera pełną ścieżkę pliku na serwerze i numer linii, a strona urywa się w środku tabeli - bez mapy, odnośnika i stopki. Takie informacje pomagają atakującemu poznać budowę serwera.
Poprawka:
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT) - każdy błąd bazy rzuca wyjątek; w PHP 8.1 i nowszych to ustawienie domyślne, w PHP 8.0 z klucza trzeba je włączyć,
operacje na bazie w bloku try, a w catch jeden wiersz tabeli na całą szerokość (colspan="5") ze zdaniem dla użytkownika. Reszta strony renderuje się normalnie,
każda wartość przed wypisaniem przechodzi przez htmlspecialchars - tutaj to liczby i daty, ale gdyby do tabeli trafiła kolumna tekstowa wpisywana przez kogoś innego (np. nazwa miasta), znacznik <script> w danych nie wykona się na stronie.
Stare linie zostają w komentarzu. Na egzaminie wystarczy wersja wcześniejsza - klucz tego nie sprawdza. Podgląd: strona przy działającej bazie wygląda tak samo jak wcześniej.
Typowe błędy
@ przed nazwą funkcji (@mysqli_connect) tylko wycisza ostrzeżenie - skrypt dalej się wywraca, a błąd znika też z dziennika serwera.
Skrypt łączy się z serwerem bazodanowym na localhost, użytkownik root bez hasła, baza danych o nazwie prognoza
Strona tylko czyta prognozy, a łączy się kontem root bez hasła - administratorem całego serwera baz. Arkusz tego wymaga (R.5.1) i na egzaminie tak zostaje. W prawdziwym serwisie każdy błąd w skrypcie, który pozwoliłby wstrzyknąć SQL, dawałby wtedy pełną władzę nad wszystkimi bazami.
Zasada najmniejszych uprawnień - osobne konto z hasłem, które może tylko odczytać jedną tabelę:
CREATE USER 'pogoda'@'localhost' IDENTIFIED BY 'Wr0claw-maj-2019!';
GRANT SELECT ON prognoza.pogoda TO 'pogoda'@'localhost';
Sprawdzone na prawdziwej bazie: strona z tym kontem wyświetla tabelę bez zmian, a próba DROP TABLE pogoda kończy się błędem „DROP command denied”, tak samo jak odczyt innej tabeli (miasta). Hasło w tym przykładzie służy do nauki - na serwerze konto dostaje długie losowe hasło, a dane logowania leżą w pliku poza folderem strony. Do pliku egzaminacyjnego nic z tego nie przenosisz - plik skryptu bez zmian.
Krok 39 · po tym etapie masz 33 z 33 kryteriów (pkt)
Krok 39: Plik przeglądarka.txt i nagranie płyty
ok. 5 min
Polecenie z arkusza
UWAGA: po zakończeniu pracy utwórz w folderze z numerem PESEL lub w przypadku jego braku w folderze z innym numerem, którym został podpisany arkusz plik tekstowy o nazwie przeglądarka.txt. Zapisz w nim nazwę przeglądarki internetowej, w której weryfikowano poprawność działania witryny. Nagraj płytę z rezultatami pracy.
W przeglądarka.txt wpisujesz nazwę przeglądarki, w której sprawdzasz stronę przez http://localhost/…/pogoda.php.
W folderze z numerem zdającego muszą być: import.png, kw1.jpg, kw2.jpg, kw3.jpg, kw4.jpg, kwerendy.txt, logo.png, obraz.jpg, pogoda.php, przeglądarka.txt i styl2.css. Nagraj płytę, sprawdź jej odczyt w obecności przewodniczącego zespołu nadzorującego 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.