Serwis używa plików cookies do analizy ruchu i poprawy działania. Szczegóły
EE.09-01-21.06-SGCzerwiec 2021 · 38 kroków · ok. 77 min · 34 kryteria z klucza
Rozwiązanie krok po kroku: Portal społecznościowy - lista przyjaciół (Wersja podstawowa)
Strona „moje konto” portalu społecznościowego: baza dane z tabelami osoby i hobby z pliku CKE, cztery zapytania (warunek z kilkoma wartościami, złączenie JOIN, LIMIT i CREATE TABLE), zdjęcie wykadrowane do kwadratu 100 × 100 px oraz strona lista.php, na której skrypt PHP wypisuje znajomych - dla każdej osoby blok ze zdjęciem w kółku, blok z imieniem, nazwiskiem i ostatnim wpisem oraz linię oddzielającą.
To arkusz EE.09 z czerwca 2021 - kwalifikacji formuły 2017, którą zastąpiła INF.03. W tej samej sesji był pokrewny arkusz EE.09-04-21.06 (panel administratora portalu): ma te same materiały - bazę osób z hobby i osiem zdjęć - ale inne zapytania, inną stronę i inny skrypt; jego rozwiązanie jest przy tamtym arkuszu. 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 zabezpieczony przed wpisami zawierającymi HTML.
To jest wersja podstawowa. W zakładce „Nowoczesny kod (flex, PDO)” jest drugi sposób rozwiązania tego samego arkusza: flexbox zamiast float, karty znajomych w <article>, PDO na górze pliku i szablon z pętlą foreach - obie wersje są zgodne z kluczem.
Baza i zdjęcia pochodzą z oryginalnego archiwum CKE zad1.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 z PHP to wynik prawdziwego uruchomienia kodu w PHP 8.2 (klucz każe sprawdzać w XAMPP 7.4.8 - użyte funkcje działają w obu wersjach tak samo).
Jak liczą się punkty. Klucz ma 34 kryteria (R.1.1 - R.5.7), 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 zad1
ok. 2 min
Polecenie z arkusza
Na pulpicie znajduje się archiwum ZIP o nazwie zad1.zip zabezpieczone hasłem: List@Przyjaciol& 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 zad1.zip otwierasz programem 7-Zip (albo innym programem do archiwów ZIP) i rozpakowujesz do tego folderu, podając hasło List@Przyjaciol& (wielkość liter, @ i & mają znaczenie). W środku jest plik dane.sql i osiem zdjęć: osoba1.jpg - osoba8.jpg.
Arkusz podkreśla, że pliki strony muszą leżeć w tym samym folderze co zdjęcia - skrypt wstawi ich nazwy z bazy bez żadnej ścieżki.
Typowe błędy
Pliki zapisane poza folderem zdającego (np. w htdocs bez kopii w folderze) nie trafią na płytę - a ocenia się tylko to, co jest na płycie.
Krok 2: XAMPP i pusta baza dane
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 dane
W XAMPP Control Panel klikasz Start przy Apache i MySQL, potem w przeglądarce otwierasz http://localhost/phpmyadmin. Nowa w lewym panelu, nazwa dane, Utwórz. Porównywanie napisów możesz zostawić domyślne - tabele z pliku i tak przyniosą własne kodowanie (latin1).
Typowe błędy
Nazwa bazy musi brzmieć dokładnie dane - skrypt PHP łączy się z bazą po nazwie (R.5.1).
Krok 3: Import pliku dane.sql i zrzut egzamin.jpg
Kryteria:
R.1.1 Wykonano import tabel do bazy danych dane , czynność udokumentowano plikiem o nazwie egzamin w formacie JPEG
ok. 3 min
Polecenie z arkusza
Do bazy dane zaimportuj plik dane.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 JPEG i nazwij egzamin. 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ę dane, karta Import, Wybierz plik → dane.sql, Wykonaj. Plik tworzy pięć tabel: hobby (16 rekordów), osoby (40 rekordów) oraz puste producenci, produkty i rodzaje - do zadania potrzebne są tylko dwie pierwsze.
„Elementy wskazujące na poprawnie wykonany import” to zielony komunikat o sukcesie i lista tabel w lewym panelu albo na karcie Struktura bazy. Zrzut całego ekranu z paskiem zadań zapisujesz jako egzamin.jpg - w tym arkuszu w formacie JPEG, a zrzuty zapytań w PNG.
Typowe błędy
Ten zrzut ma nazwę egzamin i format JPEG (nie import, nie PNG). Wykadrowany zrzut albo zrzut bez paska zadań nie jest oceniany (uwaga w kluczu przy R.1).
Podgląd strony po tym kroku
Krok 4: Zapytanie 1: osoby z hobby 1, 2 albo 6
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 imie, nazwisko, opis, zdjecie z tabeli osoby , dla wszystkich osób, których hobby ma id równe 1, 2, 6. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT imie, nazwisko, opis, zdjecie FROM osoby WHERE Hobby_id = 1 OR Hobby_id = 2 OR Hobby_id = 6; oraz wynik działania zapytania udokumentowano zrzutem, na którym widocznych jest dokładnie 13 rekordów, jedynie pola imie, nazwisko, opis, zdjecie
ok. 4 min
Polecenie z arkusza
Zapisz i wykonaj zapytania SQL działające na bazie dane. Zapytania zapisz w pliku kwerendy.txt, w folderze z numerem PESEL lub w przypadku jego braku w folderze z innym numerem, którym został podpisany arkusz. Wykonaj zrzuty ekranu przedstawiające wyniki działania kwerend. Zrzuty zapisz w formacie PNG 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 imie, nazwisko, opis, zdjecie z tabeli osoby, dla wszystkich osób, których hobby ma id jest jedną z wartości: 1, 2, 6
Zaznacz bazę dane, karta SQL. Zapytanie klauzula po klauzuli:
SELECT imie, nazwisko, opis, zdjecie - dokładnie cztery kolumny z arkusza („jedynie” wyklucza SELECT *),
FROM osoby,
WHERE Hobby_id = 1 OR Hobby_id = 2 OR Hobby_id = 6 - identyfikator hobby siedzi w tabeli osoby, w kolumnie Hobby_id (klucz obcy do hobby.id), więc złączenie nie jest potrzebne. Trzy warunki łączy OR - wystarczy, że spełniony jest jeden.
Wynik: 13 osób (muzyka, film i komputery), jak w kluczu. Zapytanie kopiujesz do pliku kwerendy.txt, a cały ekran zapisujesz jako kw1.png. To samo zapytanie wyśle później skrypt strony.
Typowe błędy
AND zamiast OR szuka osób, które mają jednocześnie trzy różne hobby - wynik jest pusty. Ten sam warunek można zapisać krócej: WHERE Hobby_id IN (1, 2, 6).
kwerendy.txtTekstnowy plik
-- Zapytanie 1SELECT imie, nazwisko, opis, zdjecie FROM osoby WHERE Hobby_id = 1 OR Hobby_id = 2 OR Hobby_id = 6;
Podgląd strony po tym kroku
Krok 5: Zapytanie 2: osoby urodzone po 2000 roku z nazwą hobby
Kryteria:
R.1.4 Utworzono zapytanie 2 wybierające jedynie pola id i nazwisko z tabeli osoby oraz odpowiadające im pole nazwa z tabeli hobby dla osób, które urodziły się po 2000 roku. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT osoby.id, nazwisko, nazwa FROM osoby JOIN hobby ON osoby.hobby_id = hobby.id WHERE rok_urodzenia > 2000; możliwe też INNER JOIN lub bez JOIN z porównaniem kluczy w warunku oraz wynik działania zapytania udokumentowano zrzutem, na którym widocznych jest dokładnie 16 rekordów, jedynie pola osoby.id, nazwisko, nazwa
ok. 4 min
Polecenie z arkusza
Zapytanie 2: wybierające jedynie pola id i nazwisko z tabeli osoby oraz odpowiadające im pole nazwa z tabeli hobby dla osób, które urodziły się po 2000 roku
SELECT osoby.id, nazwisko, nazwa - kolumna id jest w obu tabelach, więc trzeba wskazać, z której ją brać (osoby.id); nazwisko i nazwa są jednoznaczne,
FROM osoby JOIN hobby ON osoby.Hobby_id = hobby.id - złączenie: do każdej osoby dołączany jest wiersz hobby o numerze z jej kolumny Hobby_id,
WHERE rok_urodzenia > 2000 - „po 2000 roku” to rok 2001 i późniejsze, więc znak >, nie >=.
Wynik: 16 rekordów z trzema kolumnami, jak w kluczu. Zrzut: kw2.png.
Typowe błędy
Samo SELECT id, … przy złączeniu kończy się błędem #1052 („Column 'id' in field list is ambiguous”). Bez warunku ON (albo porównania kluczy w WHERE) baza zwróci każdą osobę z każdym hobby - setki wierszy.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT imie, nazwisko, opis, zdjecie FROM osoby WHERE Hobby_id = 1 OR Hobby_id = 2 OR Hobby_id = 6;-- Zapytanie 2SELECT osoby.id, nazwisko, nazwa FROM osoby JOIN hobby ON osoby.Hobby_id = hobby.id WHERE rok_urodzenia > 2000;
Podgląd strony po tym kroku
Krok 6: Zapytanie 3: pierwsze pięć Monik
Kryteria:
R.1.5 Utworzono zapytanie 3 wybierające jedynie pola id i zdjecie z tabeli osoby dla osób które mają na imię Monika. Kwerenda wybiera początkowe 5 wierszy, należy jawnie wskazać liczbę wierszy. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT id, zdjecie FROM osoby WHERE imie='Monika' LIMIT 5; oraz wynik działania zapytania udokumentowano zrzutem, na którym widocznych jest dokładnie 5 rekordów, dane: 2 osoba1.jpg; 4 osoba2.jpg; 7 osoba1.jpg; 12 osoba1.jpg; 17 osoba4.jpg
ok. 2 min
Polecenie z arkusza
Zapytanie 3: wybierające jedynie pola id i zdjecie z tabeli osoby dla osób, które mają na imię Monika. Kwerenda wybiera pierwsze 5 wierszy, należy jawnie wskazać liczbę wierszy
SELECT id, zdjecie FROM osoby,
WHERE imie = 'Monika' - napis w apostrofach,
LIMIT 5 - „jawnie wskazana liczba wierszy”: baza zwraca najwyżej pięć pierwszych pasujących rekordów.
Monik jest w tabeli więcej niż pięć, a phpMyAdmin i tak sam dopisałby LIMIT 0, 25 - dlatego arkusz każe wpisać limit w zapytaniu. Wynik: 2 osoba1.jpg, 4 osoba2.jpg, 7 osoba1.jpg, 12 osoba1.jpg, 17 osoba4.jpg - dokładnie te pary wymienia klucz. Zrzut: kw3.png.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT imie, nazwisko, opis, zdjecie FROM osoby WHERE Hobby_id = 1 OR Hobby_id = 2 OR Hobby_id = 6;-- Zapytanie 2SELECT osoby.id, nazwisko, nazwa FROM osoby JOIN hobby ON osoby.Hobby_id = hobby.id WHERE rok_urodzenia > 2000;-- Zapytanie 3SELECT id, zdjecie FROM osoby WHERE imie = 'Monika' LIMIT 5;
Podgląd strony po tym kroku
Krok 7: Zapytanie 4: tabela wpisy
Kryteria:
R.1.6 Utworzono zapytanie 4 tworzące tabelę o nazwie wpisy , kluczu głównym id typu całkowitego dodatniego oraz polach wpis typu tekstowego i uzytkownik_id typu całkowitego dodatniego. Klucz główny i pole uzytkownik_id nie mogą przyjmować wartości pustych. Klucz główny powinien być jawnie zapisany oraz automatycznie inkrementowany. W pliku z kwerendami lub na zrzucie istnieje zapis np.: CREATE TABLE wpisy ( id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, wpis TEXT, (dopuszczalna dowolna nazwa dla pola tekstowego) uzytkownik_id INTEGER UNSIGNED NOT NULL, PRIMARY KEY(id) ); (dowolne typy całkowite i tekstowe) oraz wynik działania zapytania udokumentowano zrzutem, na którym widoczny jest komunikat o poprawnie wykonanej kwerendzie lub utworzona tabela
ok. 4 min
Polecenie z arkusza
Zapytanie 4: tworzące tabelę o nazwie wpisy z następującymi polami: id, klucz główny jawnie zapisany, typu całkowitego dodatniego, automatycznie inkrementowany, nie może przyjmować wartości pustych; wpis typu tekstowego; uzytkownik_id typu całkowitego dodatniego, nie może przyjmować wartości pustych.
Każde wymaganie ma w zapytaniu swoje słowo:
id INT UNSIGNED NOT NULL AUTO_INCREMENT, - INT to typ całkowity, UNSIGNED - bez znaku, czyli tylko liczby nieujemne („dodatni”), NOT NULL - pole nie może być puste, AUTO_INCREMENT - baza sama nada kolejny numer,
wpis TEXT, - typ tekstowy na dłuższy wpis,
uzytkownik_id INT UNSIGNED NOT NULL, - liczba całkowita dodatnia, obowiązkowa,
PRIMARY KEY (id) - klucz główny zapisany jawnie, osobną klauzulą.
phpMyAdmin odpowiada „MySQL zwrócił pusty wynik” - CREATE TABLE niczego nie wybiera, a w lewym panelu pojawia się tabela wpisy. Zrzut: kw4.png. Plik kwerendy.txt ma komplet czterech zapytań.
Typowe błędy
AUTO_INCREMENT działa tylko na kolumnie, która jest kluczem - bez PRIMARY KEY (id) baza zgłosi błąd #1075.
kwerendy.txtTekstzmienione: 8 linii
-- Zapytanie 1SELECT imie, nazwisko, opis, zdjecie FROM osoby WHERE Hobby_id = 1 OR Hobby_id = 2 OR Hobby_id = 6;-- Zapytanie 2SELECT osoby.id, nazwisko, nazwa FROM osoby JOIN hobby ON osoby.Hobby_id = hobby.id WHERE rok_urodzenia > 2000;-- Zapytanie 3SELECT id, zdjecie FROM osoby WHERE imie = 'Monika' LIMIT 5;-- Zapytanie 4CREATE TABLE wpisy ( id INT UNSIGNED NOT NULL AUTO_INCREMENT, wpis TEXT, uzytkownik_id INT UNSIGNED NOT NULL, PRIMARY KEY (id));
Podgląd strony po tym kroku
Etap 2: Grafika i strona HTML
Kroki 8-20 · po tym etapie masz 16 z 34 kryteriów (pkt)
Krok 8: Grafika: kadr 1:1 z twarzą
ok. 2 min
Polecenie z arkusza
Plik osoba1.jpg, wypakowany z archiwum, skadrowany do proporcji 1:1, tak aby była widoczna twarz osoby.
osoba1.jpg z archiwum ma 300 × 200 px - jest poziomy, a strona pokazuje zdjęcia w kółku, więc potrzebny jest kwadrat. W GIMP-ie narzędzie Zaznaczenie prostokątne z opcją Stała: proporcje 1:1, zaznaczenie 200 × 200 px (cała wysokość zdjęcia) przesunięte tak, żeby twarz była w środku - tutaj od x = 35 px - i Obraz → Przytnij do zaznaczenia. Podgląd pokazuje kadr przed skalowaniem.
Typowe błędy
Kadr z lewej krawędzi zdjęcia (x = 0) ucina twarz z prawej strony - klucz wymaga, żeby twarz była widoczna (R.2.1).
Podgląd strony po tym kroku
Krok 9: Grafika: rozmiar dokładnie 100 × 100 px
Kryteria:
R.2.1 Plik osoba1.jpg zawiera widoczną twarz osoby, rozmiar zdjęcia dokładnie 100 px na 100 px
ok. 2 min
Polecenie z arkusza
Przeskalowany do rozmiaru dokładnie 100 px na 100 px. Pozostałe pliki graficzne są przygotowane i nie należy ich zmieniać
Obraz → Skaluj obraz: szerokość 100, wysokość 100 - kadr jest kwadratowy, więc proporcje się nie zmieniają. Zapis pod tą samą nazwą: Plik → Nadpisz osoba1.jpg (zwykłe Zapisz w GIMP-ie zapisuje format .xcf). Zdjęcia osoba2.jpg - osoba8.jpg mają już 100 × 100 px i zostają bez zmian.
Typowe błędy
Skalowanie całego zdjęcia 300 × 200 do 100 × 100 bez kadrowania spłaszczy twarz - klucz wymaga proporcji 1:1 uzyskanej kadrem.
Podgląd strony po tym kroku
Krok 10: Plik lista.php
Kryteria:
R.2.2 Witrynę internetową zapisano w pliku PHP o nazwie lista
ok. 2 min
Polecenie z arkusza
Składa się ze strony o nazwie lista.php
Plik lista.php w folderze zdającego, obok zdjęć. Rozszerzenie .php, bo dojdzie skrypt - na razie to czysty HTML. <!DOCTYPE html> oznacza HTML5, lang="pl" mówi przeglądarce i czytnikom ekranu, że treść jest po polsku. Nazwę pliku sprawdza klucz (R.2.2) - lista.html albo index.php to strata punktu.
R.2.3 Zastosowano właściwy standard kodowania polskich znaków dla witryny
ok. 1 min
Polecenie z arkusza
Zastosowany właściwy standard kodowania polskich znaków
<meta charset="UTF-8"> jako pierwsza rzecz w <head>. Bez tej linii „Społecznościowy” i „przyjaciół” mogą wyświetlić się jako krzaki. Plik trzeba też zapisać w UTF-8 (w Notepad++ menu Kodowanie).
R.3.3 Strona zawiera działające połączenie z zewnętrznym arkuszem stylów o nazwie styl.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 styl.css prawidłowo połączony z kodem strony
<link rel="stylesheet" href="styl.css"> w <head>. Plik stylów powstanie po HTML-u; całe formatowanie ma pochodzić tylko z niego, bez atrybutów style w HTML-u.
Typowe błędy
Klucz uznaje R.3.3 tylko przy działającym połączeniu, w którym wszystkie selektory trafiają w bloki - selektor klasy zapisany z # (albo identyfikatora z kropką) też odbiera punkt.
R.2.5 Wygląd strony zdefiniowano dzieląc ją na bloki: baner, główny i dwa bloki stopki. Zastosowano znaczniki sekcji
ok. 2 min
Polecenie z arkusza
Podział strony na bloki umiejscowione jeden pod drugim: baner, główny i dwa obok siebie bloki stopki. Podział zrealizowany za pomocą znaczników sekcji tak, aby wygląd układu bloków strony po uruchomieniu w przeglądarce, był zgodny z Obrazem 2
Cztery bloki w kolejności z obrazu 2: baner <header>, blok główny <section> i dwie stopki <footer>. Blok główny dostaje identyfikator main (po angielsku - arkusz go nie narzuca), bo to on będzie miał tło, wysokość i paski przewijania. Obie stopki wyglądają tak samo, więc wystarczy im wspólny selektor znacznika footer - identyfikatory nie są potrzebne. Bloki zdjęcie, opis i linia nie stoją w pliku na stałe - wygeneruje je skrypt dla każdej osoby.
Na razie bloki są puste i stoją jeden pod drugim; stopki ustawi obok siebie CSS.
R.2.6 W bloku banera zapisano nagłówek h1: "Portal Społecznościowy - moje konto" oraz w bloku głównym nagłówki h2: "Moje zainteresowania" i "Moi znajomi"
ok. 1 min
Polecenie z arkusza
Nagłówek drugiego stopnia o treści „Moi znajomi”
Drugi <h2>, pod listą. Pod nim skrypt wypisze znajomych. Strona ma już nagłówek <h1> w banerze i oba nagłówki <h2> (R.2.6).
R.2.8 W pierwszym bloku stopki umieszczono numer PESEL zdającego
ok. 1 min
Polecenie z arkusza
Zawartość pierwszego bloku stopki: napis 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 swój numer PESEL. W tym rozwiązaniu w jego miejscu stoi imię i nazwisko autora: Bartosz Bryniarski.
R.3.2 Na stronie umieszczono odnośnik pocztowy "napisz do mnie" łączący z adresem email (mailto:[email protected])
ok. 1 min
Polecenie z arkusza
Zawartość drugiego bloku stopki: odnośnik pocztowy o treści „napisz do mnie” prowadzący do adresu „[email protected]”
Odnośnik pocztowy ma w href przedrostek mailto: - kliknięcie otwiera program pocztowy z wpisanym adresatem [email protected], zamiast przechodzić do innej strony (R.3.2).
Typowe błędy
href="[email protected]" bez mailto: przeglądarka potraktuje jak nazwę pliku w folderze strony i pokaże błąd 404.
Kroki 21-30 · po tym etapie masz 27 z 34 kryteriów (pkt)
Krok 21: Plik styl.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
Cechy formatowania CSS: Domyślne dla całej strony: krój czcionki Georgia
Nowy plik styl.css w folderze zdającego. Pierwsza reguła: selektor uniwersalny * z font-family: Georgia - krój dostaje każdy element strony. Klucz R.4.1 przyjmuje też body albo html.
styl.cssCSSnowy plik
* {font-family: Georgia;}
Podgląd strony po tym kroku (lista.php)
Krok 22: Baner: tło, kolor, wyśrodkowanie, rozmiar czcionki, wysokość
Kryteria:
R.4.8 Ustawiono rozmiar czcionki banera na 50%
ok. 2 min
Polecenie z arkusza
Dla banera: kolor tła #005B4F, biały kolor czcionki, wyrównanie tekstu do środka, rozmiar czcionki 50%, wysokość 20 px
Selektor znacznika header - na stronie jest jeden baner. font-size: 50% zmniejsza czcionkę o połowę względem rodzica: nagłówek <h1> liczy swój rozmiar (2em) od banera, więc zamiast 32 px ma 16 px i mieści się w pasku o wysokości 20 px (R.4.8).
R.4.9 Ustawiono przynajmniej jeden pasek przewijania (przesuwania) dla bloku głównego, np. overflow: scroll; (lub auto)
ok. 2 min
Polecenie z arkusza
Dla bloku głównego: kolor tła #E1E2E1, wysokość 400px, marginesy wewnętrzne 20 px, paski przesuwania (scroll)
Selektor identyfikatora #main. Znajomych jest trzynaścioro, a blok ma tylko 400 px wysokości - overflow: scroll dokłada paski przewijania, więc treść, która się nie mieści, przewija się wewnątrz bloku, a stopki zostają na swoim miejscu (R.4.9). padding: 20px odsuwa treść od brzegów bloku; dolicza się do wysokości, więc blok zajmuje na ekranie 440 px.
Typowe błędy
Bez overflow treść wylewa się poza szare tło na stopki i dalej w dół strony.
Bloków ze zdjęciem będzie tyle, ilu znajomych, a identyfikator może wystąpić na stronie tylko raz - dlatego skrypt nada im klasęphoto, a w CSS selektor klasy zaczyna się od kropki: .photo. Szerokość 20% liczy się od szerokości bloku głównego. Na razie na stronie nie ma żadnego takiego bloku - reguła zadziała, gdy wypisze je skrypt.
Dla bloku opis: blok jest wyświetlany obok zdjęcia
Blok zdjęcia i blok opisu (klasa description) dostają float: left - pierwszy staje przy lewej krawędzi, drugi tuż obok niego. Bez float każdy blok zajmuje całą szerokość i opis spadłby pod zdjęcie.
Dla bloku linia: linia jest wyświetlana pod zdjęciem i opisem zgodnie z obrazem 2
clear: both każe blokowi linii zacząć się dopiero pod oboma pływającymi blokami. Bez tego kolejna osoba wcisnęłaby się obok poprzedniej, a linia stanęłaby w połowie wysokości zdjęcia.
Krok 27: Obie stopki: tło, kolor, wyśrodkowanie, wymiary i układ obok siebie
Kryteria: , ,
R.3.1 Układ bloków po uruchomieniu strony w przeglądarce jest zgodny z Obrazem 2 w arkuszu egzaminacyjnym (nie uwzględnia się zestawu bloków zawierających: zdjecie, opis, linia)
R.4.4 Ustawiono wysokość bloków dla banera i stopek na 20px oraz bloku głównego na 400px
R.4.5 Ustawiono szerokość stopek na 50% oraz bloku zawierającego zdjęcie na 20%
ok. 3 min
Polecenie z arkusza
Dla obu bloków stopki: kolor tła #005B4F, biały kolor czcionki, wyrównanie tekstu do środka, szerokość 50%, wysokość 20 px
Jedna reguła dla znacznika footer obejmuje obie stopki. Dwie szerokości po 50% to razem 100%, a float: left stawia drugą stopkę obok pierwszej zamiast pod nią - tak jak na obrazie 2 (R.3.1). Arkusz nie podaje tej właściwości, ale wymaga układu z obrazu; stopki nie mają marginesów ani obramowań, więc obie mieszczą się w jednym rzędzie.
Wysokości banera, stopek i bloku głównego (R.4.4) oraz szerokości stopek i bloku zdjęcia (R.4.5) są ustawione.
Typowe błędy
Dowolny margin albo border na stopce przy szerokości 50% zepchnie drugą stopkę pod pierwszą.
Krok 28: Obraz: marginesy wewnętrzne i zaokrąglenie do koła
Kryteria: ,
R.4.7 Ustawiono marginesy wewnętrzne (padding) dla bloku głównego i selektora img na 20px
R.4.10 Ustawiono zakrzywienie obramowania 100% dla obrazu, np. border-radius: 100%; poprawne również dla wartości z przedziału <50%, 100%)
ok. 2 min
Polecenie z arkusza
Dla selektora obrazu: marginesy wewnętrzne 20 px, zakrzywienie obramowania 100% (tak, że obraz jest wyświetlany w kształcie koła)
Selektor znacznika img. border-radius: 100% zaokrągla rogi tak mocno, że kwadratowe zdjęcie 100 × 100 px wyświetla się jako koło (każda wartość od 50% w górę daje ten sam efekt - klucz przyjmuje przedział od 50% do 100%). padding: 20px odsuwa zdjęcie od sąsiednich bloków. Marginesy wewnętrzne bloku głównego i obrazu są ustawione (R.4.7).
Typowe błędy
Kryterium R.4.7 jest spełnione tylko przy selektorze znacznika img - reguła dla klasy (np. .photo img albo .avatar) według uwagi w kluczu go nie spełnia.
Krok 29: Nagłówki drugiego stopnia: wyśrodkowanie i tło
Kryteria: ,
R.4.2 Ustawiono kolor tła #005B4F dla banera i stopek, #E1E2E1 dla bloku głównego oraz #00897B dla selektora h2
R.4.6 Ustawiono wyrównanie tekstu do środka dla banera i stopek oraz dla selektora h2
ok. 1 min
Polecenie z arkusza
Dla selektora nagłówka drugiego stopnia: wyrównanie tekstu do środka, tło #00897B
Selektor h2 obejmuje oba nagłówki bloku głównego. Kolory tła wszystkich elementów (R.4.2) i wyśrodkowanie banera, stopek i nagłówków (R.4.6) są ustawione.
R.4.3 Ustawiono biały kolor czcionki dla banera i stopek oraz selektora a
ok. 1 min
Polecenie z arkusza
Dla selektora odnośnika: biały kolor czcionki
Odnośnik nie dziedziczy koloru po stopce - przeglądarka maluje go własnym niebieskim (a po kliknięciu fioletowym), który na zielonym tle jest prawie niewidoczny. Reguła dla a daje biały (R.4.3). Arkusz stylów jest kompletny.
Kroki 31-36 · po tym etapie masz 34 z 34 kryteriów (pkt)
Krok 31: Miejsce skryptu i połączenie z bazą dane
Kryteria:
R.5.1 Skrypt realizuje połączenie z serwerem bazy danych i wybór bazy dane
ok. 3 min
Polecenie z arkusza
Efekt działania skryptu. Skrypt: Napisany w języku PHP. Skrypt łączy się z serwerem bazy danych na localhost, użytkownik root bez hasła, baza danych o nazwie dane
„Efekt działania skryptu” ma być w bloku głównym, pod nagłówkiem „Moi znajomi” (obraz 2) - tam więc piszesz blok PHP, między <?php a ?>. Serwer wykona go, zanim strona trafi do przeglądarki.
Pierwsza instrukcja: mysqli_connect z tabeli 1 arkusza - kolejno serwer localhost, użytkownik root, puste hasło '' i nazwa bazy dane. Czwarty parametr od razu wybiera bazę, więc mysqli_select_db nie jest potrzebne. Połączenie trafia do zmiennej $connection (R.5.1).
Od tego kroku podgląd to wynik działania strony po stronie serwera (prawdziwe uruchomienie w PHP 8.2) - na razie wygląda jak wcześniej. Stronę sprawdzasz przez http://localhost/…, a nie otwierając plik z dysku: przeglądarka sama nie wykona PHP.
mysqli_query($connection, '…') wysyła do bazy zapytanie 1 skopiowane z kwerendy.txt (R.5.3). Zapytanie stoi w apostrofach PHP, bo samo nie zawiera apostrofów. Wynik - zbiór 13 wierszy - trafia do zmiennej $result; strona jeszcze niczego nie wypisuje.
lista.phpPHPzmienione: 1 linia
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Lista przyjaciół</title> <linkrel="stylesheet"href="styl.css"></head><body> <header> <h1>Portal Społecznościowy - moje konto</h1> </header> <sectionid="main"> <h2>Moje zainteresowania</h2> <ul> <li>muzyka</li> <li>film</li> <li>komputery</li> </ul> <h2>Moi znajomi</h2><?php$connection = mysqli_connect('localhost', 'root', '', 'dane');$result = mysqli_query($connection, 'SELECT imie, nazwisko, opis, zdjecie FROM osoby WHERE Hobby_id = 1 OR Hobby_id = 2 OR Hobby_id = 6;');?> </section> <footer> Stronę wykonał: Bartosz Bryniarski </footer> <footer> <ahref="mailto:[email protected]">napisz do mnie</a> </footer></body></html>
R.5.5 Wyświetlono obraz o nazwie pobranej z bazy danych oraz tekście alternatywnym „przyjaciel”
R.5.7 Wyświetlono wszystkie wiersze zwrócone zapytaniem w oparciu o pętlę
ok. 4 min
Polecenie z arkusza
Dane z każdego zwróconego zapytaniem wiersza podzielone są na trzy bloki: blok zdjęcie, w którym jest wyświetlony obraz o nazwie pobranej z bazy danych oraz tekście alternatywnym „przyjaciel”
while ($row = mysqli_fetch_row($result)) - funkcja z tabeli 1 zwraca kolejny wiersz jako tablicę numerowaną od zera, w kolejności kolumn z zapytania: $row[0] imię, $row[1] nazwisko, $row[2] opis, $row[3] zdjęcie. Gdy wierszy zabraknie, zwraca false i pętla się kończy - przechodzi więc przez wszystkie 13 osób (R.5.7),
echo wypisuje blok z klasą photo, a w nim <img>: nazwa pliku z bazy w src (doklejona operatorem .), stały tekst alternatywny „przyjaciel” (R.5.5).
Podgląd: 13 zdjęć w kółku jedno pod drugim. Pływają do lewej krawędzi, bo blok opisu jeszcze nie istnieje.
Typowe błędy
if zamiast while wypisze tylko pierwszą osobę - klucz wymaga wszystkich wierszy w oparciu o pętlę (R.5.7).
Krok 34: Blok opis: imię i nazwisko oraz ostatni wpis
Kryteria:
R.5.6 Wyświetlono nagłówek trzeciego stopnia z imieniem i nazwiskiem pobranym z bazy danych oraz paragraf (akapit) o treści: „Ostatni wpis: <opis>”, gdzie pole <opis> jest pobrane z bazy danych
ok. 3 min
Polecenie z arkusza
blok opis, w którym jest wyświetlony nagłówek trzeciego stopnia z imieniem i nazwiskiem pobranym z bazy danych oraz paragraf (akapit) o treści: „Ostatni wpis: <opis>”, gdzie pole <opis> jest pobrane z bazy danych
Drugi echo w tej samej pętli: blok z klasą description, w nim nagłówek <h3> z imieniem i nazwiskiem rozdzielonymi spacją ($row[0] . ' ' . $row[1]) i paragraf <p> z napisem „Ostatni wpis: ” i opisem z bazy (R.5.6).
Podgląd: opis stoi obok zdjęcia, jak na obrazie 2 - pierwsza osoba to Monika Kowalska z wpisem „Z checia Ciebie poznam”. Brak polskich liter w opisach („checia”, a u Moniki Kopacz „dzi? rano 5 km”) pochodzi z pliku dane.sql z archiwum CKE - znaki zapytania w miejscu „ś” i „ą” są w nim zapisane dosłownie, skrypt niczego nie psuje.
R.5.4 Dane zwróconego zapytaniem wiersza są podzielone na bloki zawierające: zdjęcie i opis obok siebie, pod spodem linia. W przypadku linii dopuszcza się użycie jej bez znacznika bloku. Zapis jest poprawny składniowo.
ok. 2 min
Polecenie z arkusza
blok linia, w którym jest wyświetlona linia pozioma
Trzeci echo: blok z klasą line, a w nim linia pozioma <hr> (bez znacznika zamykającego). Dzięki clear: both z CSS linia staje pod zdjęciem i opisem, a następna osoba zaczyna się pod nią. Każdy wiersz z bazy jest podzielony na trzy bloki: zdjęcie i opis obok siebie, pod spodem linia (R.5.4).
Podgląd: lista znajomych jak na obrazie 2, przewijana wewnątrz szarego bloku.
R.5.2 Ostatnią operacją na bazie jest jej zamknięcie (zgodne ze składnią)
ok. 1 min
Polecenie z arkusza
Po wykonaniu operacji na bazie danych skrypt zamyka połączenie z serwerem.
mysqli_close($connection) po pętli - to ostatnia operacja na bazie (R.5.2). Wiersze są już odczytane i wypisane, więc zamknięcie niczego nie ucina. Strona spełnia wszystkie kryteria arkusza. Dalej jeden krok o zabezpieczeniu - klucz go nie wymaga.
Typowe błędy
mysqli_close przed pętlą zamyka połączenie, zanim mysqli_fetch_row odczyta wiersze - w PHP 8 kończy się to błędem.
Krok 37 · po tym etapie masz 34 z 34 kryteriów (pkt)
Krok 37: Zabezpieczenie: htmlspecialchars na wyjściu
ok. 4 min
Polecenie z arkusza
blok opis, w którym jest wyświetlony nagłówek trzeciego stopnia z imieniem i nazwiskiem pobranym z bazy danych oraz paragraf (akapit) o treści: „Ostatni wpis: <opis>”, gdzie pole <opis> jest pobrane z bazy danych
Opis to „ostatni wpis” użytkownika portalu - tekst, który wpisał ktoś inny. Skrypt wkleja go do strony wprost, więc przeglądarka wykona każdy znacznik, który się w nim znajdzie. Sprawdzone na wersji z poprzednich kroków: po zmianie opisu Moniki Kowalskiej na <b>Hej!</b> <script>document.title='przejete'</script> wpis wyświetla się pogrubiony, a skrypt z wpisu zmienia tytuł strony. Na prawdziwym portalu taki skrypt mógłby wykraść sesję każdej osoby, która otworzy listę znajomych - to atak XSS (cross-site scripting).
Lekarstwo: każda wartość z bazy przechodzi przez htmlspecialchars() tuż przed wypisaniem. Funkcja zamienia <, >, & i cudzysłowy na encje (<, >…), więc przeglądarka pokazuje je jako zwykłe znaki. Dotyczy to też nazwy pliku zdjęcia - trafia do atrybutu src w cudzysłowie. Podgląd: ten sam wpis widać dosłownie, ze znacznikami, a skrypt się nie wykonuje. Stare linie zostają w komentarzu. Na egzaminie wystarczy wersja wcześniejsza - klucz tego nie sprawdza.
Zapytanie przygotowane (mysqli_prepare) nie jest tu potrzebne: zapytanie 1 nie zawiera żadnej danej od użytkownika.
Typowe błędy
htmlspecialchars przy zapisie do bazy zamiast przy wypisywaniu psuje dane (w bazie lądują encje, a inne programy pokażą <b>). Zasada: dane w bazie zostają surowe, kodowanie robi się na wyjściu, pod konkretne miejsce w HTML-u.
Krok 38 · po tym etapie masz 34 z 34 kryteriów (pkt)
Krok 38: 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 weryfikowałeś 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/….
W folderze z numerem zdającego muszą być: egzamin.jpg, kw1.png, kw2.png, kw3.png, kw4.png, kwerendy.txt, lista.php, osoba1.jpg - osoba8.jpg, przeglądarka.txt i styl.css (plik dane.sql z archiwum może zostać). Nagraj płytę, sprawdź jej odczyt, opisz ją numerem zdającego i zostaw na stanowisku w pudełku razem z arkuszem. Pusta lub nieczytelna płyta to zero punktów za wszystkie pięć rezultatów.
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.