Serwis używa plików cookies do analizy ruchu i poprawy działania. Szczegóły
EE.09-01-20.06-SGCzerwiec 2020 · 39 kroków · ok. 77 min · 34 kryteria z klucza
Rozwiązanie krok po kroku: Organizer z wpisami zadań (Wersja podstawowa)
Organizer na sierpień 2020: baza egzamin6 z tabelą zadania (import pliku baza5.sql), cztery zapytania - wybór zadań z sierpnia, miesiąca i roku dla jednej daty, wpisów bez powtórzeń kończących się literą „o” (DISTINCT, LIKE) oraz zmiana wpisu jednego dnia (UPDATE). Do tego logo przeskalowane do 100 × 100 px, strona organizer.php z trzema blokami banera, formularzem i blokami kolejnych dni generowanymi przez skrypt, style w styl6.css oraz skrypt PHP, który wyświetla dni sierpnia, podpis miesiąca w stopce i zapisuje wpis z formularza do bazy.
To arkusz EE.09 z czerwca 2020 - kwalifikacji formuły 2017, którą zastąpiła INF.03. Z tego samego archiwum egzamin5.zip korzysta też arkusz EE.09-03 z tej sesji (kalendarz na lipiec) - baza jest ta sama, ale polecenia i klucz 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 najpierw napisany najprościej, funkcjami mysqli z tabeli 1 arkusza, a na końcu sprawdzony na prawdziwym wstrzyknięciu SQL i zabezpieczony.
To jest wersja podstawowa. W zakładce „Nowoczesny kod (flex, grid, PDO)” jest drugi sposób rozwiązania tego samego arkusza: semantyczne znaczniki, układ bez float, PDO z zapytaniem przygotowanym na górze pliku i przekierowanie po zapisie - obie wersje są zgodne z kluczem.
Baza i grafiki pochodzą z oryginalnego archiwum CKE egzamin5.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 34 kryteria (R.1.1 - R.5.8), każde za 1 punkt. Próg zdania części praktycznej to 75%, czyli 26 punktów - 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.
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 34 kryteriów (pkt)
Krok 1: Folder zdającego i archiwum egzamin5.zip
ok. 2 min
Polecenie z arkusza
Na pulpicie znajdziesz archiwum ZIP o nazwie egzamin5.zip zabezpieczone hasłem: kaL(end)arz% 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 egzamin5.zip rozpakowujesz (np. 7-Zipem), podając hasło kaL(end)arz% - wielkość liter, nawiasy i znak procentu mają znaczenie. W środku są trzy pliki: baza5.sql (tabela do importu), logo1.png i logo2.png. W tym zadaniu potrzebne jest tylko logo2.png - logo1.png należy do bliźniaczego arkusza z kalendarzem.
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.
Krok 2: XAMPP i pusta baza egzamin6
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 egzamin6
W XAMPP Control Panel klikasz Start przy Apache i MySQL, potem w przeglądarce otwierasz http://localhost/phpmyadmin. Nowa w lewym panelu, nazwa egzamin6, Utwórz.
Uwaga na numer: archiwum nazywa się egzamin5.zip, plik baza5.sql, a baza ma się nazywać egzamin6 - tak jest w arkuszu i w kluczu (R.1.1, R.5.1). Te trzy numery celowo się różnią, łatwo wpisać odruchowo egzamin5.
Typowe błędy
Baza egzamin5 zamiast egzamin6 to strata R.1.1 i R.5.1 - skrypt łączy się z bazą po nazwie.
Krok 3: Import pliku baza5.sql i zrzut import.png
Kryteria:
R.1.1 Wykonano import tabel do bazy danych egzamin6 , czynność udokumentowano plikiem o nazwie import w formacie PNG. Zrzut zawiera cały obszar ekranu monitora z widocznym paskiem zadań
ok. 3 min
Polecenie z arkusza
Do bazy egzamin6 zaimportuj tabele z pliku baza5.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ę egzamin6, karta Import, Wybierz plik → baza5.sql, Wykonaj. Plik zawiera polecenie CREATE TABLE zadania i dane, więc tabela powstaje razem z importem. Po imporcie kliknij tabelę zadania (karta Przeglądaj): 63 wiersze - każdy dzień lipca i sierpnia 2020 (miesiac to lipiec albo sierpien) oraz jeden dzień listopada. Zrzut całego ekranu z paskiem zadań: import.png.
Zwróć uwagę na pisownię miesięcy w danych: sierpien bez litery „ń”. Arkusz pisze „sierpień”, ale zapytanie musi porównywać z tym, co jest w tabeli.
Typowe błędy
Zrzut importu w PNG (import.png), zrzuty kwerend w JPG - zły format albo wykadrowany zrzut nie jest oceniany.
Podgląd strony po tym kroku
Krok 4: Zapytanie 1: zadania z sierpnia
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 dataZadania, miesiac i wpis z tabeli zadania dla zadań, których miesiąc to sierpień. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT dataZadania, miesiac, wpis FROM zadania WHERE miesiac = 'sierpien'; oraz wynik działania zapytania udokumentowano zrzutem, na którym widoczne są jedynie pola dataZadania, miesiac i wpis. Rekordy mają daty jedynie z sierpnia przy czym jest widoczna albo poprawna kwerenda albo dokładnie 31 rekordów (daty od 1-31 sierpnia)
ok. 3 min
Polecenie z arkusza
Zapytanie 1: wybierające jedynie pola dataZadania, miesiac i wpis z tabeli zadania dla zadań, których miesiąc to sierpień
Karta SQL bazy egzamin6. Zapytanie po kolei:
SELECT dataZadania, miesiac, wpis - trzy kolumny z arkusza, w tej kolejności (skrypt wyświetli je w bloku dnia),
FROM zadania,
WHERE miesiac = 'sierpien' - napis w apostrofach, pisany tak jak w tabeli, bez „ń”.
Wynik: 31 wierszy, od 2020-08-01 (Remont) do 2020-08-31 - klucz wymaga dokładnie tylu. Zapytanie zapisujesz w pliku kwerendy.txt, a cały ekran - jako kw1.jpg.
Typowe błędy
WHERE miesiac = 'sierpień' (z „ń”) zwraca zero wierszy, bo w tabeli jest sierpien. Pusty wynik to sygnał, żeby zajrzeć do danych, a nie zmieniać warunek na LIKE '%sierp%'.
kwerendy.txtTekstnowy plik
-- Zapytanie 1SELECT dataZadania, miesiac, wpis FROM zadania WHERE miesiac = 'sierpien';
Podgląd strony po tym kroku
Krok 5: Zapytanie 2: miesiąc i rok dla 1 sierpnia
Kryteria:
R.1.4 Utworzono zapytanie 2 wybierające jedynie pola miesiac i rok z tabeli zadania dla zadania z datą 2020-08-01. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT miesiac, rok FROM zadania WHERE dataZadania = '2020-08- 01'; oraz wynik działania zapytania udokumentowano zrzutem, na którym widoczny jest dokładnie jeden rekord z danymi: sierpien 2020
ok. 2 min
Polecenie z arkusza
Zapytanie 2: wybierające jedynie pola miesiac i rok z tabeli zadania dla zadania z datą 2020-08-01
SELECT miesiac, rok FROM zadania WHERE dataZadania = '2020-08-01' - datę w SQL zapisuje się jak napis, w formacie RRRR-MM-DD. Wynik: dokładnie jeden wiersz: sierpien, 2020. Zrzut: kw2.jpg. Tego zapytania użyje skrypt 2 do podpisu w stopce.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT dataZadania, miesiac, wpis FROM zadania WHERE miesiac = 'sierpien';-- Zapytanie 2SELECT miesiac, rok FROM zadania WHERE dataZadania = '2020-08-01';
Podgląd strony po tym kroku
Krok 6: Zapytanie 3: wpisy bez powtórzeń kończące się na „o”
Kryteria:
R.1.5 Utworzono zapytanie 3 wybierające jedynie pole wpis i wyświetlające je bez powtórzeń, z tabeli zadania dla wpisów kończących się literą „o”. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT DISTINCT wpis FROM zadania WHERE wpis LIKE "%o"; oraz wynik działania zapytania udokumentowano zrzutem, na którym widoczny jest jedynie jeden rekord: Mielno
ok. 2 min
Polecenie z arkusza
Zapytanie 3: wybierające jedynie pole wpis i wyświetlające je bez powtórzeń, z tabeli zadania dla wpisów kończących się literą „o”
SELECT DISTINCT wpis - DISTINCT usuwa powtórzenia: wpis „Mielno” stoi przy sześciu dniach lipca, a w wyniku pojawi się raz,
FROM zadania,
WHERE wpis LIKE '%o' - % to dowolny ciąg znaków (także pusty), a po nim litera o na samym końcu.
Wynik: jeden wiersz - Mielno, dokładnie jak w kluczu. Zrzut: kw3.jpg.
Typowe błędy
LIKE 'o%' szuka wpisów zaczynających się od „o”, a LIKE '%o%' - zawierających „o” gdziekolwiek (Projekt z programowania, Rower, Sopot...). Bez DISTINCT wynik ma sześć razy „Mielno”.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT dataZadania, miesiac, wpis FROM zadania WHERE miesiac = 'sierpien';-- Zapytanie 2SELECT miesiac, rok FROM zadania WHERE dataZadania = '2020-08-01';-- Zapytanie 3SELECT DISTINCT wpis FROM zadania WHERE wpis LIKE '%o';
Podgląd strony po tym kroku
Krok 7: Zapytanie 4: nowy wpis dla 27 sierpnia
Kryteria:
R.1.6 Utworzono zapytanie 4 zmieniające pole wpis w tabeli zadania dla zadania z datą 2020- 08-27, nowy wpis to „Wycieczka: Karkonosze”. W pliku z kwerendami lub na zrzucie istnieje zapis np.: UPDATE zadania SET wpis='Wycieczka: Karkonosze' WHERE dataZadania='2020-08-27'; oraz wynik działania zapytania udokumentowano zrzutem wskazującym na poprawne wykonanie zapytania
ok. 2 min
Polecenie z arkusza
Zapytanie 4: zmieniające pole wpis w tabeli zadania dla zadania z datą 2020-08-27, nowy wpis to „Wycieczka: Karkonosze”
UPDATE zadania - zmiana istniejących wierszy,
SET wpis = 'Wycieczka: Karkonosze' - nowa wartość kolumny,
WHERE dataZadania = '2020-08-27' - tylko ten jeden dzień.
phpMyAdmin odpowiada „1 wiersz zmieniony” - zrzut kw4.jpg. Wpis 27 sierpnia był wcześniej pusty, teraz zobaczysz go na stronie w bloku tego dnia. Plik kwerendy.txt ma komplet czterech zapytań. Z tego zapytania skrypt zrobi zapis wpisu z formularza.
Typowe błędy
UPDATE bez WHERE zmienia wszystkie 63 wiersze - phpMyAdmin wykona je bez pytania. Przed uruchomieniem sprawdź, czy warunek jest na miejscu.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT dataZadania, miesiac, wpis FROM zadania WHERE miesiac = 'sierpien';-- Zapytanie 2SELECT miesiac, rok FROM zadania WHERE dataZadania = '2020-08-01';-- Zapytanie 3SELECT DISTINCT wpis FROM zadania WHERE wpis LIKE '%o';-- Zapytanie 4UPDATE zadania SET wpis = 'Wycieczka: Karkonosze' WHERE dataZadania = '2020-08-27';
Podgląd strony po tym kroku
Etap 2: Grafika i strona HTML
Kroki 8-19 · po tym etapie masz 16 z 34 kryteriów (pkt)
Krok 8: Grafika: logo2.png 100 × 100 px
Kryteria:
R.2.1 Plik logo2.png przeskalowano do wymiarów 100 px na 100 px (± 2 px)
ok. 2 min
Polecenie z arkusza
Plik logo2.png, wypakowany z archiwum, należy przeskalować dokładnie do wymiarów 100 px na 100 px
Oryginał ma 300 × 300 px, czyli jest kwadratem - zmniejszenie do 100 × 100 px zachowuje proporcje samo z siebie. W GIMP-ie Obraz → Skaluj obraz, szerokość i wysokość 100 px, potem Plik → Nadpisz logo2.png (zwykłe Zapisz zapisuje format .xcf). Plik ma przezroczyste tło - format PNG je zachowa (R.2.1).
Typowe błędy
Wymiary ustawione tylko atrybutem width w HTML-u nie zmieniają pliku - klucz sprawdza rozmiar samego logo2.png.
Podgląd strony po tym kroku
Krok 9: Plik organizer.php
ok. 1 min
Polecenie z arkusza
Składa się ze strony o nazwie organizer.php
Plik organizer.php w folderze zdającego, obok logo2.png. Rozszerzenie .php, bo dojdzie skrypt - na razie to szkielet HTML5: <!DOCTYPE html> i lang="pl", czyli informacja dla przeglądarki i czytników ekranu, że treść jest po polsku.
R.2.2 Witrynę internetową zapisano w pliku PHP o nazwie organizer 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 pierwszy element <head>, a plik zapisany w UTF-8 (w Notepad++ menu Kodowanie). Klucz ocenia nazwę pliku i kodowanie razem (R.2.2).
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 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>. Nazwa z cyfrą 6 - jak numer bazy, a nie jak archiwum. Plik stylów powstanie po HTML-u (R.3.4).
Typowe błędy
Klucz uznaje R.3.4 tylko wtedy, gdy całe formatowanie pochodzi z tego pliku i każdy selektor trafia w swój blok (kropka zamiast # odbiera punkt).
R.2.4 Wygląd strony zdefiniowano dzieląc ją na bloki: trzy bloki banera, poniżej blok główny, na dole blok stopki. Zastosowano znaczniki sekcji
ok. 2 min
Polecenie z arkusza
Podział strony na bloki: trzy bloki banera, poniżej blok główny, w którym znajdują się bloki wyświetlające dane kolejnych dni, na dole blok stopki.
Pięć bloków w kolejności z obrazu 2: trzy bloki banera i blok główny jako <section> z identyfikatorami banner-title, banner-form, banner-logo i main (nazwy po angielsku - arkusz ich nie narzuca), na dole <footer>. Bloki kolejnych dni nie są pisane w HTML-u - wygeneruje je skrypt wewnątrz bloku głównego. Na razie bloki są puste i stoją jeden pod drugim; obok siebie ustawi je CSS (R.2.4).
Krok 14: Pierwszy blok banera: nagłówek „MÓJ ORGANIZER”
ok. 1 min
Polecenie z arkusza
Zawartość pierwszego bloku banera: nagłówek drugiego stopnia o treści „MÓJ ORGANIZER”
Drugiego stopnia to <h2>, nie <h1> - nagłówek pierwszego stopnia arkusz przeznacza na podpis miesiąca w stopce. Punkt R.2.5 przyjdzie razem z tamtym nagłówkiem i paragrafem stopki.
R.2.6 W drugim bloku banera umieszczono formularz, zastosowano znacznik <form> i jego zamknięcie
R.3.3 Zdefinowano dla formularza metodę POST
ok. 1 min
Polecenie z arkusza
Zawartość drugiego bloku banera: formularz wysyłający dane metodą POST do tej samej strony
<form method="post">bez atrybutu action wysyła dane do adresu, z którego został wczytany - czyli do organizer.php. Znacznik ma zamknięcie </form> (R.2.6), a metoda POST przesyła wpis w treści żądania, nie w adresie strony; w PHP odczytasz go z tablicy $_POST (R.3.3).
Typowe błędy
Formularz bez method używa domyślnie GET - wpis trafi do $_GET, a skrypt czytający $_POST nie dostanie niczego.
Podpis wprost w formularzu, za nim <input type="text">. Atrybut name="wpis" to klucz, pod którym tekst trafi do PHP: $_POST['wpis'] - nazwa taka sama jak kolumna w bazie, łatwo się nie pomylić.
R.2.7 W formularzu umieszczono pole do wprowadzania danych oraz przycisk "ZAPISZ"
R.3.2 Zastosowano przycisk do wysyłania danych z formularza
ok. 1 min
Polecenie z arkusza
Przycisk wysyłający zawartość formularza z etykietą „ZAPISZ”
<input type="submit" value="ZAPISZ"> - przycisk typu submit wysyła formularz, a napis to wartość value. Formularz ma pole i przycisk (R.2.7), a przycisk naprawdę wysyła dane (R.3.2).
Typowe błędy
<input type="button"> wygląda tak samo, ale niczego nie wysyła - brak punktu R.3.2, a skrypt zapisu nigdy się nie uruchomi.
Krok 18: Trzeci blok banera: logo z tekstem alternatywnym
Kryteria:
R.2.8 W trzecim bloku banera umieszczono obraz logo2.png wraz z tekstem alternatywnym "Mój organizer"
ok. 1 min
Polecenie z arkusza
Zawartość trzeciego bloku banera: logo2.png z tekstem alternatywnym o treści: „Mój organizer”
<img> z src (przeskalowany plik z folderu zdającego) i alt - tekst, który przeczyta czytnik ekranu i który pokaże się, gdy obrazu zabraknie (R.2.8). W HTML5 <img> nie ma znacznika zamykającego ani ukośnika na końcu.
Paragraf (akapit) 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 imię i nazwisko autora: Bartosz Bryniarski. To ma być paragraf <p>. Nad nim w stopce stanie jeszcze efekt skryptu 2 - nagłówek z miesiącem i rokiem.
Kroki 20-27 · po tym etapie masz 25 z 34 kryteriów (pkt)
Krok 20: Plik styl6.css: krój Georgia dla całej strony
Kryteria:
R.4.1 Ustawiono domyślny krój czcionki dla całej strony na Georgia (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 Georgia
Nowy plik styl6.css w folderze zdającego. Pierwsza reguła: selektor uniwersalny * z font-family: Georgia. Selektor * obejmuje każdy element, także pole tekstowe i przycisk „ZAPISZ”, które kroju po body nie dziedziczą - na obrazie 2 przycisk też jest pisany Georgią. Klucz R.4.1 przyjmuje *, body i html.
styl6.cssCSSnowy plik
* {font-family: Georgia;}
Podgląd strony po tym kroku (organizer.php)
Krok 21: Pierwszy i drugi blok banera
ok. 2 min
Polecenie z arkusza
Dla pierwszego i drugiego bloku banera: kolor tła #3CB371, biały kolor czcionki, wysokość 100 px, szerokość 40%
Dwa selektory identyfikatorów rozdzielone przecinkiem dostają jedną wspólną regułę. #3CB371 to zieleń z arkusza zapisana szesnastkowo (czerwony 3C, zielony B3, niebieski 71).
R.4.4 Ustawiono wysokość dla wszystkich bloków banera na 100px
R.4.5 Ustawiono szerokość pierwszego i drugiego bloku banera na 40%, trzeciego bloku banera na 20%
ok. 1 min
Polecenie z arkusza
Dla trzeciego bloku banera: kolor tła #3CB371, wysokość 100 px, szerokość 20%
Bez koloru tekstu - w tym bloku jest tylko logo. Szerokości 40% + 40% + 20% = 100%, więc trzy bloki zmieszczą się w jednym rzędzie. Wszystkie bloki banera mają wysokość (R.4.4) i szerokość (R.4.5).
Typowe błędy
Bloki o sumie szerokości 100% nie mogą mieć obramowania ani padding - każdy dodatkowy piksel zepchnie logo do następnego rzędu.
R.4.8 Ustawiono dla bloku z danymi z kalendarza: kolor tła #FFDAB9, szerokość 170px, wyskość 90px, marginesy zewnętrzne 5px, obramowanie o szerokości 1px linią ciągłą o kolorze #3CB371
ok. 2 min
Polecenie z arkusza
Dla bloku wyświetlającego dane jednego dnia: kolor tła #FFDAB9, szerokość 170 px, wysokość 90 px, marginesy zewnętrzne 5 px, obramowanie o szerokości 1 px, linią ciągłą o kolorze #3CB371
Bloków dni będzie 31, więc selektor klasy.day - identyfikator może wystąpić na stronie tylko raz. Skrypt dopisze każdemu blokowi class="day". margin: 5px to margines zewnętrzny ze wszystkich stron, a border: 1px solid #3CB371 - szerokość, styl linii (ciągła) i kolor w jednej właściwości (R.4.8).
Na razie żadnego bloku dnia nie ma, więc podgląd się nie zmienia - klucz pozwala sprawdzić to kryterium w pliku CSS.
R.4.2 Ustawiono kolor tła #3CB371 dla trzech bloków banera i stopki
R.4.3 Ustawiono biały kolor czcionki dla pierwszego i drugiego bloku banera oraz dla stopki
ok. 1 min
Polecenie z arkusza
Dla stopki: kolor tła #3CB371, biały kolor czcionki
Ta sama zieleń co w banerze. Tło trzech bloków banera i stopki (R.4.2) oraz biały tekst w dwóch pierwszych blokach banera i stopce (R.4.3) są ustawione.
R.4.7 Ustawiono marginesy wewnętrzne (padding) na 30px dla znacznika formularza
ok. 1 min
Polecenie z arkusza
Dla znacznika formularza: marginesy wewnętrzne 30 px
padding: 30px - margines wewnętrzny z czterech stron. Pole i przycisk odsuwają się od krawędzi bloku i stoją mniej więcej w połowie wysokości banera (R.4.7).
R.3.1 Układ bloków po uruchomieniu strony w przeglądarce jest w pełni zgodny z Obrazem 2 w arkuszu egzaminacyjnym (uwaga! Blok główny nie musi zawierać bloków kalendarza)
ok. 3 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 banera dostają float: left i stają obok siebie (40% + 40% + 20%),
blok główny z clear: both zaczyna się dopiero pod nimi,
bloki dni też pływają w lewo: każdy zajmuje 170 + 2 + 10 = 182 px, więc przeglądarka układa ich w rzędzie tyle, ile się zmieści, a resztę przenosi do następnego rzędu - jak kafelki kalendarza na obrazie 2,
stopka z clear: both staje pod ostatnim rzędem dni.
Bloki dni pojawią się dopiero ze skryptem; klucz przy R.3.1 zaznacza, że blok główny nie musi ich zawierać, żeby układ był uznany. Wersja nowoczesna ustawia te same bloki bez float.
Typowe błędy
Bez clear przy stopce zielony pasek stopki wsunie się pod pływające bloki dni i schowa za nimi.
Kroki 28-35 · po tym etapie masz 34 z 34 kryteriów (pkt)
Krok 28: Połączenie z bazą egzamin6
Kryteria:
R.5.1 Skrypt realizuje połączenie z serwerem bazy danych i wybór bazy egzamin6
ok. 3 min
Polecenie z arkusza
Skrypt łączy się z serwerem bazodanowym na localhost, użytkownik root bez hasła, baza danych o nazwie egzamin6
Na samej górze organizer.php, przed <!DOCTYPE html>, piszesz pierwszy blok PHP. Funkcja mysqli_connect z tabeli 1 arkusza przyjmuje kolejno serwer localhost, użytkownika root, puste hasło '' i nazwę bazy egzamin6 - czwarty argument od razu wybiera bazę (R.5.1). Połączenie trafia do zmiennej $connection, z której skorzystają wszystkie zapytania na stronie.
Dlaczego na górze: z połączenia korzystają trzy miejsca strony (zapis z formularza, blok główny i stopka), a w tym bloku za chwilę stanie też obsługa formularza - zapis musi wykonać się przed odczytem dni, żeby nowy wpis był od razu widoczny. 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.
Krok 29: Skrypt 1: zapytanie 1 i blok dla każdego wiersza
Kryteria: ,
R.5.3 Skrypt 1 wysyła do bazy danych zapytanie 1 lub Skrypt 2 wysyła do bazy zapytanie 2
R.5.4 Skrypt 1 definiuje w bloku głównym blok (za pomocą znaczników sekcji), a w nim wyświetla dane przesłane skryptem. Liczba wygenerowanych bloków odpowiada liczbie wierszy zwróconych zapytaniem
ok. 4 min
Polecenie z arkusza
Działanie skryptu 1: Wysyła do bazy danych zapytanie 1. Definiuje blok (za pomocą znacznika sekcji), a w nim wyświetla dane przesłane skryptem dotyczące jednego wiersza.
Blok PHP wewnątrz <section id="main">:
mysqli_query($connection, "SELECT ...") - zapytanie 1 z kwerendy.txt, bez zmian (R.5.3); wynik trafia do $result,
while ($row = mysqli_fetch_row($result)) - mysqli_fetch_row zwraca kolejny wiersz jako tablicę numerowaną od zera, a gdy wierszy zabraknie - false, i pętla się kończy,
w każdym obrocie echo wypisuje otwarcie i zamknięcie znacznika sekcji z klasą day - tą samą, którą ma reguła w CSS.
Zapytanie zwraca 31 wierszy, więc pętla obraca się 31 razy i na stronie jest 31 bloków - po jednym na każdy wiersz (R.5.4). Bloki są jeszcze puste, ale już widać kafelki z obramowaniem ułożone w rzędy. Napis w echo jest w apostrofach, bo w środku stoją cudzysłowy atrybutu class.
Krok 30: Skrypt 1: data i miesiąc w nagłówku szóstego stopnia
ok. 2 min
Polecenie z arkusza
W nagłówku szóstego stopnia data zadania i miesiąc oddzielone przecinkiem
Wiersz z zapytania 1 ma trzy kolumny w kolejności z SELECT: $row[0] to dataZadania, $row[1] - miesiac, $row[2] - wpis. Nagłówek <h6> dostaje datę, przecinek ze spacją i miesiąc: 2020-08-01, sierpien, jak na obrazie 3.
Napis jest w cudzysłowie "…", więc PHP podstawia w nim wartości zmiennych; zapis $row[0] bez apostrofów wokół indeksu jest w takim napisie poprawny. Reguła h6 z CSS wyrównuje daty do prawej.
R.5.5 Data zadania i miesiac są zapisana w nagłówku h6 oraz pole wpis jest zapisane w paragrafie
ok. 2 min
Polecenie z arkusza
Pole wpis w paragrafie (akapicie)
Trzecia kolumna, $row[2], w paragrafie <p>. Dni bez wpisu mają w bazie pusty napis, więc ich paragraf jest pusty, a blok pokazuje samą datę - tak jak dni 5, 6 czy 9 sierpnia na obrazie 2. Data w <h6> i wpis w <p> dają R.5.5. Blok 27 sierpnia ma już wpis „Wycieczka: Karkonosze” z zapytania 4.
Krok 32: Skrypt 2: miesiąc i rok w nagłówku pierwszego stopnia
Kryteria: ,
R.5.6 Skrypt 2 wyświetla tekst: „miesiąc: <nazwa_miesiąca>, rok: <rok>”, gdzie pola w nawiasach <> oznaczają dane pobrane skryptem
R.2.5 W pierwszym bloku banera zapisano nagłówek h2: "MÓJ OGRANIZER" oraz w stopce nagłówek h1 (w skrypcie lub HTML) oraz zapisano przynajmniej jeden paragraf (znacznik <p>)
ok. 3 min
Polecenie z arkusza
Działanie skryptu 2: Wysyła do bazy danych zapytanie 2. Wyświetla w nagłówku pierwszego stopnia tekst: „miesiąc: <nazwa_miesiąca>, rok: <rok>”, gdzie pola w nawiasach <…> oznaczają dane pobrane skryptem
Drugi blok PHP w stopce, nad paragrafem autora:
zapytanie 2 przez to samo połączenie $connection,
zapytanie zwraca dokładnie jeden wiersz, więc wystarczy jedno wywołanie mysqli_fetch_row - bez pętli,
echo nagłówka <h1> ze stałym tekstem i dwiema wartościami: $row[0] (miesiąc) i $row[1] (rok).
Na stronie: „miesiąc: sierpien, rok: 2020” (R.5.6). Nazwa miesiąca pochodzi z bazy, dlatego bez „ń” - tak samo jest na obrazie 2. Strona ma teraz <h2> w banerze, <h1> w stopce i paragraf (R.2.5).
organizer.phpPHPzmienione: 5 linii
<?php$connection = mysqli_connect('localhost', 'root', '', 'egzamin6');?><!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Organizer</title> <linkrel="stylesheet"href="styl6.css"></head><body> <sectionid="banner-title"> <h2>MÓJ ORGANIZER</h2> </section> <sectionid="banner-form"> <formmethod="post"> Wpis wydarzenia: <inputtype="text"name="wpis"> <inputtype="submit"value="ZAPISZ"> </form> </section> <sectionid="banner-logo"> <imgsrc="logo2.png"alt="Mój organizer"> </section> <sectionid="main"><?php$result = mysqli_query($connection, "SELECT dataZadania, miesiac, wpis FROM zadania WHERE miesiac = 'sierpien';");while ($row = mysqli_fetch_row($result)) {echo'<section class="day">';echo"<h6>$row[0], $row[1]</h6>";echo"<p>$row[2]</p>";echo'</section>'; }?> </section> <footer><?php$result = mysqli_query($connection, "SELECT miesiac, rok FROM zadania WHERE dataZadania = '2020-08-01';");$row = mysqli_fetch_row($result);echo"<h1>miesiąc: $row[0], rok: $row[1]</h1>";?> <p>Stronę wykonał: Bartosz Bryniarski</p> </footer></body></html>
Podgląd strony po tym kroku (organizer.php)
Krok 33: Odczyt wpisu z formularza
Kryteria:
R.5.7 W skrypcie działającym na danych przesłanych przez formularz zastosowano tablicę $_POST, zapis musi być poprawny składniowo i logicznie
ok. 2 min
Polecenie z arkusza
Działanie skryptu, który odbiera dane przesłane z formularza. Skrypt pobiera dane z pola edycyjnego
W bloku na górze pliku, pod połączeniem:
isset($_POST['wpis']) - prawdziwe dopiero po kliknięciu „ZAPISZ”. Przy zwykłym wejściu na stronę formularz nie był wysłany i ta część się nie wykonuje,
$wpis = $_POST['wpis']; - tekst z pola o nazwie wpis do zmiennej. Kluczem w tablicy $_POST jest atrybut name pola (R.5.7).
Podgląd: formularz wysłany ze słowem „Basen” - skrypt je odczytał, ale jeszcze nigdzie nie zapisał, więc strona wygląda jak wcześniej.
R.5.8 Skrypt obsługujący formularz uaktualnia dane w bazie danych. Wpis pobrany z formularza jest wpisany do rekordu o dacie 2020-08-27. Należy sprawdzić w bazie danych czy po wciśnięciu przycisku baza została uaktualniona, nie jest wymagane uaktualnienie na stronie
ok. 3 min
Polecenie z arkusza
Następnie uaktualnia dane w bazie danych. Aby uprościć zadanie skrypt wprowadza wpis zawsze do rekordu o dacie 2020-08-27. Do uaktualnienia danych wykorzystaj zapytanie 4, modyfikując w nim wartość pola wpis
Zapytanie 4 z kwerendy.txt, w którym w miejsce stałego tekstu „Wycieczka: Karkonosze” stoi '$wpis'. Data zostaje: arkusz każe zawsze zapisywać do 27 sierpnia. Całe zapytanie jest w cudzysłowie, więc PHP podstawia wartość zmiennej, a apostrofy wewnątrz to ograniczniki napisu w SQL.
Sprawdzenie, jak każe klucz (R.5.8): po wpisaniu „Basen” i kliknięciu „ZAPISZ” w tabeli zadania wiersz z datą 2020-08-27 ma wpis Basen. Ponieważ zapis stoi na górze pliku, przed skryptem 1, nowy wpis widać od razu w bloku 27 sierpnia - klucz tego nie wymaga, ale to wygodne przy sprawdzaniu.
Typowe błędy
Wpis z literami „ś” czy „ż” (np. „Śnieżka”) kończy się błędem „Incorrect string value”: tabela z archiwum ma kodowanie latin1, które tych liter nie zna, a MariaDB z XAMPP działa w trybie ścisłym. To cecha bazy z archiwum, nie błąd skryptu - klucz sprawdza import pliku bez zmian, więc tabeli nie przerabiaj, a zapis sprawdź słowem bez polskich liter.
organizer.phpPHPzmienione: 1 linia
<?php$connection = mysqli_connect('localhost', 'root', '', 'egzamin6');if (isset($_POST['wpis'])) {$wpis = $_POST['wpis']; mysqli_query($connection, "UPDATE zadania SET wpis = '$wpis' WHERE dataZadania = '2020-08-27';");}?><!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Organizer</title> <linkrel="stylesheet"href="styl6.css"></head><body> <sectionid="banner-title"> <h2>MÓJ ORGANIZER</h2> </section> <sectionid="banner-form"> <formmethod="post"> Wpis wydarzenia: <inputtype="text"name="wpis"> <inputtype="submit"value="ZAPISZ"> </form> </section> <sectionid="banner-logo"> <imgsrc="logo2.png"alt="Mój organizer"> </section> <sectionid="main"><?php$result = mysqli_query($connection, "SELECT dataZadania, miesiac, wpis FROM zadania WHERE miesiac = 'sierpien';");while ($row = mysqli_fetch_row($result)) {echo'<section class="day">';echo"<h6>$row[0], $row[1]</h6>";echo"<p>$row[2]</p>";echo'</section>'; }?> </section> <footer><?php$result = mysqli_query($connection, "SELECT miesiac, rok FROM zadania WHERE dataZadania = '2020-08-01';");$row = mysqli_fetch_row($result);echo"<h1>miesiąc: $row[0], rok: $row[1]</h1>";?> <p>Stronę wykonał: Bartosz Bryniarski</p> </footer></body></html>
Podgląd strony po tym kroku (organizer.php)
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) w bloku PHP stopki, po zapytaniu 2 - to ostatnie zapytanie na stronie, więc zamknięcie jest ostatnią operacją na bazie (R.5.2). Strona spełnia wszystkie kryteria arkusza. Dalej trzy kroki o zabezpieczeniach - klucz ich nie wymaga.
Typowe błędy
mysqli_close zaraz po połączeniu albo w bloku głównym sprawia, że zapytanie 2 w stopce dostaje zamknięte połączenie i PHP kończy się błędem.
organizer.phpPHPzmienione: 1 linia
<?php$connection = mysqli_connect('localhost', 'root', '', 'egzamin6');if (isset($_POST['wpis'])) {$wpis = $_POST['wpis']; mysqli_query($connection, "UPDATE zadania SET wpis = '$wpis' WHERE dataZadania = '2020-08-27';");}?><!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Organizer</title> <linkrel="stylesheet"href="styl6.css"></head><body> <sectionid="banner-title"> <h2>MÓJ ORGANIZER</h2> </section> <sectionid="banner-form"> <formmethod="post"> Wpis wydarzenia: <inputtype="text"name="wpis"> <inputtype="submit"value="ZAPISZ"> </form> </section> <sectionid="banner-logo"> <imgsrc="logo2.png"alt="Mój organizer"> </section> <sectionid="main"><?php$result = mysqli_query($connection, "SELECT dataZadania, miesiac, wpis FROM zadania WHERE miesiac = 'sierpien';");while ($row = mysqli_fetch_row($result)) {echo'<section class="day">';echo"<h6>$row[0], $row[1]</h6>";echo"<p>$row[2]</p>";echo'</section>'; }?> </section> <footer><?php$result = mysqli_query($connection, "SELECT miesiac, rok FROM zadania WHERE dataZadania = '2020-08-01';");$row = mysqli_fetch_row($result);echo"<h1>miesiąc: $row[0], rok: $row[1]</h1>"; mysqli_close($connection);?> <p>Stronę wykonał: Bartosz Bryniarski</p> </footer></body></html>
Podgląd strony po tym kroku (organizer.php)
Etap 5: Dobre praktyki (poza kluczem)
Kroki 36-38 · po tym etapie masz 34 z 34 kryteriów (pkt)
Krok 36: Zabezpieczenie: zapytanie przygotowane dla UPDATE
ok. 4 min
Polecenie z arkusza
Do uaktualnienia danych wykorzystaj zapytanie 4, modyfikując w nim wartość pola wpis
Tekst z formularza trafia do zapytania wprost - to SQL injection. Sprawdzone na wersji z poprzednich kroków:
wpis Hakowanie' -- (z apostrofem i dwoma myślnikami ze spacją) zamienia zapytanie w UPDATE zadania SET wpis = 'Hakowanie' -- ' WHERE .... Dwa myślniki ze spacją zaczynają w SQL komentarz, więc warunek WHERE znika i baza zmienia wszystkie 63 wiersze tabeli - cały lipiec, sierpień i listopad dostały wpis „Hakowanie”,
zwykły wpis z apostrofem, np. Kino 'Helios', rozbija składnię zapytania - PHP 8.1 i nowsze zgłaszają wtedy wyjątek mysqli_sql_exception, a zamiast strony widać „Fatal error”.
Lekarstwo to zapytanie przygotowane: mysqli_prepare z jednym znakiem ? w miejscu wpisu, mysqli_stmt_bind_param z typem 's' (napis) i mysqli_stmt_execute. Baza dostaje treść zapytania i dane osobno, więc dane nigdy nie staną się kodem SQL. Podgląd: ten sam „wpis-atak” zapisał się jako zwykły tekst - tylko w bloku 27 sierpnia. Stara linia zostaje w komentarzu.
Typowe błędy
Data 2020-08-27 jest stała, więc może zostać w treści zapytania. Znak ? zastępuje tylko wartości pochodzące od użytkownika.
organizer.phpPHPzmienione: 4 linie
<?php$connection = mysqli_connect('localhost', 'root', '', 'egzamin6');if (isset($_POST['wpis'])) {$wpis = $_POST['wpis'];// mysqli_query($connection, "UPDATE zadania SET wpis = '$wpis' WHERE dataZadania = '2020-08-27';");$statement = mysqli_prepare($connection, "UPDATE zadania SET wpis = ? WHERE dataZadania = '2020-08-27';"); mysqli_stmt_bind_param($statement, 's', $wpis); mysqli_stmt_execute($statement);}?><!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Organizer</title> <linkrel="stylesheet"href="styl6.css"></head><body> <sectionid="banner-title"> <h2>MÓJ ORGANIZER</h2> </section> <sectionid="banner-form"> <formmethod="post"> Wpis wydarzenia: <inputtype="text"name="wpis"> <inputtype="submit"value="ZAPISZ"> </form> </section> <sectionid="banner-logo"> <imgsrc="logo2.png"alt="Mój organizer"> </section> <sectionid="main"><?php$result = mysqli_query($connection, "SELECT dataZadania, miesiac, wpis FROM zadania WHERE miesiac = 'sierpien';");while ($row = mysqli_fetch_row($result)) {echo'<section class="day">';echo"<h6>$row[0], $row[1]</h6>";echo"<p>$row[2]</p>";echo'</section>'; }?> </section> <footer><?php$result = mysqli_query($connection, "SELECT miesiac, rok FROM zadania WHERE dataZadania = '2020-08-01';");$row = mysqli_fetch_row($result);echo"<h1>miesiąc: $row[0], rok: $row[1]</h1>"; mysqli_close($connection);?> <p>Stronę wykonał: Bartosz Bryniarski</p> </footer></body></html>
Podgląd strony po tym kroku (organizer.php)
Krok 37: Zabezpieczenie: htmlspecialchars przy wyświetlaniu wpisu
ok. 3 min
Polecenie z arkusza
Pole wpis w paragrafie (akapicie)
Zapytanie przygotowane chroni bazę, ale wpis wraca potem na stronę - i każdy, kto otworzy organizer, zobaczy go jako kod HTML. Sprawdzone: wpis <b style="color:red">PILNE</b> wyświetlał się w bloku 27 sierpnia jako czerwone, pogrubione słowo. Tak samo przeszedłby znacznik <script> - kod JavaScript uruchamiałby się u każdego odwiedzającego (stored XSS, zapisany atak na przeglądarki).
Funkcja htmlspecialchars zamienia <, >, & i cudzysłowy na encje (np. < na <), więc przeglądarka pokazuje znaki dosłownie, zamiast je wykonywać. Stosuje się ją przy wypisywaniu danych, które przyszły od użytkownika - tutaj to kolumna wpis. Daty i nazwy miesięcy pochodzą z importu, a nie z formularza. Podgląd: wpis widać dosłownie, ze znacznikami.
organizer.phpPHPzmienione: 2 linie
<?php$connection = mysqli_connect('localhost', 'root', '', 'egzamin6');if (isset($_POST['wpis'])) {$wpis = $_POST['wpis'];// mysqli_query($connection, "UPDATE zadania SET wpis = '$wpis' WHERE dataZadania = '2020-08-27';");$statement = mysqli_prepare($connection, "UPDATE zadania SET wpis = ? WHERE dataZadania = '2020-08-27';"); mysqli_stmt_bind_param($statement, 's', $wpis); mysqli_stmt_execute($statement);}?><!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Organizer</title> <linkrel="stylesheet"href="styl6.css"></head><body> <sectionid="banner-title"> <h2>MÓJ ORGANIZER</h2> </section> <sectionid="banner-form"> <formmethod="post"> Wpis wydarzenia: <inputtype="text"name="wpis"> <inputtype="submit"value="ZAPISZ"> </form> </section> <sectionid="banner-logo"> <imgsrc="logo2.png"alt="Mój organizer"> </section> <sectionid="main"><?php$result = mysqli_query($connection, "SELECT dataZadania, miesiac, wpis FROM zadania WHERE miesiac = 'sierpien';");while ($row = mysqli_fetch_row($result)) {echo'<section class="day">';echo"<h6>$row[0], $row[1]</h6>";// echo "<p>$row[2]</p>";echo'<p>' . htmlspecialchars($row[2]) . '</p>';echo'</section>'; }?> </section> <footer><?php$result = mysqli_query($connection, "SELECT miesiac, rok FROM zadania WHERE dataZadania = '2020-08-01';");$row = mysqli_fetch_row($result);echo"<h1>miesiąc: $row[0], rok: $row[1]</h1>"; mysqli_close($connection);?> <p>Stronę wykonał: Bartosz Bryniarski</p> </footer></body></html>
Podgląd strony po tym kroku (organizer.php)
Krok 38: Zabezpieczenie: pusty formularz nie kasuje wpisu
ok. 3 min
Polecenie z arkusza
Skrypt pobiera dane z pola edycyjnego
isset jest prawdziwe także wtedy, gdy pole jest puste - po kliknięciu „ZAPISZ” klucz wpis zawsze jest w $_POST. Sprawdzone: kliknięcie przycisku bez wpisania tekstu zapisało pusty napis i skasowało „Wycieczka: Karkonosze” z 27 sierpnia.
Warunek dostaje drugi człon: trim($_POST['wpis']) !== '' - trim zdejmuje spacje z brzegów, więc wpis z samych spacji też się nie liczy. Do bazy idzie wersja przycięta. Podgląd: formularz wysłany z trzema spacjami - wpis 27 sierpnia został.
W prawdziwym serwisie doszłaby jeszcze kontrola długości wpisu (blok ma 170 × 90 px) i ochrona przed wysłaniem formularza z obcej strony (token CSRF) - klucz ich nie ocenia.
organizer.phpPHPzmienione: 4 linie
<?php$connection = mysqli_connect('localhost', 'root', '', 'egzamin6');// if (isset($_POST['wpis'])) {// $wpis = $_POST['wpis'];if (isset($_POST['wpis']) && trim($_POST['wpis']) !== '') {$wpis = trim($_POST['wpis']);// mysqli_query($connection, "UPDATE zadania SET wpis = '$wpis' WHERE dataZadania = '2020-08-27';");$statement = mysqli_prepare($connection, "UPDATE zadania SET wpis = ? WHERE dataZadania = '2020-08-27';"); mysqli_stmt_bind_param($statement, 's', $wpis); mysqli_stmt_execute($statement);}?><!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Organizer</title> <linkrel="stylesheet"href="styl6.css"></head><body> <sectionid="banner-title"> <h2>MÓJ ORGANIZER</h2> </section> <sectionid="banner-form"> <formmethod="post"> Wpis wydarzenia: <inputtype="text"name="wpis"> <inputtype="submit"value="ZAPISZ"> </form> </section> <sectionid="banner-logo"> <imgsrc="logo2.png"alt="Mój organizer"> </section> <sectionid="main"><?php$result = mysqli_query($connection, "SELECT dataZadania, miesiac, wpis FROM zadania WHERE miesiac = 'sierpien';");while ($row = mysqli_fetch_row($result)) {echo'<section class="day">';echo"<h6>$row[0], $row[1]</h6>";// echo "<p>$row[2]</p>";echo'<p>' . htmlspecialchars($row[2]) . '</p>';echo'</section>'; }?> </section> <footer><?php$result = mysqli_query($connection, "SELECT miesiac, rok FROM zadania WHERE dataZadania = '2020-08-01';");$row = mysqli_fetch_row($result);echo"<h1>miesiąc: $row[0], rok: $row[1]</h1>"; mysqli_close($connection);?> <p>Stronę wykonał: Bartosz Bryniarski</p> </footer></body></html>
Podgląd strony po tym kroku (organizer.php)
Etap 6: Oddanie pracy
Krok 39 · po tym etapie masz 34 z 34 kryteriów (pkt)
Krok 39: 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, kw2.jpg, kw3.jpg, kw4.jpg, kwerendy.txt, logo2.png, organizer.php, przeglądarka.txt i styl6.css (pliki z archiwum mogą zostać). Nagraj płytę, sprawdź jej odczyt, opisz ją numerem PESEL i zostaw w pudełku na stanowisku razem z arkuszem.
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.