INF.03-01-26.06-SGCzerwiec 2026 · 50 kroków · ok. 95 min · 37 kryteriów z klucza
Rozwiązanie krok po kroku: Portal turystyczny Islandii (Wersja podstawowa)
Rozwiązanie buduje portal turystyczny o Islandii: baza islandia z trzema tabelami połączonymi relacją i czterema zapytaniami (SELECT z warunkiem, złączenie z tabelą rodzajów, warunek z AND, grupowanie z COUNT i aliasem), dwie strony PHP ze wspólnym nagłówkiem, blokiem bocznym i stopką - islandia.php z galerią miniatur i obiekty.php z opisem miejsca wybranego w galerii - oraz style w styl.css z zaokrągleniami, linią kreskową, paskami przewijania i płynną zmianą przezroczystości po najechaniu kursorem. Cztery skrypty PHP: dwie listy numerowane w bloku bocznym, galeria odnośników przekazujących identyfikator metodą GET i strona opisu, która ten identyfikator odczytuje z $_GET.
Kroki idą zdanie po zdaniu za treścią arkusza - każdy zaczyna się poleceniem z arkusza, a kod pokazuje dokładnie te linie, które je spełniają. Kod PHP jest najpierw pisany funkcjami z tabeli 1 arkusza (proceduralne mysqli), tak jak każe arkusz - a na końcu całość zostaje przerobiona na wersję z prawdziwych projektów: zapytanie przygotowane dla parametru z adresu (dziś obiekty.php?id=... jest furtką do SQL injection), escapowanie danych i wspólny blok boczny w jednym pliku zamiast w dwóch kopiach.
To jest wersja podstawowa. Obok są jeszcze dwie zgodne z kluczem: „Nowoczesny kod (grid, PDO)” - układ na siatce CSS i PHP na PDO z zapytaniami przygotowanymi od pierwszej linii, oraz „Wspólne pliki (include, mysqli)” - kod rozłożony na pliki jak w prawdziwym projekcie.
Baza i zdjęcia pochodzą z prawdziwego archiwum pliki1 (załącznik do arkusza, hasło w treści zadania). Zrzuty wyników zapytań są odtworzone z tej bazy - na egzaminie robisz je sam, z całego ekranu. Podgląd strony obiekty.php pokazuje obiekt z ilustracji 3 (Godafoss, obiekty.php?id=53).
Jak liczą się punkty. Klucz ma 37 kryteriów (R.1.1 - R.5.7), każde za 1 punkt. Próg zdania części praktycznej to 75%, czyli 28 punktów - można stracić 9 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 37 kryteriów (pkt)
Krok 1: Baza danych islandia
Kryteria:
R.1.1 Wykonany import tabel do bazy danych islandia - plik import w formacie JPEG
ok. 3 min
Polecenie z arkusza
Utwórz bazę danych o nazwie islandia, z zestawem znaków utf8_unicode_ci.
Najpierw rozpakuj archiwum pliki1.7z z pulpitu (hasło isLandi@ z treści zadania) - są w nim baza1.sql i dziewięć zdjęć. W phpMyAdmin (http://localhost/phpmyadmin) klikasz Nowa, wpisujesz islandia i z listy metod porównywania wybierasz utf8_unicode_ci. To ogólne porównywanie Unicode: sortuje polskie („siedlisko zwierząt”, „gorące źródło”) i islandzkie litery („Fuglaskoðunarhús”) według zasad Unicode, a przy porównaniach nie rozróżnia wielkości liter. Dziedziczą je jednak tylko tabele zakładane później bez własnego ustawienia - tabele z baza1.sql mają w definicji utf8_polish_ci i to ono działa w zapytaniach.
Typowe błędy
Nazwa bazy musi być dokładnie islandia - skrypty łączą się z bazą po nazwie (R.5.1).
Krok 2: Import tabel z pliku baza1.sql
Kryteria:
R.1.1 Wykonany import tabel do bazy danych islandia - plik import w formacie JPEG
ok. 2 min
Polecenie z arkusza
Do utworzonej bazy zaimportuj tabele z pliku baza1.sql.
Wejdź do bazy islandia (zaznaczona w lewym panelu), karta Import, Wybierz plik → baza1.sql, Wykonaj. Plik tworzy pięć tabel, ale arkusz każe korzystać tylko z trzech z ilustracji 1: kontynenty, rodzaje (9 rodzajów obiektów: wodospad, szczyt, siedlisko zwierząt...) i obiekty (25 obiektów; każdy ma klucz obcy idRodzaj wskazujący jego rodzaj i kolumnę panstwo). Uwaga na wielkość liter w nazwach kolumn: idObiekt, idRodzaj, nazwaCechy, wartoscCechy.
Krok 3: Zrzut ekranu import.jpg
Kryteria:
R.1.1 Wykonany import tabel do bazy danych islandia - plik import w formacie JPEG
ok. 2 min
Polecenie z arkusza
Wykonaj zrzut ekranu po imporcie. Zapisz zrzut w formacie JPEG pod nazwą 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.
Print Screen (cały ekran), wklejasz do edytora grafiki i zapisujesz jako import.jpg - w tym arkuszu zrzut importu jest w JPEG, a zrzuty zapytań w PNG. Na zrzucie ma być komunikat o udanym imporcie albo lista tabel bazy.
Typowe błędy
Zły format (import.png) albo wykadrowany zrzut to strata punktu R.1.1 - klucz nie ocenia wykadrowanych zrzutów.
Krok 4: Zapytanie 1: obiekty z Islandii
Kryteria: ,
R.1.2 W pliku kwerendy.txt zapisane co najmniej jedno zapytanie SQL, wynikające z treści zadania
R.1.3 Wykonane zapytanie 1 wybierające jedynie pola idObiekt, plik i nazwa z tabeli obiekty dla Islandii. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT idObiekt, plik, nazwa FROM obiekty WHERE panstwo = "Islandia"; oraz na zrzucie widocznych jest dokładnie 9 rekordów o identyfikatorach 46 ÷ 54
ok. 2 min
Polecenie z arkusza
Zapytanie 1: wybierające jedynie pola idObiekt, plik i nazwa z tabeli obiekty dla Islandii.
Karta SQL przy zaznaczonej bazie. SELECT idObiekt, plik, nazwa - trzy kolumny w kolejności z arkusza, FROM obiekty, a „dla Islandii” to warunek na kolumnie panstwo: WHERE panstwo = "Islandia". Wynik: dokładnie 9 wierszy o identyfikatorach 46-54 - jak w kluczu. Zapytanie kopiujesz do kwerendy.txt, zrzut zapisujesz jako kw1.png. To zapytanie wyśle skrypt 3, budując galerię.
kwerendy.txtTekstnowy plik
-- Zapytanie 1SELECT idObiekt, plik, nazwa FROM obiekty WHERE panstwo = "Islandia";
Podgląd strony po tym kroku
Krok 5: Zapytanie 2: dane obiektu 46 z rodzajem
Kryteria:
R.1.4 Wykonane zapytanie 2 wybierające jedynie pola plik, nazwa, nazwaCechy, wartoscCechy, opis z tabeli obiekty oraz odpowiadające im pole rodzaj z tabeli rodzaje dla obiektu o identyfikatorze 46. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT plik, nazwa, nazwaCechy, wartoscCechy, opis, rodzaj FROM obiekty JOIN rodzaje USING(idRodzaj) WHERE idObiekt = 46; (lub INNER JOIN lub porównanie kluczy po ON lub WHERE ) oraz na zrzucie widoczny jest dokładnie 1 rekord dla nazwy Strokkur
ok. 3 min
Polecenie z arkusza
Zapytanie 2: wybierające jedynie pola plik, nazwa, nazwaCechy, wartoscCechy, opis z tabeli obiekty oraz odpowiadające im pole rodzaj z tabeli rodzaje dla obiektu o identyfikatorze 46. Należy posłużyć się relacją.
Pole rodzaj jest w innej tabeli, więc łączysz tabele relacją:
SELECT plik, nazwa, nazwaCechy, wartoscCechy, opis, rodzaj - sześć kolumn, pięć z obiekty i jedna z rodzaje.
FROM obiekty JOIN rodzaje ON obiekty.idRodzaj = rodzaje.idRodzaj - do obiektu dokładasz wiersz jego rodzaju. Kolumna idRodzaj jest w obu tabelach, więc poprzedzasz ją nazwą tabeli (krócej: USING(idRodzaj)).
WHERE idObiekt = 46 - jeden obiekt.
Wynik: dokładnie 1 wiersz, gejzer Strokkur - jak w kluczu. Zrzut: kw2.png. To zapytanie wyśle skrypt 4, podstawiając w miejsce 46 identyfikator z adresu strony.
Typowe błędy
WHERE idRodzaj = ... bez nazwy tabeli w warunku złączenia to błąd „column is ambiguous” - kolumna idRodzaj jest w obu tabelach.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT idObiekt, plik, nazwa FROM obiekty WHERE panstwo = "Islandia";-- Zapytanie 2SELECT plik, nazwa, nazwaCechy, wartoscCechy, opis, rodzaj FROM obiekty JOIN rodzaje ON obiekty.idRodzaj = rodzaje.idRodzaj WHERE idObiekt = 46;
Podgląd strony po tym kroku
Krok 6: Zapytanie 3: wodospady Islandii
Kryteria:
R.1.5 Wykonane zapytanie 3 wybierające jedynie nazwy obiektów z Islandii, których identyfikator rodzaju to 10. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT nazwa FROM obiekty WHERE idRodzaj = 10 AND Panstwo = "Islandia"; oraz na zrzucie widoczne są dokładnie 4 rekordy: Skogafoss, Seljalandsfoss, Godafoss, Dettifoss
ok. 2 min
Polecenie z arkusza
Zapytanie 3: wybierające jedynie nazwy obiektów z Islandii, których identyfikator rodzaju to 10.
Dwa warunki naraz, więc AND: państwo to Islandia i rodzaj ma identyfikator 10 (w tabeli rodzaje to wodospad). Złączenia nie trzeba - identyfikator rodzaju jest w samej tabeli obiekty. Wynik: 4 wiersze - Skogafoss, Seljalandsfoss, Godafoss, Dettifoss, jak w kluczu. Zrzut: kw3.png. To zapytanie wyśle skrypt 1 do listy „Wodospady:”.
Typowe błędy
OR zamiast AND zwróci wszystko z Islandii plus wszystkie wodospady świata (w bazie jest ich 12).
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT idObiekt, plik, nazwa FROM obiekty WHERE panstwo = "Islandia";-- Zapytanie 2SELECT plik, nazwa, nazwaCechy, wartoscCechy, opis, rodzaj FROM obiekty JOIN rodzaje ON obiekty.idRodzaj = rodzaje.idRodzaj WHERE idObiekt = 46;-- Zapytanie 3SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 10;
Podgląd strony po tym kroku
Krok 7: Zapytanie 4: liczba obiektów każdego rodzaju
Kryteria:
R.1.6 Wykonane zapytanie 4 wybierające jedynie rodzaj z tabeli rodzaje oraz zliczające liczbę obiektów danego rodzaju. Kolumna z liczbą obiektów powinna mieć nadaną nazwę (alias) „Liczba obiektów”. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT rodzaj, COUNT(obiekty.idObiekt) AS "Liczba obiektów" FROM Rodzaje JOIN obiekty USING(idRodzaj) GROUP BY rodzaj; (Po COUNT dowolna nazwa pola tabeli obiekty, AS opcjonalnie, lub porównanie kluczy po ON lub WHERE ) oraz na zrzucie widocznych jest dokładnie 8 rekordów: gorące źródło 1, jaskinia 2, jezioro 1, park narodowy 1, siedlisko zwierząt 2, szczyt 4, wodospad 12, wulkan 2
ok. 3 min
Polecenie z arkusza
Zapytanie 4: wybierające jedynie rodzaj z tabeli rodzaje oraz zliczające liczbę obiektów (wodospadów, szczytów itd.) danego rodzaju. Kolumna z liczbą obiektów powinna mieć nadaną nazwę (alias) „Liczba obiektów”. Należy posłużyć się grupowaniem i relacją.
FROM rodzaje JOIN obiekty ON ... - relacja: każdy obiekt dostaje swój rodzaj.
GROUP BY rodzaj - wiersze z tym samym rodzajem zlewają się w jeden.
COUNT(idObiekt) - w każdej grupie liczy obiekty. AS "Liczba obiektów" nadaje kolumnie alias; ma spację i polską literę, więc musi być w cudzysłowie.
Zlicz obiekty z całej bazy, nie tylko z Islandii (arkusz nie podaje warunku). Wynik: 8 wierszy - gorące źródło 1, jaskinia 2, jezioro 1, park narodowy 1, siedlisko zwierząt 2, szczyt 4, wodospad 12, wulkan 2 - dokładnie jak w kluczu. Rodzaj bez żadnego obiektu nie pojawia się, bo JOIN pomija wiersze bez pary. Zrzut: kw4.png - plik kwerendy.txt ma komplet czterech zapytań.
Typowe błędy
Alias bez cudzysłowu (AS Liczba obiektów) to błąd składni - spacja kończy alias. Bez GROUP BYCOUNT zliczy wszystkie 25 obiektów w jednym wierszu.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT idObiekt, plik, nazwa FROM obiekty WHERE panstwo = "Islandia";-- Zapytanie 2SELECT plik, nazwa, nazwaCechy, wartoscCechy, opis, rodzaj FROM obiekty JOIN rodzaje ON obiekty.idRodzaj = rodzaje.idRodzaj WHERE idObiekt = 46;-- Zapytanie 3SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 10;-- Zapytanie 4SELECT rodzaj, COUNT(idObiekt) AS "Liczba obiektów" FROM rodzaje JOIN obiekty ON rodzaje.idRodzaj = obiekty.idRodzaj GROUP BY rodzaj;
Podgląd strony po tym kroku
Etap 2: Strona HTML
Kroki 8-20 · po tym etapie masz 16 z 37 kryteriów (pkt)
Krok 8: Plik islandia.php w HTML5
Kryteria:
R.2.1 W pliku islandia.php lub obiekty.php znajduje się deklaracja HTML5 <!DOCTYPE HTML> i deklaracja języka zawartości: polski np. <html lang="pl">
ok. 2 min
Polecenie z arkusza
Witryna składa się z podstron: islandia.php i obiekty.php. Cechy wspólne obu stron: Zapisane w języku HTML5.
Najpierw skopiuj dziewięć zdjęć z rozpakowanego archiwum do folderu zdającego - skrypty będą je wskazywać samą nazwą pliku z bazy (kolumna plik). Arkusz nie wymaga ich obróbki.
W edytorze tworzysz islandia.php. Obie strony mają wspólny nagłówek, blok boczny i stopkę - budujesz więc najpierw całą islandia.php, a potem obiekty.php powstanie z jej kopii. <!DOCTYPE html> deklaruje HTML5, dalej szkielet <html>, <head>, <body>.
R.2.2 W sekcji head znajduje się jawnie podany standard kodowania polskich znaków i tytuł strony "Islandia”
ok. 1 min
Polecenie z arkusza
Jawnie zastosowany właściwy standard kodowania polskich znaków.
<meta charset="UTF-8"> jako pierwszy element <head>. W bazie są nie tylko polskie litery, ale też islandzkie: obiekt „Fuglaskoðunarhús” ma literę ð - UTF-8 obejmuje wszystkie alfabety, więc wyświetli się poprawnie.
R.2.3 W sekcji body zdefiniowany jest podział na bloki za pomocą semantycznych znaczników HTML5: header, aside, main -> section, footer (dopuszcza się stosowanie bloków pomocniczych)
ok. 2 min
Polecenie z arkusza
Podział strony na bloki: nagłówkowy, boczny, główny, stopki. Blok główny zawiera blok sekcji. Podział zrealizowany za pomocą semantycznych znaczników języka HTML5 tak, aby po uruchomieniu w przeglądarce układ bloków był zgodny z ilustracją 4.
Tabela 4 arkusza podsuwa nazwy: <header>, <aside> (treść obok głównej - blok boczny), <main> z <section> w środku, <footer>. Klucz R.2.3 wymienia dokładnie ten zestaw.
Kolejność w kodzie ma znaczenie dla układu z ilustracji 4: blok boczny stoi po prawej na wysokość nagłówka i bloku głównego razem. Dlatego <aside> piszesz zaraz po <header> - przy układzie opływanym (float) blok, który ma zacząć się przy górnej krawędzi strony, musi pojawić się w kodzie przed blokiem głównym.
Krok 14: Nagłówek pierwszego stopnia będący odnośnikiem
Kryteria: ,
R.2.4 W bloku nagłówkowym znajduje się <h1>: "Zwiedzaj Islandię", w bloku bocznym <h3>: "Do zwiedzania" w bloku głównym <h2>: "Galeria" lub "Opis miejsca" oraz <p> z numerem zdającego w stopce
R.3.3 Przynajmniej na jednej stronie kliknięcie odnośnika z bloku nagłówkowego prowadzi do strony islandia.php
ok. 1 min
Polecenie z arkusza
Zawartość bloku nagłówkowego: Nagłówek pierwszego stopnia o treści „Zwiedzaj Islandię”. Treść jest odnośnikiem do strony islandia.php.
Odnośnik jest wewnątrz nagłówka: <h1><a href="islandia.php">...</a></h1> - nagłówek zostaje nagłówkiem, a jego treść da się kliknąć. Na stronie obiekty.php ten sam nagłówek zaprowadzi z powrotem do galerii (klucz R.3.3).
R.2.4 W bloku nagłówkowym znajduje się <h1>: "Zwiedzaj Islandię", w bloku bocznym <h3>: "Do zwiedzania" w bloku głównym <h2>: "Galeria" lub "Opis miejsca" oraz <p> z numerem zdającego w stopce
ok. 1 min
Polecenie z arkusza
Zawartość bloku bocznego: Nagłówek trzeciego stopnia o treści „Do zwiedzania”.
<h3> - trzeciego stopnia, choć na stronie nie ma jeszcze <h2> (pojawi się w bloku głównym). Arkusz decyduje o stopniu nagłówka, nie kolejność na stronie.
R.2.5 W bloku bocznym znajduje się jedna lista punktowana z dwoma elementami „Wodospady:” i „Siedliska zwierząt:” (znaczniki <ul>, <li> )
ok. 1 min
Polecenie z arkusza
Lista punktowana (nieuporządkowana) z dwoma elementami: „Wodospady:” i „Siedliska zwierząt:”.
Punktowana = <ul>, dwa elementy <li>. Znacznik zamykający </li> piszesz w osobnej linii, bo za chwilę w środku każdego elementu zagnieździsz drugą listę.
R.2.6 Przynajmniej jeden element listy zawiera zagnieżdżoną jedną listę numerowaną (w skrypcie lub HTML, znaczniki <ol> i <li>, znacznik <ol> zawarto wewnątrz <li> listy z R.2.5)
ok. 2 min
Polecenie z arkusza
Element „Wodospady:” zawiera listę numerowaną (uporządkowaną) wypełnioną skryptem 1. Element „Siedliska zwierząt:” zawiera listę numerowaną (uporządkowaną) wypełnioną skryptem 2.
Lista zagnieżdżona to cała lista wewnątrz elementu <li> - <ol> stoi między tekstem „Wodospady:” a </li>. Numerowana = <ol>. Na razie listy są puste; elementy <li> dopiszą skrypty 1 i 2 (klucz R.2.6 przyjmuje <ol> w HTML albo w skrypcie).
Typowe błędy
<ol> między </li> a kolejnym <li> (zamiast wewnątrz elementu) to niepoprawny HTML - lista nie jest wtedy zagnieżdżona w elemencie, a klucz R.2.6 wymaga <ol> wewnątrz <li>.
Krok 18: Blok główny: nagłówek „Galeria” i blok sekcji
Kryteria:
R.2.4 W bloku nagłówkowym znajduje się <h1>: "Zwiedzaj Islandię", w bloku bocznym <h3>: "Do zwiedzania" w bloku głównym <h2>: "Galeria" lub "Opis miejsca" oraz <p> z numerem zdającego w stopce
ok. 1 min
Polecenie z arkusza
Zawartość bloku głównego dla strony islandia.php: Nagłówek drugiego stopnia o treści: „Galeria”. Blok sekcji z efektem wykonania skryptu 3.
<h2> przed <section> - sekcja jest na galerię, którą wypisze skrypt 3. Nagłówek stoi poza ramką sekcji, jak na ilustracji 2.
R.2.4 W bloku nagłówkowym znajduje się <h1>: "Zwiedzaj Islandię", w bloku bocznym <h3>: "Do zwiedzania" w bloku głównym <h2>: "Galeria" lub "Opis miejsca" oraz <p> z numerem zdającego w stopce
R.2.9 Stopka zawiera linię poziomą (<hr> lub za pomocą obramowania w CSS )
ok. 1 min
Polecenie z arkusza
Zawartość bloku stopki: Linia pozioma. Paragraf o treści „Autor: ”, dalej wstawiony numer zdającego.
<hr> to linia pozioma (element pusty - bez znacznika zamykającego i bez ukośnika w HTML5), pod nią paragraf. W tym rozwiązaniu po „Autor:” stoi nazwisko autora - na egzaminie wpisujesz swój numer zdającego (PESEL).
R.2.8 Na stronie obiekty.php w bloku głównym lub bloku sekcji znajdują się elementy <h2>, <h3> i przynajmniej jeden <p> (w skrypcie lub HTML )
ok. 2 min
Polecenie z arkusza
Zawartość bloku głównego dla strony obiekty.php: Nagłówek drugiego stopnia o treści: „Opis miejsca”. Blok sekcji z efektem działania skryptu 4.
Wszystkie cechy wspólne są już w islandia.php, więc zapisujesz ją jako obiekty.php (Zapisz jako) i zmieniasz jedną linię: nagłówek bloku głównego to „Opis miejsca”. Sekcję wypełni skrypt 4, a nagłówek strony, blok boczny i stopka zostają takie same - obie strony wyglądają jak jedna witryna.
Kroki 21-30 · po tym etapie masz 27 z 37 kryteriów (pkt)
Krok 21: Plik styl.css: krój czcionki
Kryteria:
R.4.1 domyślne formatowanie selektorów (*): krój czcionki "Comic Sans MS" - jako pierwszy, sans-serif - jako ostatni
ok. 1 min
Polecenie z arkusza
Domyślnie, dla wszystkich selektorów: krój czcionki Comic Sans MS, w przypadku braku sans-serif.
Utwórz styl.css. Selektor * obejmuje każdy element. Nazwa kroju ma spacje, więc bierzesz ją w cudzysłów: "Comic Sans MS"; po przecinku rodzina zastępcza sans-serif - przeglądarka użyje dowolnego kroju bezszeryfowego, gdy Comic Sans nie ma w systemie (klucz R.4.1: Comic Sans pierwszy, sans-serif ostatni).
styl.cssCSSnowy plik
* {font-family: "Comic Sans MS", sans-serif;}
Podgląd strony po tym kroku (islandia.php)
Krok 22: Nagłówek i blok główny: szerokość i wyśrodkowanie
Kryteria: ,
R.4.3 szerokość: blok nagłówkowy, główny - 70%, boczny - 25% (width lub grid-template- columns lub flex ) wysokość: blok nagłówkowy - 100px, boczny - 700px, sekcja - 400px
R.4.5 wyrównanie tekstu: blok nagłówkowy, główny - do środka
ok. 1 min
Polecenie z arkusza
Dla bloku nagłówkowego i głównego: szerokość 70%, wyrównanie tekstu do środka.
Wspólne cechy dwóch bloków piszesz raz: selektory po przecinku (header, main) dostają tę samą regułę. Procent liczy się od szerokości okna, więc układ dopasuje się do ekranu.
styl.cssCSSzmienione: 4 linie
* {font-family: "Comic Sans MS", sans-serif;}header, main {width: 70%;text-align: center;}
Podgląd strony po tym kroku (islandia.php)
Krok 23: Nagłówek i blok boczny: tło i zaokrąglenie
Kryteria: ,
R.4.2 kolor tła: blok nagłówkowy i boczny - PaleTurquoise
R.4.7 zaokrąglenie rogów (border-radius) : blok nagłówkowy, boczny - 20px
ok. 1 min
Polecenie z arkusza
Dla bloku nagłówkowego i bocznego: kolor tła PaleTurquoise, zaokrąglenie rogów 20 px.
background-color przyjmuje nazwę koloru z arkusza wprost (PaleTurquoise, wielkość liter bez znaczenia), a border-radius: 20px zaokrągla wszystkie cztery rogi.
styl.cssCSSzmienione: 4 linie
* {font-family: "Comic Sans MS", sans-serif;}header, main {width: 70%;text-align: center;}header, aside {background-color: PaleTurquoise;border-radius: 20px;}
Podgląd strony po tym kroku (islandia.php)
Krok 24: Nagłówek: wysokość i marginesy wewnętrzne
Kryteria: ,
R.4.3 szerokość: blok nagłówkowy, główny - 70%, boczny - 25% (width lub grid-template- columns lub flex ) wysokość: blok nagłówkowy - 100px, boczny - 700px, sekcja - 400px
R.4.4 marginesy wewnętrzne (padding ): blok nagłówkowy - 2%, stopka jedynie padding-top: 10px; marginesy zewnętrzne (margin ): sekcja - górny i dolny - 10px, pozostałe - 50px
ok. 1 min
Polecenie z arkusza
Dodatkowo dla bloku nagłówkowego: wysokość 100 px, marginesy wewnętrzne 2%.
„Dodatkowo” - druga reguła dla header, uzupełniająca tę wspólną. Margines wewnętrzny to padding; procent liczy się od szerokości rodzica, także w pionie.
styl.cssCSSzmienione: 4 linie
* {font-family: "Comic Sans MS", sans-serif;}header, main {width: 70%;text-align: center;}header, aside {background-color: PaleTurquoise;border-radius: 20px;}header {height: 100px;padding: 2%;}
Podgląd strony po tym kroku (islandia.php)
Krok 25: Blok boczny: wymiary i interlinia
Kryteria: ,
R.4.3 szerokość: blok nagłówkowy, główny - 70%, boczny - 25% (width lub grid-template- columns lub flex ) wysokość: blok nagłówkowy - 100px, boczny - 700px, sekcja - 400px
R.4.8 wysokość linii (line-hight) : blok boczny - 2
ok. 1 min
Polecenie z arkusza
Dodatkowo dla bloku bocznego: szerokość 25%, wysokość 700 px, wysokość linii (interlinia) 2.
line-height: 2 bez jednostki to dwukrotność rozmiaru czcionki - podwójna interlinia, dzięki której lista w bloku bocznym jest luźna, jak na ilustracji 2.
R.4.3 szerokość: blok nagłówkowy, główny - 70%, boczny - 25% (width lub grid-template- columns lub flex ) wysokość: blok nagłówkowy - 100px, boczny - 700px, sekcja - 400px
R.4.4 marginesy wewnętrzne (padding ): blok nagłówkowy - 2%, stopka jedynie padding-top: 10px; marginesy zewnętrzne (margin ): sekcja - górny i dolny - 10px, pozostałe - 50px
R.4.6 cechy sekcji: obramowanie 1px dashed DimGray, paski przewijania (overflow) auto
ok. 2 min
Polecenie z arkusza
Dla bloku sekcji: obramowanie linią kreskową o szerokości 1 px i kolorze DimGray, marginesy zewnętrzne górny i dolny 10 px, pozostałe 50 px, wysokość 400 px, paski przewijania pojawiające się tylko w przypadku przepełnienia bloku.
border: 1px dashed DimGray - grubość, styl linii (kreskowa to dashed, kropkowa byłaby dotted) i kolor w jednej właściwości.
margin: 10px 50px - dwie wartości: pierwsza dla góry i dołu, druga dla lewej i prawej.
overflow: auto - paski przewijania tylko gdy treść się nie mieści (scroll pokazywałby je zawsze). Galeria ma 9 zdjęć po 200 px wysokości, więc w sekcji 400 px pojawi się pasek, jak na ilustracji 2.
Krok 28: Klasa miniatury: wysokość, przezroczystość, tranzycja
Kryteria:
R.4.9 styl klasy .miniatury : wysokość - 200px, padding: 10px, przezroczystość (opacity) - 0.8, tranzycja trwająca 1s (transition lub transition-duration)
ok. 2 min
Polecenie z arkusza
Dla klasy miniatury przypisanej do obrazów ze strony islandia.php, generowanych skryptem 3: wysokość 200 px, marginesy wewnętrzne 10 px, przezroczystość 0.8, dodana tranzycja trwająca 1 sekundę.
Selektor klasy zaczyna się kropką: .miniatury. Podaj tylko wysokość - szerokość dopasuje się do proporcji zdjęcia. opacity: 0.8 to 80% krycia. transition: 1s (tabela 3 arkusza: wystarczy sam czas trwania) sprawia, że zmiana przezroczystości po najechaniu kursorem nie przeskoczy, tylko płynnie potrwa sekundę. Klasy nie ma jeszcze w HTML - przypisze ją skrypt 3 (klucz pozwala sprawdzić taką regułę w kodzie CSS).
R.4.10 gdy kursor znajdzie się na elemencie z przypisaną klasą .miniatury , jego przezroczystość (opacity) zmienia się na wartość 1
ok. 1 min
Polecenie z arkusza
W przypadku gdy kursor znajdzie się na elemencie z przypisaną klasą miniatury, jego przezroczystość zmienia się na wartość 1.
Pseudoklasa :hover - stan „kursor nad elementem”. Ustaw tylko to, co się zmienia: opacity: 1. Tranzycja z poprzedniej reguły zadziała w obie strony - przy najechaniu i przy zjechaniu kursorem.
R.3.1 Układ bloków po uruchomieniu strony w przeglądarce jest zgodny z ilustracją 4 w arkuszu egzaminacyjnym (prawidłowo zastosowane właściwości CSS decydujące o układzie bloków na stronie, np. float i clear albo display flex albo grid albo position; żaden blok nie zachodzi na inne bloki - sprawdzić w inspektorze)
ok. 3 min
Polecenie z arkusza
Podział zrealizowany za pomocą semantycznych znaczników języka HTML5 tak, aby po uruchomieniu w przeglądarce układ bloków był zgodny z ilustracją 4.
Arkusz nie podaje właściwości układu - wybierasz float, bo trzy linie wystarczą:
header, main { float: left; } - nagłówek staje przy lewej krawędzi, blok główny też, a ponieważ obok nagłówka nie ma już miejsca, ląduje pod nim.
aside { float: right; } - blok boczny przy prawej krawędzi, od samej góry (stąd jego miejsce w kodzie przed <main>).
footer { clear: both; } - stopka nie opływa żadnego bloku, tylko schodzi pod najniższy z nich (blok boczny ma 700 px).
Szerokości się mieszczą: nagłówek ma 70% plus 2 × 2% marginesu wewnętrznego, czyli 74%, do tego 25% bloku bocznego - razem 99%. Układ odpowiada ilustracji 4 (klucz R.3.1).
Typowe błędy
Bez clear: both stopka wsunie się pod pływające bloki, a linia pozioma przetnie stronę na wysokości nagłówka.
Kroki 31-46 · po tym etapie masz 37 z 37 kryteriów (pkt)
Krok 31: Połączenie z bazą na obu stronach
Kryteria: ,
R.5.1 Skrypt realizuje połączenie z serwerem bazy danych i wybór bazy islandia oraz ostatnią operacją na bazie jest jej zamknięcie (wystarczy na jednej stronie )
R.5.2 Zastosowana przynajmniej jedna zmienna oraz nazewnictwo jest w języku polskim lub angielskim i odzwierciedla cel zastosowania
ok. 3 min
Polecenie z arkusza
Wymagania dotyczące skryptów: Napisane w języku PHP. Łączą się z serwerem bazodanowym na localhost, użytkownik root bez hasła, baza danych o nazwie islandia.
Kod PHP stoi między <?php a ?> i wykonuje się na serwerze, zanim strona trafi do przeglądarki. Połączenie otwierasz raz, zaraz po <body>, i trzymasz w zmiennej $connection - korzystają z niego wszystkie skrypty strony. mysqli_connect z tabeli 1 przyjmuje kolejno: serwer, użytkownika, hasło (puste) i nazwę bazy. Ten sam blok wstawiasz w obu plikach - każda strona to osobne żądanie do serwera i potrzebuje własnego połączenia.
Od tego kroku podgląd to wynik działania strony po stronie serwera.
Typowe błędy
mysqli_connect('localhost', 'root', 'islandia') podaje „islandia” jako HASŁO - nazwa bazy jest czwartym argumentem. Stronę otwierasz przez http://localhost/…, nie z dysku.
R.5.3 Skrypty zawierają przynajmniej jedną instrukcję wysyłającą zapytanie do bazy danych: skrypt 2 zmodyfikowane zapytanie 3 - idRodzaj = 14 skrypt 1 zapytanie 3 skrypt 3 - zapytanie 1 skrypt 4 - zmodyfikowane zapytanie 2 - id pobrane z tablicy $_GET
ok. 2 min
Polecenie z arkusza
Skrypt 1 na obu stronach: Wysyła do bazy danych zapytanie 3.
Skrypt 1 piszesz wewnątrz<ol> przy „Wodospady:” - tam ma trafić jego wynik. mysqli_query($connection, ...) wysyła zapytanie i zwraca wynik, który zapisujesz w zmiennej $waterfalls (wodospady). Treść to zapytanie 3 z kwerendy.txt. Zapytanie zawiera cudzysłowy, więc cały napis w PHP bierzesz w apostrofy.
R.5.4 Skrypt 1 lub skrypt 2 wyświetla wszystkie zwrócone zapytaniem nazwy jako elementy listy
ok. 2 min
Polecenie z arkusza
Każda zwrócona zapytaniem nazwa jest wyświetlana jako element listy.
Pętla while z mysqli_fetch_row($waterfalls) (tabela 1) bierze kolejne wiersze jako tablice liczone od zera; gdy wierszy zabraknie, funkcja zwraca false i pętla się kończy. Zapytanie wybiera jedną kolumnę, więc nazwa to $row[0], a echo wypisuje ją w <li>. W podglądzie lista numerowana wypełnia się czterema wodospadami (klucz R.5.4).
R.5.3 Skrypty zawierają przynajmniej jedną instrukcję wysyłającą zapytanie do bazy danych: skrypt 2 zmodyfikowane zapytanie 3 - idRodzaj = 14 skrypt 1 zapytanie 3 skrypt 3 - zapytanie 1 skrypt 4 - zmodyfikowane zapytanie 2 - id pobrane z tablicy $_GET
R.5.4 Skrypt 1 lub skrypt 2 wyświetla wszystkie zwrócone zapytaniem nazwy jako elementy listy
ok. 2 min
Polecenie z arkusza
Skrypt 2 na obu stronach: Wysyła do bazy danych zapytanie 3, zmodyfikowane tak, że w warunku sprawdzane jest pole idRodzaj równe 14. Każda zwrócona zapytaniem nazwa jest wyświetlana jako element listy.
Skopiuj skrypt 1 do drugiej <ol> i zmień dwie rzeczy: w zapytaniu idRodzaj = 14 (siedlisko zwierząt) i nazwę zmiennej na $habitats - nazwa ma mówić, co jest w środku. Wynik: dwa siedliska, w tym „Fuglaskoðunarhús” z islandzką literą ð.
islandia.phpPHPzmienione: 6 linii
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Islandia</title> <linkrel="stylesheet"href="styl.css"></head><body><?php$connection = mysqli_connect('localhost', 'root', '', 'islandia');?> <header> <h1><ahref="islandia.php">Zwiedzaj Islandię</a></h1> </header> <aside> <h3>Do zwiedzania</h3> <ul> <li>Wodospady: <ol><?php$waterfalls = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 10;');while ($row = mysqli_fetch_row($waterfalls)) {echo"<li>$row[0]</li>";}?> </ol> </li> <li>Siedliska zwierząt: <ol><?php$habitats = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 14;');while ($row = mysqli_fetch_row($habitats)) {echo"<li>$row[0]</li>";}?> </ol> </li> </ul> </aside> <main> <h2>Galeria</h2> <section> </section> </main> <footer> <hr> <p>Autor: Bartosz Bryniarski</p> </footer></body></html>
Podgląd strony po tym kroku (islandia.php)
Krok 35: Skrypty 1 i 2 również na stronie obiekty.php
Kryteria:
R.5.4 Skrypt 1 lub skrypt 2 wyświetla wszystkie zwrócone zapytaniem nazwy jako elementy listy
ok. 2 min
Polecenie z arkusza
Skrypt 1 na obu stronach. Skrypt 2 na obu stronach.
„Na obu stronach” - kopiujesz oba skrypty w te same miejsca w obiekty.php. Blok boczny wygląda teraz identycznie na obu stronach. (W etapie „Dobre praktyki” wyniesiesz go do jednego pliku, żeby nie trzymać dwóch kopii.)
obiekty.phpPHPzmienione: 12 linii
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Islandia</title> <linkrel="stylesheet"href="styl.css"></head><body><?php$connection = mysqli_connect('localhost', 'root', '', 'islandia');?> <header> <h1><ahref="islandia.php">Zwiedzaj Islandię</a></h1> </header> <aside> <h3>Do zwiedzania</h3> <ul> <li>Wodospady: <ol><?php$waterfalls = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 10;');while ($row = mysqli_fetch_row($waterfalls)) {echo"<li>$row[0]</li>";}?> </ol> </li> <li>Siedliska zwierząt: <ol><?php$habitats = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 14;');while ($row = mysqli_fetch_row($habitats)) {echo"<li>$row[0]</li>";}?> </ol> </li> </ul> </aside> <main> <h2>Opis miejsca</h2> <section> </section> </main> <footer> <hr> <p>Autor: Bartosz Bryniarski</p> </footer></body></html>
Podgląd strony po tym kroku (obiekty.php)
Krok 36: Skrypt 3: zapytanie 1 do bazy
Kryteria:
R.5.3 Skrypty zawierają przynajmniej jedną instrukcję wysyłającą zapytanie do bazy danych: skrypt 2 zmodyfikowane zapytanie 3 - idRodzaj = 14 skrypt 1 zapytanie 3 skrypt 3 - zapytanie 1 skrypt 4 - zmodyfikowane zapytanie 2 - id pobrane z tablicy $_GET
ok. 1 min
Polecenie z arkusza
Skrypt 3 na stronie islandia.php: Wysyła do bazy danych zapytanie 1.
Wróć do islandia.php. Skrypt 3 stoi w <section> bloku głównego. Zapytanie 1 zwraca identyfikator, plik i nazwę dziewięciu obiektów - wynik zapisujesz w $objects.
islandia.phpPHPzmienione: 3 linie
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Islandia</title> <linkrel="stylesheet"href="styl.css"></head><body><?php$connection = mysqli_connect('localhost', 'root', '', 'islandia');?> <header> <h1><ahref="islandia.php">Zwiedzaj Islandię</a></h1> </header> <aside> <h3>Do zwiedzania</h3> <ul> <li>Wodospady: <ol><?php$waterfalls = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 10;');while ($row = mysqli_fetch_row($waterfalls)) {echo"<li>$row[0]</li>";}?> </ol> </li> <li>Siedliska zwierząt: <ol><?php$habitats = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 14;');while ($row = mysqli_fetch_row($habitats)) {echo"<li>$row[0]</li>";}?> </ol> </li> </ul> </aside> <main> <h2>Galeria</h2> <section><?php$objects = mysqli_query($connection, 'SELECT idObiekt, plik, nazwa FROM obiekty WHERE panstwo = "Islandia";');?> </section> </main> <footer> <hr> <p>Autor: Bartosz Bryniarski</p> </footer></body></html>
Podgląd strony po tym kroku (islandia.php)
Krok 37: Skrypt 3: obraz z każdego wiersza
Kryteria: ,
R.5.6 Skrypt 3 dla każdego zwróconego zapytaniem wiersza wyświetla obraz, którego źródłem jest zwrócone pole plik
R.2.7 W bloku głównym lub bloku sekcji znajduje się przynajmniej jeden obraz wraz z tekstem alternatywnym (w skrypcie lub HTML )
ok. 3 min
Polecenie z arkusza
Odnośnik jest obrazem, dla którego źródło to zwrócone pole plik, tekst alternatywny to zwrócone pole nazwa.
Dla każdego wiersza <img>: źródło $row[1] (pole plik, np. Strokkur.jpg - zdjęcia leżą obok strony), tekst alternatywny $row[2] (pole nazwa). W napisie w cudzysłowie atrybuty HTML też potrzebują cudzysłowów - poprzedzasz je ukośnikiem \", żeby nie zakończyły napisu PHP. Galeria pokazuje zdjęcia w naturalnym rozmiarze - zmniejszy je klasa z CSS.
Typowe błędy
echo "<img src="$row[1]">"; bez ukośników kończy napis na drugim cudzysłowie - PHP zgłosi błąd składni i cała strona przestanie działać.
islandia.phpPHPzmienione: 3 linie
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Islandia</title> <linkrel="stylesheet"href="styl.css"></head><body><?php$connection = mysqli_connect('localhost', 'root', '', 'islandia');?> <header> <h1><ahref="islandia.php">Zwiedzaj Islandię</a></h1> </header> <aside> <h3>Do zwiedzania</h3> <ul> <li>Wodospady: <ol><?php$waterfalls = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 10;');while ($row = mysqli_fetch_row($waterfalls)) {echo"<li>$row[0]</li>";}?> </ol> </li> <li>Siedliska zwierząt: <ol><?php$habitats = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 14;');while ($row = mysqli_fetch_row($habitats)) {echo"<li>$row[0]</li>";}?> </ol> </li> </ul> </aside> <main> <h2>Galeria</h2> <section><?php$objects = mysqli_query($connection, 'SELECT idObiekt, plik, nazwa FROM obiekty WHERE panstwo = "Islandia";');while ($row = mysqli_fetch_row($objects)) {echo"<img src=\"$row[1]\" alt=\"$row[2]\">";}?> </section> </main> <footer> <hr> <p>Autor: Bartosz Bryniarski</p> </footer></body></html>
Podgląd strony po tym kroku (islandia.php)
Krok 38: Skrypt 3: dymek z nazwą i klasa miniatury
Kryteria:
R.3.5 Przynajmniej jeden obraz ze strony islandia.php ma przypisaną klasę miniatury oraz atrybut title
ok. 2 min
Polecenie z arkusza
Dodatkowo pole nazwa jest tekstem pojawiającym się w postaci dymka, gdy kursor znajdzie się na obrazie (ilustracja 2, czwarty obraz). Obraz ma przypisaną klasę miniatury.
Dymek po najechaniu kursorem to atrybut title - ta sama nazwa co w alt. class="miniatury" podpina regułę z styl.css: zdjęcia mają po 200 px wysokości, lekko prześwitują, a po najechaniu kursorem płynnie nabierają pełnego koloru. Najedź na zdjęcie w podglądzie (klucz R.3.5).
islandia.phpPHPzmienione: 1 linia
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Islandia</title> <linkrel="stylesheet"href="styl.css"></head><body><?php$connection = mysqli_connect('localhost', 'root', '', 'islandia');?> <header> <h1><ahref="islandia.php">Zwiedzaj Islandię</a></h1> </header> <aside> <h3>Do zwiedzania</h3> <ul> <li>Wodospady: <ol><?php$waterfalls = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 10;');while ($row = mysqli_fetch_row($waterfalls)) {echo"<li>$row[0]</li>";}?> </ol> </li> <li>Siedliska zwierząt: <ol><?php$habitats = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 14;');while ($row = mysqli_fetch_row($habitats)) {echo"<li>$row[0]</li>";}?> </ol> </li> </ul> </aside> <main> <h2>Galeria</h2> <section><?php$objects = mysqli_query($connection, 'SELECT idObiekt, plik, nazwa FROM obiekty WHERE panstwo = "Islandia";');while ($row = mysqli_fetch_row($objects)) {echo"<img src=\"$row[1]\" alt=\"$row[2]\" title=\"$row[2]\" class=\"miniatury\">";}?> </section> </main> <footer> <hr> <p>Autor: Bartosz Bryniarski</p> </footer></body></html>
Podgląd strony po tym kroku (islandia.php)
Krok 39: Skrypt 3: odnośnik z parametrem GET
Kryteria: ,
R.3.4 Na stronie islandia.php umieszczono przynajmniej jeden odnośnik, którego kliknięcie powoduje otwarcie strony obiekty.php oraz zostaje wysłane żądanie metodą GET z jednym parametrem
R.5.5 Skrypt 3 dla każdego zwróconego zapytaniem wiersza wstawia idObiekt jako wartość parametru przesłanego metodą GET
ok. 3 min
Polecenie z arkusza
Dla każdego zwróconego zapytaniem wiersza wypisuje odnośnik prowadzący do strony obiekty.php oraz przekazujący do tej strony metodą GET parametr o wartości równej polu idObiekt.
Obraz otaczasz odnośnikiem <a href="obiekty.php?id=...">. Parametr GET to część adresu po znaku zapytania (tabela 2 arkusza): id=46 dla Strokkura, id=53 dla Godafossu - wartość to $row[0], czyli pole idObiekt. Nazwę parametru (id) wybierasz sam; ważne, by skrypt 4 odczytał ją pod tą samą nazwą (klucz R.3.4, R.5.5). W podglądzie kliknięcia są zablokowane - po kliknięciu na egzaminie przeglądarka otworzy np. obiekty.php?id=53.
islandia.phpPHPzmienione: 1 linia
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Islandia</title> <linkrel="stylesheet"href="styl.css"></head><body><?php$connection = mysqli_connect('localhost', 'root', '', 'islandia');?> <header> <h1><ahref="islandia.php">Zwiedzaj Islandię</a></h1> </header> <aside> <h3>Do zwiedzania</h3> <ul> <li>Wodospady: <ol><?php$waterfalls = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 10;');while ($row = mysqli_fetch_row($waterfalls)) {echo"<li>$row[0]</li>";}?> </ol> </li> <li>Siedliska zwierząt: <ol><?php$habitats = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 14;');while ($row = mysqli_fetch_row($habitats)) {echo"<li>$row[0]</li>";}?> </ol> </li> </ul> </aside> <main> <h2>Galeria</h2> <section><?php$objects = mysqli_query($connection, 'SELECT idObiekt, plik, nazwa FROM obiekty WHERE panstwo = "Islandia";');while ($row = mysqli_fetch_row($objects)) {echo"<a href=\"obiekty.php?id=$row[0]\"><img src=\"$row[1]\" alt=\"$row[2]\" title=\"$row[2]\" class=\"miniatury\"></a>";}?> </section> </main> <footer> <hr> <p>Autor: Bartosz Bryniarski</p> </footer></body></html>
Podgląd strony po tym kroku (islandia.php)
Krok 40: Zamknięcie połączenia na stronie islandia.php
Kryteria:
R.5.1 Skrypt realizuje połączenie z serwerem bazy danych i wybór bazy islandia oraz ostatnią operacją na bazie jest jej zamknięcie (wystarczy na jednej stronie )
ok. 1 min
Polecenie z arkusza
Na końcu należy zamknąć połączenie z bazą.
mysqli_close($connection) po stopce, jako ostatnia operacja na bazie - po wszystkich trzech skryptach strony (klucz R.5.1). Strona islandia.php jest gotowa.
Typowe błędy
Zamknięcie przed skryptem 3 (np. zaraz po bloku bocznym) zostawi galerię pustą - zapytanie pójdzie po zamkniętym połączeniu.
islandia.phpPHPzmienione: 3 linie
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Islandia</title> <linkrel="stylesheet"href="styl.css"></head><body><?php$connection = mysqli_connect('localhost', 'root', '', 'islandia');?> <header> <h1><ahref="islandia.php">Zwiedzaj Islandię</a></h1> </header> <aside> <h3>Do zwiedzania</h3> <ul> <li>Wodospady: <ol><?php$waterfalls = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 10;');while ($row = mysqli_fetch_row($waterfalls)) {echo"<li>$row[0]</li>";}?> </ol> </li> <li>Siedliska zwierząt: <ol><?php$habitats = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 14;');while ($row = mysqli_fetch_row($habitats)) {echo"<li>$row[0]</li>";}?> </ol> </li> </ul> </aside> <main> <h2>Galeria</h2> <section><?php$objects = mysqli_query($connection, 'SELECT idObiekt, plik, nazwa FROM obiekty WHERE panstwo = "Islandia";');while ($row = mysqli_fetch_row($objects)) {echo"<a href=\"obiekty.php?id=$row[0]\"><img src=\"$row[1]\" alt=\"$row[2]\" title=\"$row[2]\" class=\"miniatury\"></a>";}?> </section> </main> <footer> <hr> <p>Autor: Bartosz Bryniarski</p> </footer><?phpmysqli_close($connection);?></body></html>
Krok 41: Skrypt 4: parametr z adresu w zapytaniu 2
Kryteria:
R.5.3 Skrypty zawierają przynajmniej jedną instrukcję wysyłającą zapytanie do bazy danych: skrypt 2 zmodyfikowane zapytanie 3 - idRodzaj = 14 skrypt 1 zapytanie 3 skrypt 3 - zapytanie 1 skrypt 4 - zmodyfikowane zapytanie 2 - id pobrane z tablicy $_GET
ok. 3 min
Polecenie z arkusza
Skrypt 4 na stronie obiekty.php: Wysyła do bazy danych zapytanie 2, zmodyfikowane w ten sposób, że w warunku jest sprawdzane id obiektu przesłane jako parametr metody GET ze strony islandia.php.
Parametry z adresu PHP trzyma w tablicy $_GET (tabela 2): $_GET['id'] to wartość z obiekty.php?id=53. Zapisz ją w $id i wstaw w miejsce 46 z zapytania 2. Zapytanie bierzesz tym razem w cudzysłów, bo w cudzysłowie PHP podstawia wartości zmiennych (... WHERE idObiekt = $id), a jedyny tekst w środku zapytania nie ma już cudzysłowów. Zapytanie zwraca jeden wiersz, więc zamiast pętli wystarczy jedno mysqli_fetch_row.
⚠️ Tak zrobiona podstawa jest niebezpieczna: każdy może dopisać do adresu dowolny fragment SQL - poprawisz to w etapie „Dobre praktyki”. Na egzaminie wystarcza i spełnia R.5.3.
Typowe błędy
Stronę obiekty.php sprawdzaj, klikając zdjęcie w galerii. Otwarta wprost, bez ?id= w adresie, kończy się ostrzeżeniem „Undefined array key "id"” i błędem składni SQL (zapytanie kończy się na idObiekt =) - obsługę braku parametru dodaje etap „Dobre praktyki”.
obiekty.phpPHPzmienione: 5 linii
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Islandia</title> <linkrel="stylesheet"href="styl.css"></head><body><?php$connection = mysqli_connect('localhost', 'root', '', 'islandia');?> <header> <h1><ahref="islandia.php">Zwiedzaj Islandię</a></h1> </header> <aside> <h3>Do zwiedzania</h3> <ul> <li>Wodospady: <ol><?php$waterfalls = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 10;');while ($row = mysqli_fetch_row($waterfalls)) {echo"<li>$row[0]</li>";}?> </ol> </li> <li>Siedliska zwierząt: <ol><?php$habitats = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 14;');while ($row = mysqli_fetch_row($habitats)) {echo"<li>$row[0]</li>";}?> </ol> </li> </ul> </aside> <main> <h2>Opis miejsca</h2> <section><?php$id = $_GET['id'];$details = mysqli_query($connection, "SELECT plik, nazwa, nazwaCechy, wartoscCechy, opis, rodzaj FROM obiekty JOIN rodzaje ON obiekty.idRodzaj = rodzaje.idRodzaj WHERE idObiekt = $id;");$row = mysqli_fetch_row($details);?> </section> </main> <footer> <hr> <p>Autor: Bartosz Bryniarski</p> </footer></body></html>
Podgląd strony po tym kroku (obiekty.php)
Krok 42: Skrypt 4: obraz obiektu
Kryteria:
R.5.7 Skrypt 4 wyświetla obraz oraz dane których id zostało przesłane metodą GET
ok. 1 min
Polecenie z arkusza
Na podstawie zwróconych zapytaniem danych: Wyświetla obraz, którego źródłem jest pole plik, a tekstem alternatywnym pole nazwa.
Kolejność kolumn z zapytania 2: plik (0), nazwa (1), nazwaCechy (2), wartoscCechy (3), opis (4), rodzaj (5). Obraz: źródło $row[0], tekst alternatywny $row[1]. W podglądzie: Godafoss, czyli obiekty.php?id=53 - obiekt z ilustracji 3.
obiekty.phpPHPzmienione: 1 linia
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Islandia</title> <linkrel="stylesheet"href="styl.css"></head><body><?php$connection = mysqli_connect('localhost', 'root', '', 'islandia');?> <header> <h1><ahref="islandia.php">Zwiedzaj Islandię</a></h1> </header> <aside> <h3>Do zwiedzania</h3> <ul> <li>Wodospady: <ol><?php$waterfalls = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 10;');while ($row = mysqli_fetch_row($waterfalls)) {echo"<li>$row[0]</li>";}?> </ol> </li> <li>Siedliska zwierząt: <ol><?php$habitats = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 14;');while ($row = mysqli_fetch_row($habitats)) {echo"<li>$row[0]</li>";}?> </ol> </li> </ul> </aside> <main> <h2>Opis miejsca</h2> <section><?php$id = $_GET['id'];$details = mysqli_query($connection, "SELECT plik, nazwa, nazwaCechy, wartoscCechy, opis, rodzaj FROM obiekty JOIN rodzaje ON obiekty.idRodzaj = rodzaje.idRodzaj WHERE idObiekt = $id;");$row = mysqli_fetch_row($details);echo"<img src=\"$row[0]\" alt=\"$row[1]\">";?> </section> </main> <footer> <hr> <p>Autor: Bartosz Bryniarski</p> </footer></body></html>
Podgląd strony po tym kroku (obiekty.php)
Krok 43: Skrypt 4: nazwa w nagłówku drugiego stopnia
Kryteria:
R.2.8 Na stronie obiekty.php w bloku głównym lub bloku sekcji znajdują się elementy <h2>, <h3> i przynajmniej jeden <p> (w skrypcie lub HTML )
ok. 1 min
Polecenie z arkusza
W nagłówku drugiego stopnia wyświetla wartość pola nazwa.
<h2> z $row[1]. Na stronie są teraz dwa nagłówki drugiego stopnia: „Opis miejsca” bloku głównego i nazwa obiektu w sekcji - tak pokazuje ilustracja 3.
obiekty.phpPHPzmienione: 1 linia
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Islandia</title> <linkrel="stylesheet"href="styl.css"></head><body><?php$connection = mysqli_connect('localhost', 'root', '', 'islandia');?> <header> <h1><ahref="islandia.php">Zwiedzaj Islandię</a></h1> </header> <aside> <h3>Do zwiedzania</h3> <ul> <li>Wodospady: <ol><?php$waterfalls = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 10;');while ($row = mysqli_fetch_row($waterfalls)) {echo"<li>$row[0]</li>";}?> </ol> </li> <li>Siedliska zwierząt: <ol><?php$habitats = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 14;');while ($row = mysqli_fetch_row($habitats)) {echo"<li>$row[0]</li>";}?> </ol> </li> </ul> </aside> <main> <h2>Opis miejsca</h2> <section><?php$id = $_GET['id'];$details = mysqli_query($connection, "SELECT plik, nazwa, nazwaCechy, wartoscCechy, opis, rodzaj FROM obiekty JOIN rodzaje ON obiekty.idRodzaj = rodzaje.idRodzaj WHERE idObiekt = $id;");$row = mysqli_fetch_row($details);echo"<img src=\"$row[0]\" alt=\"$row[1]\">";echo"<h2>$row[1]</h2>";?> </section> </main> <footer> <hr> <p>Autor: Bartosz Bryniarski</p> </footer></body></html>
Podgląd strony po tym kroku (obiekty.php)
Krok 44: Skrypt 4: rodzaj w nagłówku trzeciego stopnia
Kryteria:
R.2.8 Na stronie obiekty.php w bloku głównym lub bloku sekcji znajdują się elementy <h2>, <h3> i przynajmniej jeden <p> (w skrypcie lub HTML )
ok. 1 min
Polecenie z arkusza
W nagłówku trzeciego stopnia wyświetla wartość pola rodzaj.
<h3> z $row[5] - pole rodzaj pochodzi z tabeli rodzaje, dołączonej relacją w zapytaniu 2.
obiekty.phpPHPzmienione: 1 linia
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Islandia</title> <linkrel="stylesheet"href="styl.css"></head><body><?php$connection = mysqli_connect('localhost', 'root', '', 'islandia');?> <header> <h1><ahref="islandia.php">Zwiedzaj Islandię</a></h1> </header> <aside> <h3>Do zwiedzania</h3> <ul> <li>Wodospady: <ol><?php$waterfalls = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 10;');while ($row = mysqli_fetch_row($waterfalls)) {echo"<li>$row[0]</li>";}?> </ol> </li> <li>Siedliska zwierząt: <ol><?php$habitats = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 14;');while ($row = mysqli_fetch_row($habitats)) {echo"<li>$row[0]</li>";}?> </ol> </li> </ul> </aside> <main> <h2>Opis miejsca</h2> <section><?php$id = $_GET['id'];$details = mysqli_query($connection, "SELECT plik, nazwa, nazwaCechy, wartoscCechy, opis, rodzaj FROM obiekty JOIN rodzaje ON obiekty.idRodzaj = rodzaje.idRodzaj WHERE idObiekt = $id;");$row = mysqli_fetch_row($details);echo"<img src=\"$row[0]\" alt=\"$row[1]\">";echo"<h2>$row[1]</h2>";echo"<h3>$row[5]</h3>";?> </section> </main> <footer> <hr> <p>Autor: Bartosz Bryniarski</p> </footer></body></html>
Podgląd strony po tym kroku (obiekty.php)
Krok 45: Skrypt 4: cecha i jej wartość w paragrafie
Kryteria:
R.2.8 Na stronie obiekty.php w bloku głównym lub bloku sekcji znajdują się elementy <h2>, <h3> i przynajmniej jeden <p> (w skrypcie lub HTML )
ok. 1 min
Polecenie z arkusza
W paragrafie wyświetla tekst „<nazwaCechy>: <wartoscCechy>”, gdzie w <> umieszczono wartości zwrócone zapytaniem.
Dwie kolumny w jednym napisie, oddzielone dwukropkiem i spacją: "<p>$row[2]: $row[3]</p>". Dla Godafossu: „wysokość: 30”.
obiekty.phpPHPzmienione: 1 linia
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Islandia</title> <linkrel="stylesheet"href="styl.css"></head><body><?php$connection = mysqli_connect('localhost', 'root', '', 'islandia');?> <header> <h1><ahref="islandia.php">Zwiedzaj Islandię</a></h1> </header> <aside> <h3>Do zwiedzania</h3> <ul> <li>Wodospady: <ol><?php$waterfalls = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 10;');while ($row = mysqli_fetch_row($waterfalls)) {echo"<li>$row[0]</li>";}?> </ol> </li> <li>Siedliska zwierząt: <ol><?php$habitats = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 14;');while ($row = mysqli_fetch_row($habitats)) {echo"<li>$row[0]</li>";}?> </ol> </li> </ul> </aside> <main> <h2>Opis miejsca</h2> <section><?php$id = $_GET['id'];$details = mysqli_query($connection, "SELECT plik, nazwa, nazwaCechy, wartoscCechy, opis, rodzaj FROM obiekty JOIN rodzaje ON obiekty.idRodzaj = rodzaje.idRodzaj WHERE idObiekt = $id;");$row = mysqli_fetch_row($details);echo"<img src=\"$row[0]\" alt=\"$row[1]\">";echo"<h2>$row[1]</h2>";echo"<h3>$row[5]</h3>";echo"<p>$row[2]: $row[3]</p>";?> </section> </main> <footer> <hr> <p>Autor: Bartosz Bryniarski</p> </footer></body></html>
Podgląd strony po tym kroku (obiekty.php)
Krok 46: Skrypt 4: opis i zamknięcie połączenia
Kryteria: ,
R.5.7 Skrypt 4 wyświetla obraz oraz dane których id zostało przesłane metodą GET
R.5.1 Skrypt realizuje połączenie z serwerem bazy danych i wybór bazy islandia oraz ostatnią operacją na bazie jest jej zamknięcie (wystarczy na jednej stronie )
ok. 2 min
Polecenie z arkusza
W paragrafie wyświetla pole opis. Na końcu należy zamknąć połączenie z bazą.
Ostatni paragraf to $row[4] - opis miejsca. Długi opis razem ze zdjęciem nie mieści się w sekcji o wysokości 400 px, więc pojawia się pasek przewijania (ilustracja 3, „przewinięto suwak”). Na końcu pliku, po stopce, zamykasz połączenie - jak w islandia.php. Obie strony spełniają wszystkie kryteria arkusza (klucz R.5.7).
obiekty.phpPHPzmienione: 4 linie
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Islandia</title> <linkrel="stylesheet"href="styl.css"></head><body><?php$connection = mysqli_connect('localhost', 'root', '', 'islandia');?> <header> <h1><ahref="islandia.php">Zwiedzaj Islandię</a></h1> </header> <aside> <h3>Do zwiedzania</h3> <ul> <li>Wodospady: <ol><?php$waterfalls = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 10;');while ($row = mysqli_fetch_row($waterfalls)) {echo"<li>$row[0]</li>";}?> </ol> </li> <li>Siedliska zwierząt: <ol><?php$habitats = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 14;');while ($row = mysqli_fetch_row($habitats)) {echo"<li>$row[0]</li>";}?> </ol> </li> </ul> </aside> <main> <h2>Opis miejsca</h2> <section><?php$id = $_GET['id'];$details = mysqli_query($connection, "SELECT plik, nazwa, nazwaCechy, wartoscCechy, opis, rodzaj FROM obiekty JOIN rodzaje ON obiekty.idRodzaj = rodzaje.idRodzaj WHERE idObiekt = $id;");$row = mysqli_fetch_row($details);echo"<img src=\"$row[0]\" alt=\"$row[1]\">";echo"<h2>$row[1]</h2>";echo"<h3>$row[5]</h3>";echo"<p>$row[2]: $row[3]</p>";echo"<p>$row[4]</p>";?> </section> </main> <footer> <hr> <p>Autor: Bartosz Bryniarski</p> </footer><?phpmysqli_close($connection);?></body></html>
Podgląd strony po tym kroku (obiekty.php)
Etap 5: Dobre praktyki (poza kluczem)
Kroki 47-49 · po tym etapie masz 37 z 37 kryteriów (pkt)
Krok 47: obiekty.php: zapytanie przygotowane zamiast wklejania $_GET do SQL
ok. 5 min
Polecenie z arkusza
Skrypt 4 na stronie obiekty.php: Wysyła do bazy danych zapytanie 2, zmodyfikowane w ten sposób, że w warunku jest sprawdzane id obiektu przesłane jako parametr metody GET ze strony islandia.php.
Wersja z egzaminu wkleja tekst z adresu wprost do zapytania. Adres obiekty.php?id=0 OR 1=1 zmienia sens warunku - to SQL injection, najczęstsza dziura w stronach z bazą danych. Napraw to dwiema warstwami:
(int) $_GET['id'] zamienia parametr na liczbę całkowitą (tekst daje 0), a isset obsługuje wejście bez parametru zamiast ostrzeżenia PHP,
zapytanie przygotowane: mysqli_prepare z ? w miejscu wartości, mysqli_stmt_bind_param z typem 'i' (integer) - baza dostaje SQL i wartość osobno, więc wartość nigdy nie stanie się kodem.
Gdy obiektu nie ma ($row to null), strona mówi to wprost zamiast wypisywać puste znaczniki. Stare linie zostają w komentarzu. Na egzaminie wystarczy wersja wcześniejsza - klucz tego nie sprawdza.
obiekty.phpPHPzmienione: 17 linii
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Islandia</title> <linkrel="stylesheet"href="styl.css"></head><body><?php$connection = mysqli_connect('localhost', 'root', '', 'islandia');?> <header> <h1><ahref="islandia.php">Zwiedzaj Islandię</a></h1> </header> <aside> <h3>Do zwiedzania</h3> <ul> <li>Wodospady: <ol><?php$waterfalls = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 10;');while ($row = mysqli_fetch_row($waterfalls)) {echo"<li>$row[0]</li>";}?> </ol> </li> <li>Siedliska zwierząt: <ol><?php$habitats = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 14;');while ($row = mysqli_fetch_row($habitats)) {echo"<li>$row[0]</li>";}?> </ol> </li> </ul> </aside> <main> <h2>Opis miejsca</h2> <section><?php$id = isset($_GET['id']) ? (int) $_GET['id'] : 0;$statement = mysqli_prepare($connection, 'SELECT plik, nazwa, nazwaCechy, wartoscCechy, opis, rodzaj FROM obiekty JOIN rodzaje ON obiekty.idRodzaj = rodzaje.idRodzaj WHERE idObiekt = ?');mysqli_stmt_bind_param($statement, 'i', $id);mysqli_stmt_execute($statement);$row = mysqli_fetch_row(mysqli_stmt_get_result($statement));// $id = $_GET['id'];// $details = mysqli_query($connection, "SELECT plik, nazwa, nazwaCechy, wartoscCechy, opis, rodzaj FROM obiekty JOIN rodzaje ON obiekty.idRodzaj = rodzaje.idRodzaj WHERE idObiekt = $id;");// $row = mysqli_fetch_row($details);if ($row) {echo"<img src=\"$row[0]\" alt=\"$row[1]\">";echo"<h2>$row[1]</h2>";echo"<h3>$row[5]</h3>";echo"<p>$row[2]: $row[3]</p>";echo"<p>$row[4]</p>";} else {echo'<p>Nie znaleziono takiego miejsca - wybierz zdjęcie w galerii.</p>';}?> </section> </main> <footer> <hr> <p>Autor: Bartosz Bryniarski</p> </footer><?phpmysqli_close($connection);?></body></html>
Krok 48: islandia.php: escapowanie nazw w atrybutach
ok. 3 min
Polecenie z arkusza
Odnośnik jest obrazem, dla którego źródło to zwrócone pole plik, tekst alternatywny to zwrócone pole nazwa.
Nazwa obiektu trafia do atrybutów alt i title. Gdyby w bazie była nazwa z cudzysłowem (np. Wodospad "Złoty"), zamknęłaby atrybut i rozbiła znacznik - a nazwa z <script> wykonałaby się u każdego, kto otworzy galerię (XSS). htmlspecialchars() zamienia ", <, > i & na encje, więc tekst zawsze zostaje tekstem. Escapujesz przy wypisywaniu, nie przy zapisie do bazy. Podgląd bez zmian.
Na egzaminie wystarczy wersja wcześniejsza - klucz tego nie sprawdza.
islandia.phpPHPzmienione: 2 linie
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Islandia</title> <linkrel="stylesheet"href="styl.css"></head><body><?php$connection = mysqli_connect('localhost', 'root', '', 'islandia');?> <header> <h1><ahref="islandia.php">Zwiedzaj Islandię</a></h1> </header> <aside> <h3>Do zwiedzania</h3> <ul> <li>Wodospady: <ol><?php$waterfalls = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 10;');while ($row = mysqli_fetch_row($waterfalls)) {echo"<li>$row[0]</li>";}?> </ol> </li> <li>Siedliska zwierząt: <ol><?php$habitats = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 14;');while ($row = mysqli_fetch_row($habitats)) {echo"<li>$row[0]</li>";}?> </ol> </li> </ul> </aside> <main> <h2>Galeria</h2> <section><?php$objects = mysqli_query($connection, 'SELECT idObiekt, plik, nazwa FROM obiekty WHERE panstwo = "Islandia";');while ($row = mysqli_fetch_row($objects)) {$name = htmlspecialchars($row[2]);echo"<a href=\"obiekty.php?id=$row[0]\"><img src=\"$row[1]\" alt=\"$name\" title=\"$name\" class=\"miniatury\"></a>";}?> </section> </main> <footer> <hr> <p>Autor: Bartosz Bryniarski</p> </footer><?phpmysqli_close($connection);?></body></html>
Podgląd strony po tym kroku (islandia.php)
Krok 49: Wspólny blok boczny w pliku boczny.php
ok. 4 min
Polecenie z arkusza
Skrypt 1 na obu stronach. Skrypt 2 na obu stronach.
Blok boczny ze skryptami 1 i 2 stoi w dwóch plikach, znak w znak. Poprawka w jednej kopii łatwo omija drugą. Przenieś go do boczny.php i w obu stronach w jego miejscu napisz <?php include 'boczny.php'; ?> - PHP wkleja zawartość pliku przy każdym wyświetleniu. Dołączony plik widzi zmienne strony, więc korzysta z jej $connection. Tak samo w prawdziwych witrynach powstają wspólne nagłówki, menu i stopki. Wygląd stron się nie zmienia.
Na egzaminie wystarczy wersja wcześniejsza - klucz sprawdza skrypty 1 i 2 na stronie i oba wymagania spełniają.
boczny.phpPHPnowy plik
<aside> <h3>Do zwiedzania</h3> <ul> <li>Wodospady: <ol><?php$waterfalls = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 10;');while ($row = mysqli_fetch_row($waterfalls)) {echo"<li>$row[0]</li>";}?> </ol> </li> <li>Siedliska zwierząt: <ol><?php$habitats = mysqli_query($connection, 'SELECT nazwa FROM obiekty WHERE panstwo = "Islandia" AND idRodzaj = 14;');while ($row = mysqli_fetch_row($habitats)) {echo"<li>$row[0]</li>";}?> </ol> </li> </ul> </aside>
Krok 50 · po tym etapie masz 37 z 37 kryteriów (pkt)
Krok 50: Plik przeglądarka.txt i nagranie płyty
ok. 5 min
Polecenie z arkusza
Po zakończeniu pracy utwórz plik tekstowy o nazwie przeglądarka.txt. Zapisz w nim nazwę przeglądarki internetowej, w której weryfikowana była poprawność działania witryny. Umieść go w folderze z numerem zdającego. Nagraj płytę z rezultatami pracy. W folderze z numerem zdającego, powinno znajdować się 9 plików z grafiką do strony oraz pliki: import.jpg, islandia.php, kw1.png, kw2.png, kw3.png, kw4.png, kwerendy.txt, obiekty.php, przeglądarka.txt, styl.css, ewentualnie inne przygotowane pliki.
W przeglądarka.txt wpisujesz nazwę przeglądarki, w której sprawdzasz strony przez http://localhost/….
Sprawdź folder: dziewięć zdjęć z archiwum, import.jpg, islandia.php, obiekty.php, kw1.png - kw4.png, kwerendy.txt, przeglądarka.txt, styl.css (oraz boczny.php, jeśli powstał w refaktorze). Nagraj płytę, sprawdź jej odczyt i opisz numerem zdającego.
Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.
To jedno z możliwych rozwiązań. Egzaminator ocenia spełnienie kryteriów z klucza odpowiedzi, a nie zgodność z tym kodem - inna, poprawna droga też daje punkty.
Autor rozwiązania: Bartosz Bryniarski. Licencja CC BY-NC 4.0 - kopiowanie i przeróbki do celów niekomercyjnych, z podaniem autora i źródła (link do tej strony) (zasady wykorzystania). Treść arkusza i klucza oceniania pochodzi z CKE.