Serwis używa plików cookies do analizy ruchu i poprawy działania. Szczegóły
E.14-03-21.06-SGCzerwiec 2021 · 40 kroków · ok. 81 min · 33 kryteria z klucza
Rozwiązanie krok po kroku: Biblioteka miejska - dodawanie czytelników (Nowoczesny kod (flex, PDO))
To drugi sposób rozwiązania tego samego arkusza. Wynik jest ten sam - baza biblioteka z czterema zapytaniami i strona biblioteka.php z listą autorów i formularzem nowego czytelnika - i tak samo spełnia każde kryterium klucza. Inna jest droga:
flex zamiast float: trzy panele stoją we wspólnym <main>, który układa je w rzędzie, a stopka nie potrzebuje clear,
zmienne CSS dla dwóch kolorów z arkusza, etykiety <label for> i wiersze formularza w blokach zamiast <br>,
PHP na PDO na górze pliku, przed HTML-em: najpierw zapis nowego czytelnika, potem lista autorów - w panelach zostaje samo wypisywanie,
zapytanie przygotowane do INSERT, sprawdzenie danych (puste pola, rok urodzenia z sensownego zakresu, długość kolumn), kod czytelnika liczony funkcjami mb_, które rozumieją polskie litery,
dane wracają do pól po błędzie, a po dodaniu czytelnika przekierowanie - odświeżenie strony nie doda go drugi raz.
To arkusz E.14 z czerwca 2021 - kwalifikacji formuły 2012, którą zastąpiła INF.03. Baza i grafika pochodzą z archiwum odtworzonego z plików zgodnych z arkuszem (załącznik pliki3.zip na stronie arkusza, hasło jak w arkuszu), zapytania i zrzuty są policzone na MariaDB 10.4, a podgląd od kroków z PHP to wynik prawdziwego uruchomienia kodu w PHP 8.2 (klucz każe sprawdzać w XAMPP 7.4.8 - użyte konstrukcje działają w obu wersjach).
Jak liczą się punkty. Klucz ma 33 kryteria (R.1.1 - R.5.8), każde za 1 punkt. Próg zdania części praktycznej to 75%, czyli 25 punktów. Przy każdym kroku jest napisane, które kryteria spełnia; klucz przyjmuje zarówno mysqli, jak i PDO.
Suwak i strzałki obok niego - albo ←→ na klawiaturze - przechodzą krok po kroku; wyjaśnienie, pliki i podgląd zmieniają się razem z krokiem.
Lista „Etap” przenosi od razu do wybranego etapu.
„Rozwiązuję samodzielnie” chowa rozwiązanie kroku - najpierw własna próba, potem odsłonięcie.
„Tryb prezentacji” pokazuje same kroki, bez menu strony - na rzutnik.
Etap 1: Baza danych
Kroki 1-7 · po tym etapie masz 6 z 33 kryteriów (pkt)
Krok 1: Folder zdającego i archiwum pliki3.zip
ok. 2 min
Polecenie z arkusza
Aby wykonać zadanie, zaloguj się na konto Egzamin bez hasła. Na pulpicie znajdziesz archiwum ZIP o nazwie pliki3.zip zabezpieczone hasłem: Arch!wumE_14. Archiwum należy rozpakować. Na pulpicie konta Egzamin utwórz folder. Jako nazwy folderu użyj swojego numeru PESEL. Rozpakowane pliki umieść w tym folderze. Wyniki swojej pracy również zapisz w tym folderze.
Folder na pulpicie nazwany numerem PESEL (w tym rozwiązaniu w jego miejscu stoi Bartosz Bryniarski), do niego archiwum pliki3.zip rozpakowane z hasłem Arch!wumE_14. W środku: biblioteka.sql i biblioteka.png. Do tego folderu trafiają wszystkie rezultaty pracy.
Krok 2: XAMPP i pusta baza biblioteka
ok. 2 min
Polecenie z arkusza
Uruchom usługi MySQL i Apache z XAMPP Control Panel i przejdź do narzędzia phpMyAdmin. Następnie wykonaj operacje na bazie danych: Utwórz nową bazę danych o nazwie biblioteka
Start przy Apache i MySQL, potem http://localhost/phpmyadmin, Nowa, nazwa biblioteka, porównywanie np. utf8mb4_polish_ci, Utwórz.
Krok 3: Import pliku biblioteka.sql i zrzut import.jpg
Kryteria:
R.1.1 Wykonano import tabel z pliku biblioteka.sql do bazy danych o nazwie biblioteka. Czynność udokumentowano plikiem o nazwie import w formacie JPEG
ok. 3 min
Polecenie z arkusza
Do bazy zaimportuj tabele z pliku biblioteka.sql, z wcześniej rozpakowanego archiwum. Wykonaj zrzut ekranu po imporcie. Zrzut zapisz w folderze z Twoim numerem PESEL, w formacie JPEG 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
Baza biblioteka, karta Import, plik biblioteka.sql, Wykonaj. Plik sam tworzy sześć tabel z obrazu 1 i wstawia dane: autorzy (10), czytelnicy (10), kategorie (3), ksiazki (21), wydawnictwa (4), wypozyczenia (10). Zrzut całego ekranu z komunikatem o imporcie i listą tabel: import.jpg (R.1.1).
Podgląd strony po tym kroku
Krok 4: Zapytanie 1: imiona i nazwiska autorów
Kryteria: ,
R.1.2 Zapisano plik kwerendy.txt zawierający co najmniej jedno zapytanie SQL, wynikające z treści zadania
R.1.3 Zapisano zapytanie 1 wybierające jedynie pola imie i nazwisko dla wszystkich rekordów w tabeli autorzy . W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT imie, nazwisko FROM autorzy; oraz na zrzucie widoczne są jedynie imiona i nazwiska wszystkich autorów (10 rekordów)
ok. 2 min
Polecenie z arkusza
Zapytanie 1: wybierające jedynie pola imie i nazwisko dla wszystkich rekordów w tabeli autorzy
Dwie kolumny, bez warunku - 10 autorów. Zapytanie trafia do kwerendy.txt (R.1.2), zrzut do kw1.jpg (R.1.3). Każda klauzula w osobnej linii - przy dłuższych zapytaniach łatwiej wtedy znaleźć błąd.
kwerendy.txtTekstnowy plik
-- Zapytanie 1SELECT imie, nazwiskoFROM autorzy;
Podgląd strony po tym kroku
Krok 5: Zapytanie 2: nowy czytelnik Anna Michalak
Kryteria:
R.1.4 Zapisano zapytanie 2 wstawiające dane do tabeli czytelnicy: Anna, Michalak, ANMI05. W pliku z kwerendami lub na zrzucie istnieje zapis np.: INSERT INTO czytelnicy VALUES (null, 'Anna', 'Michalak', 'ANMI05'); oraz na zrzucie widoczne jest potwierdzenie dodania rekordu lub wykonanie zapytania bez błędów
ok. 2 min
Polecenie z arkusza
Zapytanie 2: wstawiające do tabeli czytelnicy nowy rekord z danymi: Anna, Michalak, ANMI05
Lista kolumn bez id - numer nada AUTO_INCREMENT (Anna dostaje 11). Zrzut: kw2.jpg (R.1.4). Kod ANMI05 to wzór dla skryptu: dwie litery imienia, dwie litery nazwiska, dwie ostatnie cyfry roku urodzenia.
R.1.5 Zapisano zapytanie 3 wybierające jedynie pole tytul dla wszystkich utworów z kategorii epika. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT tytul FROM ksiazki, kategorie WHERE ksiazki.id_kategoria=kategorie.id AND nazwa='epika'; (dozwolona również wersja zapytania bez relacji: SELECT tytul FROM ksiazki WHERE id_kategoria = 1, relację można zapisać poprzez INNER JOIN) oraz na zrzucie widoczne są jedynie tytuły 10 utworów: Kosmos, Ferdydurke, Transatlantyk, Pech, Lesio, Quo vadis, Potop, Ogniem i mieczem, Panny roztropne, Zamek z piasku
ok. 3 min
Polecenie z arkusza
Zapytanie 3: wybierające jedynie pole tytul dla wszystkich utworów w tabeli ksiazki, należących do kategorii epika
JOIN kategorie ON ksiazki.id_kategoria = kategorie.id dołącza do książki jej kategorię, a WHERE kategorie.nazwa = 'epika' zostawia epikę - zapytanie nie zależy od numeru kategorii w tabeli. Wynik: 10 tytułów, od Kosmosu do Zamku z piasku. Zrzut: kw3.jpg (R.1.5).
kwerendy.txtTekstzmienione: 6 linii
-- Zapytanie 1SELECT imie, nazwiskoFROM autorzy;-- Zapytanie 2INSERT INTO czytelnicy (imie, nazwisko, kod)VALUES ('Anna', 'Michalak', 'ANMI05');-- Zapytanie 3SELECT tytulFROM ksiazkiJOIN kategorie ON ksiazki.id_kategoria = kategorie.idWHERE kategorie.nazwa = 'epika';
Podgląd strony po tym kroku
Krok 7: Zapytanie 4: książki wypożyczone przez czytelnika 3
Kryteria:
R.1.6 Zapisano zapytanie 4 wybierające jedynie pole tytul wszystkich utworów w tabeli ksiazki wypożyczonych przez czytelnika o identyfikatorze 3. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT tytul FROM ksiazki, wypozyczenia WHERE ksiazki.id=wypozyczenia.id_ksiazka AND id_czytelnik=3; lub SELECT tytul FROM ksiazki INNER JOIN wypozyczenia ON ksiazki.id=wypozyczenia.id_ksiazka AND id_czytelnik=3); oraz na zrzucie widoczne są jedynie tytuły: Rzepka oraz Kosmos
ok. 3 min
Polecenie z arkusza
Zapytanie 4: wybierające jedynie pole tytul wszystkich utworów w tabeli książki, wypożyczonych przez czytelnika o identyfikatorze 3
Złączenie książek z wypożyczeniami i warunek id_czytelnik = 3. Wynik: Rzepka i Kosmos. Trzeci wpis czytelnika 3 w tabeli wypozyczenia wskazuje książkę numer 15, której nie ma w tabeli ksiazki - JOIN pomija wiersz bez pary. Zrzut: kw4.jpg (R.1.6).
kwerendy.txtTekstzmienione: 6 linii
-- Zapytanie 1SELECT imie, nazwiskoFROM autorzy;-- Zapytanie 2INSERT INTO czytelnicy (imie, nazwisko, kod)VALUES ('Anna', 'Michalak', 'ANMI05');-- Zapytanie 3SELECT tytulFROM ksiazkiJOIN kategorie ON ksiazki.id_kategoria = kategorie.idWHERE kategorie.nazwa = 'epika';-- Zapytanie 4SELECT tytulFROM ksiazkiJOIN wypozyczenia ON ksiazki.id = wypozyczenia.id_ksiazkaWHERE wypozyczenia.id_czytelnik = 3;
Podgląd strony po tym kroku
Etap 2: Strona HTML
Kroki 8-19 · po tym etapie masz 17 z 33 kryteriów (pkt)
R.2.1 Witrynę internetową zapisano w pliku biblioteka.php oraz zastosowano właściwy standard kodowania polskich znaków
R.2.2 Nadano tytuł stronie "Biblioteka”, jest on widoczny na karcie przeglądarki
R.3.5 Strona zawiera działające połączenie z zewnętrznym arkuszem stylów o nazwie styl.css , formatowanie pochodzi jedynie z pliku CSS Uwaga: kryterium to nie jest spełnione również, gdy źle przypisano co najmniej jeden selektor do bloku (np. kropka zamiast #)
ok. 3 min
Polecenie z arkusza
Składa się ze strony o nazwie biblioteka.php. Zastosowany właściwy standard kodowania polskich znaków. Tytuł strony widoczny na karcie przeglądarki: „Biblioteka”. Arkusz stylów w pliku o nazwie styl.css prawidłowo połączony z kodem strony
Szkielet HTML5 w pliku biblioteka.php: lang="pl", <meta charset="UTF-8"> jako pierwszy element <head> (R.2.1), <meta name="viewport"> - na telefonie strona nie będzie pomniejszana jak widok komputera, tytuł Biblioteka (R.2.2) i odnośnik do styl.css (R.3.5). Plik zapisz w kodowaniu UTF-8.
Typowe błędy
R.3.5 przepada, gdy którykolwiek selektor nie trafia w blok (np. .left zamiast #left) albo gdy część formatowania siedzi w atrybutach style.
R.2.3 Układ strony zdefiniowano dzieląc ją na baner, panele lewy, środkowy, prawy oraz stopkę. Zastosowano znaczniki sekcji.
ok. 2 min
Polecenie z arkusza
Podział strony na bloki: na górze baner, poniżej bloki: lewy, środkowy i prawy oraz 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
Baner to <header>, stopka <footer>, a trzy panele - znaczniki <section> z identyfikatorami left, middle i right (R.2.3). Panele stoją we wspólnym <main>: to główna treść strony (czytnik ekranu pozwala do niej przeskoczyć), a jednocześnie pojemnik, który w CSS ułoży panele w rzędzie. Baner i stopka zostają poza nim - zajmują całą szerokość.
Nagłówek trzeciego stopnia o treści: „ul. Czytelnicza 25 12-120 Książkowice tel.: 555666777 e-mail: [email protected]”. Treść nagłówka podzielona jest na cztery wiersze zgodnie z obrazem 2. Napis [email protected] jest odsyłaczem pocztowym łączącym z tym samym adresem e-mail
<h3> z trzema <br> - cztery wiersze jak na obrazie 2. Adres e-mail to odnośnik mailto: (R.3.4): kliknięcie otwiera program pocztowy z wpisanym odbiorcą.
⚠️ Rozbieżność arkusz-klucz: treść arkusza podaje telefon 555666777, a obraz 2 i klucz (R.2.4) - 123123123. Arkusz sam sobie przeczy, więc wpisany jest numer z obrazu 2 i z klucza.
Krok 13: Blok środkowy: nagłówek i formularz metodą post
Kryteria:
R.3.2 Dane z formularza przesyłane są za pomocą metody POST
ok. 1 min
Polecenie z arkusza
Zawartość bloku środkowego: Nagłówek drugiego stopnia o treści „Dodaj nowego czytelnika”. Formularz wysyła dane do serwera za pomocą przycisku DODAJ, metodą post
<h2> i <form method="post"> bez action - dane wracają do biblioteka.php, gdzie czeka skrypt (R.3.2). Metoda POST przesyła je w treści żądania, nie w adresie strony.
Pole edycyjne typu tekstowego poprzedzone napisem „imię:”
Napis staje się etykietą<label for="first-name">, związaną z polem o id="first-name": kliknięcie napisu ustawia kursor w polu, a czytnik ekranu odczyta „imię” przy wejściu w pole. name="imie" to klucz w $_POST - bez polskiej litery, jak kolumna w bazie. Etykieta z polem stoją we własnym <div>, więc kolejne pole zacznie się w nowym wierszu bez <br>.
maxlength="30" - kolumna imie ma 30 znaków; required - przeglądarka nie wyśle formularza z pustym polem. To tylko wygoda dla użytkownika: dane i tak sprawdzi serwer, bo formularz da się wysłać z pominięciem przeglądarki.
R.2.6 W bloku środkowym umieszczono: dwa pola edycyjne typu tekstowego, jedno pole edycyjne typu numerycznego oraz przycisk
R.3.3 Przycisk wysyła dane z formularza (input lub button z typem submit lub button bez typu)
ok. 1 min
Polecenie z arkusza
Przycisk DODAJ – realizujący skrypt 2
<button type="submit"> - w odróżnieniu od <input> może zawierać dowolną treść, a typ submit wysyła formularz (R.3.3). Formularz ma dwa pola tekstowe, pole numeryczne i przycisk (R.2.6).
R.2.4 Zapisano wszystkie nagłówki: w banerze - h1 "Miejska Biblioteka Publiczna w Książkowicach”, w bloku lewym - h3 "ul. Czytelnicza 25 12-120 Książkowice tel.: 123123123 e-mail: [email protected]", w bloku środkowym - h2 "Dodaj nowego czytelnika”, w bloku prawym - h2 "W naszych zbiorach znajdziesz dzieła następujących autorów:”
ok. 2 min
Polecenie z arkusza
Zawartość bloku prawego: Nagłówek drugiego stopnia o treści „W naszych zbiorach znajdziesz dzieła następujących autorów:”. Lista numerowana (uporządkowana) zgodna z obrazem 3, elementy listy generowane są skryptem 1
Drugi <h2> - wszystkie cztery nagłówki są na miejscu (R.2.4). Pod nim pusta lista numerowana <ol>; elementy wypisze skrypt 1.
⚠️ Sprzeczność w arkuszu: obraz 3 i ta część arkusza mówią o liście numerowanej, a opis skryptu 1 - o punktowanej. Klucz (R.2.5) przyjmuje <ol> albo <ul>; wybrana jest lista z obrazów 2 i 3.
Kroki 20-30 · po tym etapie masz 24 z 33 kryteriów (pkt)
Krok 20: Plik styl.css: kolory jako zmienne i baner
ok. 2 min
Polecenie z arkusza
format banera: kolor tła #00CCFF, wysokość 70 px
Na początku pliku zmienne CSS w :root: dwa kolory z arkusza dostają nazwy --blue i --orange, a reguły używają var(--blue). Każdy kolor występuje na stronie kilka razy - zmiana odcienia to wtedy jedna linia. Pierwsza reguła: baner.
R.3.1 Układ bloków po uruchomieniu strony w przeglądarce jest zgodny z obrazem 2 w arkuszu
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
display: flex na <main> - jego dzieci, trzy sekcje, stają obok siebie w jednym rzędzie. Stopka stoi pod <main> zwyczajnie, bez clear, bo nic tu nie „pływa”. Szerokości paneli ustawisz na samych panelach - klucz z 2021 roku sprawdza właściwość width przy panelach (R.4.3), dlatego nie siatka z kolumnami.
Od tego kroku układ bloków odpowiada obrazowi 2 (R.3.1) - panele są na razie wąskie, bo jeszcze nie mają szerokości.
Krok 25: Stopka: tło, wysokość, wyrównanie do prawej
Kryteria: , ,
R.4.1 Ustawiono kolor tła dla banera, stopki i panelu środkowego na #00CCFF oraz panelu lewego i prawego na #E3A329
R.4.2 Ustawiono wysokość banera i stopki na 70px oraz paneli: lewego i prawego i środkowego na 450px
R.4.4 Ustawiono wyrównanie tekstu do prawej dla: stopki
ok. 1 min
Polecenie z arkusza
format stopki: kolor tła #00CCFF, wysokość 70 px, wyrównanie tekstu do prawej
Kolory tła (R.4.1) i wysokości (R.4.2) wszystkich bloków są ustawione, tekst stopki stoi przy prawej krawędzi (R.4.4).
Druga reguła to dodatek spoza arkusza: górny margines akapitu w stopce (16 px) „przecieka” na zewnątrz stopki - to łączenie marginesów - i między panelami a stopką pojawiłby się biały pasek. W wersji podstawowej paska nie ma, bo stopka z clear: both stoi pod pływającymi panelami. margin-top: 0 przy akapicie stopki daje wygląd z obrazu 2.
Kroki 31-38 · po tym etapie masz 33 z 33 kryteriów (pkt)
Krok 31: Skrypt na górze pliku i połączenie z bazą biblioteka
Kryteria: ,
R.5.1 Skrypt napisano w języku PHP i umieszczono w pliku biblioteka.php
R.5.2 Zastosowano funkcję realizującą połączenie z serwerem bazy danych na localhost, użytkownik root, bez hasła, baza danych biblioteka
ok. 4 min
Polecenie z arkusza
Napisany w języku PHP, umieszczony w pliku biblioteka.php. Skrypt łączy się z serwerem bazodanowym na localhost, użytkownik root bez hasła, baza danych o nazwie biblioteka
Skrypt stoi na samej górze biblioteka.php, przed <!DOCTYPE html> (R.5.1): najpierw przygotowuje dane, potem HTML je tylko wypisuje. Pod formularzem zostają trzy linie: jeśli jest komunikat, wypisz go w akapicie <p>.
e() - krótka funkcja z htmlspecialchars: każdy tekst wypisywany na stronie zamienia <, >, & i cudzysłowy na encje, więc znaczniki wpisane w formularz nie staną się kodem strony,
new PDO(...) - serwer localhost, baza biblioteka i kodowanie w jednym napisie, potem użytkownik root i puste hasło (R.5.2). ERRMODE_EXCEPTION - każdy błąd bazy rzuca wyjątek, FETCH_ASSOC - wiersze wyniku przychodzą jako tablice z nazwami kolumn,
try / catch - gdy baza nie działa, uczeń dostaje zwykłe zdanie, a nie komunikat PHP z danymi serwera.
PDO zamiast funkcji mysqli z tabeli 1 - klucz przyjmuje obie biblioteki (uwaga przy R.5). Połączenie z nazwą bazy stoi w pliku strony, bo tam klucz je sprawdza, jeśli strona się nie uruchomi. Od tego kroku podgląd to wynik prawdziwego uruchomienia strony.
R.2.5 W bloku prawym umieszczono dowolną listę, zawierającą imiona i nazwiska autorów. W kodzie HTML lub PHP użyto znaczników <ol> lub <ul> oraz <li> i ich zamknięcia
R.5.4 Skrypt 1 wyświetla imiona i nazwiska wszystkich autorów zwrócone zapytaniem 1
R.5.5 Wyświetlane przez skrypt 1 imiona i nazwiska autorów są umieszczone w elementach listy
ok. 4 min
Polecenie z arkusza
Skrypt 1: Wysyła do bazy danych zapytanie 1 (z pliku kwerendy.txt). Imiona i nazwiska wszystkich autorów pobrane zapytaniem wypisywane są jako elementy listy punktowanej (nieuporządkowanej) zgodnie z obrazem 3
Dwie części w dwóch miejscach pliku:
na górze $pdo->query(...) wysyła zapytanie 1 z kwerendy.txt - bez danych od użytkownika, więc wystarczy zwykłe query - a fetchAll() od razu zwraca wszystkie wiersze jako tablicę, bez pętli while,
w liście <ol> pętla foreach w zapisie alternatywnym (foreach (...): … endforeach;), który dobrze czyta się między znacznikami HTML. Każdy autor to jeden <li>, a imię i nazwisko przechodzą przez e().
Podgląd: lista numerowana z 10 autorami - jak na obrazie 3. Skrypt 1 wyświetla autorów z zapytania 1 (R.5.4) w elementach listy (R.5.5), w bloku prawym jest lista z imionami i nazwiskami (R.2.5).
Krok 33: Skrypt 2: pobranie i sprawdzenie danych z formularza
ok. 4 min
Polecenie z arkusza
Skrypt 2: Pobiera dane z formularza
Skrypt 2 stoi w skrypcie przed zapytaniem 1 - najpierw zapis, potem odczyt. Działa tylko po wysłaniu formularza ($_SERVER['REQUEST_METHOD'] === 'POST'):
$_POST['imie'] ?? '' - operator ?? daje pusty napis, gdy pola w ogóle nie wysłano, zamiast ostrzeżenia PHP; trim() zdejmuje spacje z brzegów,
filter_var(..., FILTER_VALIDATE_INT, ...) zamienia rok na liczbę całkowitą tylko wtedy, gdy jest liczbą z zakresu 1900 - bieżący rok; w każdym innym przypadku zwraca false,
puste imię lub nazwisko albo zły rok - komunikat; za długie imię lub nazwisko (kolumny mają 30 i 50 znaków, a XAMPP dłuższy tekst po cichu ucina) - osobny komunikat.
Pola formularza dostały value z wpisanymi danymi - po błędzie nie trzeba wpisywać wszystkiego od nowa - a pole roku górną granicę max z bieżącego roku. Podgląd: rok urodzenia 206 zamiast 2006.
R.5.7 Skrypt 2 generuje kod czytelnika (dwie początkowe litery z imienia, dwie początkowe litery z nazwiska oraz dwie ostatnie cyfry z roku urodzenia, wszystkie litery są wielkie)
ok. 3 min
Polecenie z arkusza
Tworzy kod czytelnika składający się z dwóch początkowych liter imienia, dwóch początkowych liter nazwiska (wszystkie litery powinny być wielkie) oraz dwóch ostatnich cyfr z roku urodzenia
mb_substr($firstName, 0, 2) - dwa pierwsze znaki imienia: z „Tomasz” To; tak samo z nazwiska - No,
mb_strtoupper() - wielkie litery: TONO,
substr((string) $year, -2) - dwie ostatnie cyfry roku jako napis: 06.
Funkcje mb_ liczą znaki, a nie bajty: zwykłe substr dla imienia „Łucja” wzięłoby tylko Ł (w UTF-8 ta litera zajmuje dwa bajty), a strtoupper nie zmienia polskich liter. Z mb_ kod Łucji Żak to ŁUŻA04. Dla danych z podglądu: TONO06 (R.5.7).
Typowe błędy
$year % 100 daje dla roku 2005 liczbę 5, a nie 05 - kod ma wtedy pięć znaków.
Krok 35: Skrypt 2: zapytanie 2 jako zapytanie przygotowane
Kryteria:
R.5.8 Skrypt 2 dodaje do tabeli czytelnicy nowy rekord, zawierający przynajmniej dwa elementy z trzech: imię, nazwisko pobrane z formularza, wygenerowany kod (należy sprawdzić w bazie czy rekord został dodany)
ok. 3 min
Polecenie z arkusza
Wysyła do bazy danych zmodyfikowane zapytanie 2 (z pliku kwerendy.txt), wstawiające do tabeli czytelnicy nowy rekord zawierający imię i nazwisko pobrane z formularza oraz kod czytelnika wygenerowany w skrypcie
Zapytanie 2, w którym wartości zastępują parametry:imie, :nazwisko i :kod: $pdo->prepare(...) wysyła do bazy samą treść zapytania, a $statement->execute([...]) - osobno dane. Dane nigdy nie staną się częścią kodu SQL, więc nazwisko z apostrofem (O'Neal) zapisuje się bez błędu.
Sprawdzenie, jak każe klucz (R.5.8): w tabeli czytelnicy jest nowy wiersz - 12, Tomasz, Nowak, TONO06.
R.5.6 Skrypt 2 wyświetla napis: "Czytelnik ……. został dodany do bazy danych" (w miejscu kropek powinno znaleźć się imię lub/i nazwisko pobrane z formularza)
ok. 1 min
Polecenie z arkusza
Wyświetla napis „Czytelnik: ……………………. został dodany do bazy danych” (w miejscu kropek należy umieścić imię i nazwisko pobrane z formularza)
Komunikat ustawiany dopiero po execute - gdyby zapis się nie udał, wyjątek przeskoczy tę linię i pojawi się komunikat z catch. Na stronie wypisuje go akapit pod formularzem, przez e() (R.5.6).
R.5.3 Ostatnią operacją na bazie jest jej zamknięcie (zgodne ze składnią)
ok. 2 min
Polecenie z arkusza
Na końcu działania skrypt zamyka połączenie z serwerem
PDO nie ma funkcji close - połączenie zamyka się, gdy znika ostatnie odwołanie do obiektu. Dlatego $statement = null i $pdo = null w bloku finally: wykona się on zawsze po try, zarówno gdy wszystko się udało, jak i po wyjątku - zamknięcie jest ostatnią operacją na bazie w każdej gałęzi (R.5.3). Lista autorów jest już wtedy w tablicy $authors, więc HTML nie potrzebuje bazy.
Krok 38: Odświeżenie po dodaniu czytelnika nie wysyła formularza drugi raz
ok. 4 min
Dodatek spoza arkusza - klucz go nie ocenia. Strona po wysłaniu formularza jest wynikiem żądania POST, więc odświeżenie (F5) pyta, czy wysłać dane ponownie - i drugi raz dodałoby tego samego czytelnika. Wzorzec PRG (Post/Redirect/Get):
session_start() na samym początku pliku - sesja przechowa komunikat między dwoma żądaniami,
po udanym zapisie $readerAdded = true, a po bloku finally (połączenie jest już zamknięte) komunikat trafia do $_SESSION, a header('Location: biblioteka.php') każe przeglądarce wczytać stronę jeszcze raz zwykłym żądaniem GET. exit jest konieczne - header tylko ustawia nagłówek i nie zatrzymuje skryptu,
nowe wejście odczytuje komunikat z sesji i od razu go usuwa (unset), więc pokaże się raz.
Sprawdzone na prawdziwym PHP: wysłanie formularza daje odpowiedź 302, potem „Czytelnik: Tomasz Nowak został dodany do bazy danych”, a kolejne odświeżenie - stronę bez komunikatu i bez drugiego Tomasza w tabeli. Podgląd: stan po przekierowaniu.
Krok 39 · po tym etapie masz 33 z 33 kryteriów (pkt)
Krok 39: Co jest inaczej i którą wersję wybrać na egzaminie
ok. 3 min
Obie wersje dają komplet 33 punktów. Różnice:
wersja podstawowa
wersja nowoczesna
układ
float: left trzech sekcji, clear stopki
<main> z display: flex
kolory
wpisane w każdej regule
zmienne --blue, --orange
formularz
napis, pole, <br>
label for, wiersze w <div>, maxlength, required, zakres roku
biblioteka
mysqli (tabela 1 arkusza)
PDO z wyjątkami
gdzie są skrypty
w panelach, połączenie w bloku środkowym
na górze pliku, w panelach tylko wypisywanie
dane z formularza
$_POST wprost
?? '', trim, filter_var z zakresem, długość kolumn
kod czytelnika
substr, strtoupper - gubią polskie litery
mb_substr, mb_strtoupper
INSERT
dane wklejone w treść zapytania
parametry :imie, :nazwisko, :kod
wypisanie imienia i nazwiska
wprost, znaczniki działają jak HTML
przez e() (htmlspecialchars)
zamknięcie bazy
mysqli_close na końcu skryptu 1
$pdo = null w finally
po wysłaniu
puste pola, F5 dodaje czytelnika ponownie
dane wracają do pól po błędzie, po dodaniu przekierowanie
Jednej rzeczy żadna wersja nie naprawi z poziomu PHP: tabela czytelnicy z pliku biblioteka.sql ma kodowanie latin1, w którym nie ma liter Ł, Ż, ś, ę. Sprawdzone: Łucja Żak zapisuje się jako ?ucja ?ak z kodem ?U?A04. Poza egzaminem tabelę przepisuje się na UTF-8 zapytaniem ALTER TABLE czytelnicy CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_polish_ci; - na egzaminie struktury bazy z arkusza się nie zmienia.
Na egzaminie wersja podstawowa trzyma się funkcji z tabeli 1 i łatwiej ją napisać bez dokumentacji. Nowoczesna nie wywraca się na apostrofie, nie dodaje pustych czytelników i nie dodaje nikogo drugi raz po odświeżeniu - a klucz przyjmuje obie.
Krok 40 · po tym etapie masz 33 z 33 kryteriów (pkt)
Krok 40: 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 nazwa przeglądarki, w której sprawdzana była strona. W folderze z numerem zdającego: przeglądarka.txt, import.jpg, kw1.jpg - kw4.jpg, kwerendy.txt, biblioteka.php, styl.css i biblioteka.png. Nagraj płytę, sprawdź jej odczyt i opisz ją numerem PESEL.
Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.
To jedno z możliwych rozwiązań. Egzaminator ocenia spełnienie kryteriów z klucza odpowiedzi, a nie zgodność z tym kodem - inna, poprawna droga też daje punkty.
Autor rozwiązania: Bartosz Bryniarski. Licencja CC BY-NC 4.0 - kopiowanie i przeróbki do celów niekomercyjnych, z podaniem autora i źródła (link do tej strony) (zasady wykorzystania). Treść arkusza i klucza oceniania pochodzi z CKE.