Przejdź do głównej treści
INF.03-07-24.06-SGCzerwiec 2024 · 49 kroków · ok. 85 min · 37 kryteriów z klucza

Rozwiązanie krok po kroku: Witryna ważenia pojazdów (Wersja podstawowa)

Testowa aplikacja miejskiego ważenia pojazdów: baza wazenietirow (lokalizacje wag i pomiary nacisku na oś) i cztery operacje - UPDATE z aktualną datą i czasem, prosty wybór ulic, INSERT z losową wagą (FLOOR i RAND) oraz złączenie JOIN z warunkiem „powyżej 5 t” - potem dwie grafiki (cyfra na znaku drogowym i odbite zdjęcie ciężarówki) i strona wazenie.php: dwa banery obok siebie, trzy bloki i stopka, a w nich trzy skrypty PHP: lista ulic, tabela alertów i testowy pomiar dopisywany przy każdym odświeżeniu strony co 10 sekund.

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ą. Skrypty powstają najpierw najprościej, funkcjami z tabeli 1 arkusza (mysqli_query, mysqli_fetch_row), a na końcu przechodzą do wersji z prawdziwych projektów: nagłówek odświeżania na początku pliku (sprawdzone: w wersji egzaminacyjnej odświeżanie po pewnym czasie przestaje działać) oraz mysqli_fetch_assoc z htmlspecialchars.

To jest wersja podstawowa. W zakładce „Nowoczesny kod (grid, PDO)” jest drugi sposób rozwiązania tego samego arkusza: bloki na siatce CSS, kolory w zmiennych i PHP na PDO z danymi pobranymi przed HTML-em, z nagłówkiem odświeżania przed treścią strony - obie wersje są zgodne z kluczem.

Baza i grafiki pochodzą z prawdziwego archiwum pliki7 (załącznik do arkusza, hasło w treści zadania). Zrzuty wyników zapytań są odtworzone z tej bazy - na egzaminie robi się je samemu, z całego ekranu. Podgląd strony od kroków z PHP to wynik prawdziwego uruchomienia kodu z danego kroku w PHP 8.2 na bazie z arkusza po zapytaniu 1 (dlatego część pomiarów ma datę i godzinę wykonania zapytania 1 - tu 2026-10-04, 11:17:40 - tak jak na obrazie 2 część ma godzinę 10:41:36).

Jak liczą się punkty. Klucz ma 37 kryteriów (R.1.1 - R.5.8), 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.

  1. Etap 1: Baza danych

    Kroki 1-7 · po tym etapie masz 6 z 37 kryteriów (pkt)

    Krok 1: Baza danych wazenietirow

    ok. 2 min
    Polecenie z arkusza

    Utwórz bazę danych o nazwie wazenietirow, z zestawem polskich znaków (np. utf8_unicode_ci)

    Najpierw archiwum pliki7.zip z pulpitu (hasło %WAg@Poj@zdoW - procent na początku, dwie małpy zamiast „a”) rozpakowuje się do folderu nazwanego numerem zdającego. W phpMyAdmin: Nowa, nazwa wazenietirow (jedno słowo, bez polskich liter), porównywanie utf8_unicode_ci.

    Typowe błędy

    Nazwa bazy musi brzmieć dokładnie wazenietirow - skrypty łączą się z bazą po nazwie (R.5.1).

  2. Krok 2: Import tabel z pliku baza.sql

    ok. 2 min
    Polecenie z arkusza

    Do bazy zaimportuj tabele z pliku baza.sql z rozpakowanego archiwum

    Zaznaczona baza wazenietirow, potem Import → baza.sql → Wykonaj. Powstają dwie tabele z obrazu 1: lokalizacje (6 ulic, na których stoją wagi) i wagi (22 pomiary: identyfikator lokalizacji, nacisk na oś w tonach, numer rejestracyjny, dzień i czas). Relacja 1..n: jedna lokalizacja, wiele pomiarów.

  3. Krok 3: Zrzut ekranu import.png

    Kryteria:

    R.1.1 Wykonano import tabel do bazy danych wazenietirow czynność udokumentowano plikiem o nazwie import w formacie PNG

    ok. 2 min
    Polecenie z arkusza

    Wykonaj zrzut ekranu po imporcie. Zrzut zapisz w formacie PNG i nazwij import. Nie kadruj zrzutu. Powinien on obejmować cały ekran monitora, z widocznym paskiem zadań. Na zrzucie powinny być widoczne elementy wskazujące na poprawnie wykonany import tabel.

    Print Screen, wklejenie do edytora grafiki i zapis jako import.png. Zrzuty zapytań idą później do JPEG.

    Typowe błędy

    Wykadrowany zrzut albo zrzut bez paska zadań nie jest oceniany (uwaga w kluczu przy R.1).

  4. Krok 4: Zapytanie 1: aktualna data i czas dla lokalizacji 2-4

    Kryteria: ,

    R.1.2 Zapisano plik kwerendy.txt zawierający co najmniej jedno zapytanie SQL, wynikające z treści zadania

    R.1.3 Wykonano zapytanie 1 aktualizujące tabelę wagi . Rekordy, w których pole lokalizacje_id jest równe 2, 3, 4 mają zmienione datę i czas na wartości aktualne. W pliku z kwerendami lub na zrzucie istnieje zapis np.: UPDATE wagi SET dzien=CURRENT_DATE,czas=CURRENT_TIME WHERE lokalizacje_id BETWEEN 2 AND 4; (dowolne funkcje wstawiające aktualną datę/czas, lub także z pustymi nawiasami; dowolny warunek sprawdzający przedział 2..4) oraz wynik działania udokumentowano zrzutem, na którym jest widoczny komunikat o poprawnie wykonanym zapytaniu lub wiersze z lokalizacje_id równym 2, 3, 4 mają datę i czas zgodny z terminem egzaminu

    ok. 3 min
    Polecenie z arkusza

    Zapytanie 1: aktualizujące tabelę wagi. Rekordy, w których pole lokalizacje_id jest równe: 2, 3, 4 mają zmienione datę i czas na wartości aktualne. Zapytanie ma charakter uniwersalny, zawsze zmienia wartość na aktualną datę / czas

    • UPDATE wagi - zmiana danych w tabeli pomiarów,
    • SET dzien = CURDATE(), czas = CURTIME() - dwie kolumny naraz, rozdzielone przecinkiem; funkcje z tabeli 2 arkusza zwracają bieżącą datę i bieżący czas w chwili wykonania - to jest „charakter uniwersalny”,
    • WHERE lokalizacje_id BETWEEN 2 AND 4 - przedział domknięty: 2, 3 i 4 (klucz uznaje każdy warunek na ten przedział, np. IN (2, 3, 4)).

    Zmienionych rekordów: 13 - wszystkie dostały datę 2026-10-04 i ten sam czas. Zapytania zapisuje się w kwerendy.txt, zrzut z komunikatem albo ze zmienionymi wierszami jako kw1.jpg.

    Typowe błędy

    Data wpisana ręcznie ('2024-06-20') nie jest uniwersalna - jutro zapytanie wstawiłoby wczorajszy dzień. Bez WHERE zmieniłyby się wszystkie 22 pomiary.

    kwerendy.txt Tekst nowy plik
    -- Zapytanie 1
    UPDATE wagi SET dzien = CURDATE(), czas = CURTIME() WHERE lokalizacje_id BETWEEN 2 AND 4;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 4
  5. Krok 5: Zapytanie 2: ulice

    Kryteria:

    R.1.4 Wykonano zapytanie 2 wybierające jedynie ulicę z tabeli lokalizacje . W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT ulica FROM lokalizacje; oraz wynik działania udokumentowano zrzutem, na którym są widoczne jedynie dane: Ślężna, Tyska, Średzka, Wilanowska, Żmigrodzka, Karkonowska

    ok. 1 min
    Polecenie z arkusza

    Zapytanie 2: wybierające jedynie ulicę z tabeli lokalizacje

    • SELECT ulica - jedno pole, bez identyfikatora,
    • FROM lokalizacje.

    Wynik: Ślężna, Tyska, Średzka, Wilanowska, Żmigrodzka, Karkonowska - jak w kluczu. Zrzut: kw2.jpg. To zapytanie wypełni listę w bloku lewym (Skrypt 1).

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    UPDATE wagi SET dzien = CURDATE(), czas = CURTIME() WHERE lokalizacje_id BETWEEN 2 AND 4;
    
    -- Zapytanie 2
    SELECT ulica FROM lokalizacje;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 5
  6. Krok 6: Zapytanie 3: pomiar z losową wagą

    Kryteria:

    R.1.5 Wykonano zapytanie 3 wstawiające rekord do tabeli wagi z danymi: lokalizacje_id: 5, waga: liczba pseudolosowa z przedziału 1..10, rejestracja: DW12345, aktualna data i czas. Klucz główny nadawany automatycznie. W pliku z kwerendami lub na zrzucie istnieje zapis np.: INSERT INTO `wagi`(`lokalizacje_id`, `waga`, `rejestracja`, `dzien`, `czas`) VALUES ('5', FLOOR(1+RAND()*10), 'DW12345', CURRENT_DATE, CURRENT_TIME); (dowolny sposób liczenia liczby pseudolosowej z przedziału 1..10; dowolne funkcje wstawiające aktualny czas/datę, też z pustymi nawiasami) oraz wynik działania udokumentowano zrzutem, na którym jest widoczny komunikat o poprawnie wykonanym zapytaniu lub wstawiony do tabeli wiersz

    ok. 3 min
    Polecenie z arkusza

    Zapytanie 3: wstawiające do tabeli wagi rekord z danymi: lokalizacje_id: 5, waga: losowa liczba z przedziału 1..10 (wygenerowana funkcją), rejestracja: DW12345, aktualna data (do pola dzien) i aktualny czas (do pola czas). Klucz główny nadawany automatycznie. Zapytanie ma charakter uniwersalny, zawsze wstawia wartość aktualnej daty i czasu

    • INSERT INTO wagi (lokalizacje_id, waga, rejestracja, dzien, czas) - pięć kolumn; id pominięte, więc baza nada je sama,
    • FLOOR(1 + RAND() * 10) - wzór z pomocy do RAND w arkuszu: RAND() daje liczbę od 0 do 1 (bez 1), po pomnożeniu przez 10 - od 0 do 9,99..., po dodaniu 1 - od 1 do 10,99..., a FLOOR obcina część ułamkową. Wychodzą liczby całkowite od 1 do 10, każda z tym samym prawdopodobieństwem,
    • 'DW12345', CURDATE(), CURTIME() - numer rejestracyjny jako tekst i bieżąca data oraz czas.

    Wstawiony pomiar dostał identyfikator 23 i wagę 5 - przy każdym wykonaniu będzie inna. Zrzut: kw3.jpg.

    Typowe błędy

    ROUND(RAND() * 10) daje także 0 (i rzadziej 10 niż pozostałe liczby) - przedział z arkusza to 1..10.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    UPDATE wagi SET dzien = CURDATE(), czas = CURTIME() WHERE lokalizacje_id BETWEEN 2 AND 4;
    
    -- Zapytanie 2
    SELECT ulica FROM lokalizacje;
    
    -- Zapytanie 3
    INSERT INTO wagi (lokalizacje_id, waga, rejestracja, dzien, czas) VALUES (5, FLOOR(1 + RAND() * 10), 'DW12345', CURDATE(), CURTIME());
    Podgląd strony po tym kroku
    Podgląd strony po kroku 6
  7. Krok 7: Zapytanie 4: pomiary powyżej 5 t z nazwą ulicy

    Kryteria:

    R.1.6 Wykonano zapytanie 4 wybierające jedynie pola rejestracja, waga, dzien, czas z tabeli wagi i odpowiadające mu pole ulica z tabeli lokalizacje dla pojazdów, których waga na oś przekracza 5 t. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT rejestracja, ulica, waga, dzien, czas FROM wagi JOIN lokalizacje ON wagi.lokalizacje_id = lokalizacje.id WHERE waga > 5; (możliwe również INNER JOIN lub bez JOIN i porównanie kluczy po WHERE) oraz wynik działania udokumentowano zrzutem, na którym widoczne są rekordy z wagą powyżej 5; jedynie pola: rejestracja, waga, dzien, czas, ulica. Liczba wierszy dowolna, w zależności od wykonania zapytań 1 i 3

    ok. 3 min
    Polecenie z arkusza

    Zapytanie 4: wybierające jedynie pola rejestracja, waga, dzien, czas z tabeli wagi i odpowiadające mu pole ulica z tabeli lokalizacje dla pojazdów, których waga na oś przekracza 5 t. Należy posłużyć się relacją

    • SELECT rejestracja, ulica, waga, dzien, czas - kolejność pól jak w tabeli na obrazie 3 (arkusz wymaga jej przy Skrypcie 2), więc to samo zapytanie od razu nadaje się do skryptu,
    • FROM wagi JOIN lokalizacje ON wagi.lokalizacje_id = lokalizacje.id - relacja: do pomiaru dołączana jest jego lokalizacja z nazwą ulicy,
    • WHERE waga > 5 - „przekracza 5 t”, czyli ostro większe; pomiary z wagą równą 5 (DWTKU32, DW54874) się nie łapią.

    Wynik: 9 wierszy - dziewięć pomiarów z obrazu 2 (od DW54U32 do DW54N32) i ewentualnie wstawiony DW12345, jeśli wylosował więcej niż 5 (tutaj wylosował 5). Klucz dopuszcza dowolną liczbę wierszy, bo zależy ona od zapytań 1 i 3. Zrzut: kw4.jpg.

    Typowe błędy

    waga >= 5 dorzuca dwa pomiary z wagą dokładnie 5 t, które limitu nie przekraczają.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    UPDATE wagi SET dzien = CURDATE(), czas = CURTIME() WHERE lokalizacje_id BETWEEN 2 AND 4;
    
    -- Zapytanie 2
    SELECT ulica FROM lokalizacje;
    
    -- Zapytanie 3
    INSERT INTO wagi (lokalizacje_id, waga, rejestracja, dzien, czas) VALUES (5, FLOOR(1 + RAND() * 10), 'DW12345', CURDATE(), CURTIME());
    
    -- Zapytanie 4
    SELECT rejestracja, ulica, waga, dzien, czas FROM wagi JOIN lokalizacje ON wagi.lokalizacje_id = lokalizacje.id WHERE waga > 5;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 7
  8. Etap 2: Grafika i strona HTML

    Kroki 8-25 · po tym etapie masz 16 z 37 kryteriów (pkt)

    Krok 8: obraz1.png: 5T zamiast 8T

    Kryteria:

    R.2.1 Plik obraz1.png zmodyfikowano w ten sposób że przy samochodzie widnieje tonaż 5T. Napis 8T nie jest widoczny

    ok. 4 min
    Polecenie z arkusza

    Plik obraz1.png, wypakowany z archiwum, należy zmodyfikować w ten sposób, że zamiast informacji 8T na przedstawionym znaku powinna być zapisana wartość 5T. Zmodyfikowany obraz jest widoczny na obrazie 2.

    W GIMP-ie: zaznaczenie prostokątne wokół cyfry 8, wypełnienie bielą (Edycja → Wypełnij kolorem tła przy białym tle), potem narzędzie Tekst: cyfra 5 czarna, krój bezszeryfowy o wąskich znakach, rozmiar dobrany tak, by cyfra miała wysokość litery T obok (ok. 21 px). Tutaj użyty jest krój Bahnschrift, wzorowany na kroju DIN ze znaków drogowych. Litera T zostaje bez zmian. Zapis pod tą samą nazwą (Plik → Nadpisz obraz1.png), z przezroczystością wokół znaku. Podgląd pokazuje znak przed i po, powiększony trzy razy.

    Typowe błędy

    Cyfra 5 dopisana obok ósemki albo na niej bez zamalowania - klucz wymaga, żeby napis 8T nie był widoczny.

    Podgląd strony po tym kroku
    Podgląd strony po kroku 8
  9. Krok 9: obraz2.jpg: odbicie i szerokość 350 px

    Kryteria:

    R.2.2 Plik obraz2.jpg odbito wzdłuż osi pionowej oraz przeskalowano z zachowaniem proporcji do szerokości 350 px. Odpowiadająca temu wysokość wynosi 285 px (± 5 px)

    ok. 3 min
    Polecenie z arkusza

    Plik obraz2.jpg odbić wzdłuż osi pionowej oraz przeskalować z zachowaniem proporcji tak, aby jego szerokość wynosiła dokładnie 350 px. Zmodyfikowany obraz jest widoczny na obrazie 2.

    Odbicie „wzdłuż osi pionowej” zamienia lewą stronę z prawą: w GIMP-ie Obraz → Przekształć → Odbij poziomo (nazwa menu mówi o kierunku ruchu pikseli, a arkusz - o osi, wokół której obraz się obraca). Kabina ciężarówki przechodzi z prawej strony na lewą - tak jak na obrazie 2. Potem Obraz → Skaluj obraz z zamkniętym łańcuchem: szerokość 350, wysokość wychodzi 407 · 350 / 500 ≈ 285 px (klucz: 285 px ± 5).

    Typowe błędy

    Odbij pionowo stawia ciężarówkę kołami do góry - obraz 2 pokazuje odbicie lewo-prawo.

    Podgląd strony po tym kroku
    Podgląd strony po kroku 9
  10. Krok 10: Plik wazenie.php w HTML5

    ok. 2 min
    Polecenie z arkusza

    Składa się ze strony o nazwie wazenie.php zapisanej w języku HTML5

    Deklaracja <!DOCTYPE html> i szkielet z sekcjami head i body. Rozszerzenie .php, bo dojdą skrypty; na egzaminie plik leży w htdocs XAMPP-a i otwiera się go przez http://localhost/....

    wazenie.php PHP nowy plik
    <!DOCTYPE html>
    <html>
    <head>
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (wazenie.php)
  11. Krok 11: Język strony

    ok. 1 min
    Polecenie z arkusza

    Ustawiony język zawartości strony na polski

    Atrybut lang="pl" w znaczniku <html>.

    wazenie.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (wazenie.php)
  12. Krok 12: Kodowanie polskich znaków

    Kryteria:

    R.2.3 Witrynę internetową zapisano w pliku wazenie.php oraz zapisano jawnie standard kodowania polskich znaków i deklarację HTML5 <!DOCTYPE HTML> i zadeklarowano język witryny polski np.<HTML lang="pl">. Strona zawiera sekcje head i body

    ok. 1 min
    Polecenie z arkusza

    Jawnie zastosowany właściwy standard kodowania polskich znaków

    <meta charset="UTF-8"> jako pierwszy element <head> - inaczej „Ślężna” i „Żmigrodzka” z bazy mogą wyjść krzakami. Z deklaracją HTML5, językiem i nazwą pliku to jedno kryterium klucza.

    wazenie.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (wazenie.php)
  13. Krok 13: Tytuł strony

    Kryteria:

    R.2.4 Nadano tytuł stronie: Ważenie samochodów ciężarowych

    ok. 1 min
    Polecenie z arkusza

    Tytuł strony widoczny na karcie przeglądarki: „Ważenie samochodów ciężarowych”

    <title> w <head>. Uwaga: tytuł karty mówi o samochodach ciężarowych, a nagłówek strony - o pojazdach; to dwa różne teksty.

    wazenie.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Ważenie samochodów ciężarowych</title>
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (wazenie.php)
  14. Krok 14: Podpięcie arkusza stylów

    Kryteria:

    R.3.3 Strona zawiera działające połączenie z zewnętrznym arkuszem stylów o nazwie styl.css , formatowanie CSS pochodzi jedynie z tego arkusza Uwaga: kryterium to nie jest spełnione również, gdy zdający źle przypisał co najmniej jeden selektor do bloku (np. kropka zamiast #)

    ok. 1 min
    Polecenie z arkusza

    Arkusz stylów w pliku o nazwie styl.css prawidłowo połączony z kodem strony

    Nazwa pliku: styl.css. Całe formatowanie ma pochodzić z tego pliku.

    Typowe błędy

    Klucz odbiera R.3.3 także wtedy, gdy choć jeden selektor nie trafia w blok (np. kropka zamiast #).

    wazenie.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Ważenie samochodów ciężarowych</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (wazenie.php)
  15. Krok 15: Bloki: dwa banery, trzy bloki, stopka

    Kryteria:

    R.2.5 Układ strony zdefiniowano dzieląc ją na bloki: dwa bloki banera, blok lewy, środkowy, prawy oraz stopkę. Zastosowano semantyczne znaczniki sekcji HTML5 zgodnie z ich znaczeniem, w tym do części nagłówkowej - header, stopki - footer, dopuszcza się zagnieżdżenie bloków div w znacznikach semantycznych

    ok. 2 min
    Polecenie z arkusza

    Podział strony na bloki: na górze dwa bloki banera, poniżej trzy bloki: lewy, środkowy i prawy, na dole blok stopki. Podział zrealizowany wyłącznie za pomocą semantycznych znaczników sekcji języka HTML5 tak, aby po uruchomieniu w przeglądarce wygląd układu bloków był zgodny z obrazem 2

    Oba banery to <header> (znacznik może wystąpić kilka razy), trzy bloki środkowe to <section>, stopka - <footer>; klucz (R.2.5) wymaga wprost header i footer. Identyfikatory po angielsku: banner1, banner2, left, middle, right - banery i bloki mają wspólne cechy (selektory znaczników), ale różne szerokości, które rozróżnią identyfikatory.

    wazenie.php PHP zmienione: 12 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Ważenie samochodów ciężarowych</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="banner1">
        </header>
        <header id="banner2">
        </header>
        <section id="left">
        </section>
        <section id="middle">
        </section>
        <section id="right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wazenie.php)
  16. Krok 16: Baner 1: nagłówek

    ok. 1 min
    Polecenie z arkusza

    Zawartość pierwszego banera: nagłówek pierwszego stopnia o treści „Ważenie pojazdów we Wrocławiu”

    <h1> w pierwszym banerze.

    wazenie.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Ważenie samochodów ciężarowych</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="banner1">
            <h1>Ważenie pojazdów we Wrocławiu</h1>
        </header>
        <header id="banner2">
        </header>
        <section id="left">
        </section>
        <section id="middle">
        </section>
        <section id="right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wazenie.php)
  17. Krok 17: Baner 2: znak z limitem wagi

    ok. 1 min
    Polecenie z arkusza

    Zawartość drugiego banera: obraz1.png z tekstem alternatywnym o treści: „waga”

    Znacznik <img> z plikiem przerobionym w GIMP-ie. Tekst alternatywny (alt) czytają czytniki ekranu i widać go, gdy obraz się nie wczyta. Znak ma 150 px wysokości - tyle samo co baner.

    wazenie.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Ważenie samochodów ciężarowych</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="banner1">
            <h1>Ważenie pojazdów we Wrocławiu</h1>
        </header>
        <header id="banner2">
            <img src="obraz1.png" alt="waga">
        </header>
        <section id="left">
        </section>
        <section id="middle">
        </section>
        <section id="right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wazenie.php)
  18. Krok 18: Blok lewy: nagłówek i lista numerowana

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku lewego: Nagłówek drugiego stopnia o treści: „Lokalizacje wag”. Lista numerowana (uporządkowana) wypełniona przez skrypt 1

    <h2>, a pod nim pusta lista uporządkowana <ol> (numeruje elementy 1., 2., 3.). Elementy <li> wypisze Skrypt 1.

    wazenie.php PHP zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Ważenie samochodów ciężarowych</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="banner1">
            <h1>Ważenie pojazdów we Wrocławiu</h1>
        </header>
        <header id="banner2">
            <img src="obraz1.png" alt="waga">
        </header>
        <section id="left">
            <h2>Lokalizacje wag</h2>
            <ol>
            </ol>
        </section>
        <section id="middle">
        </section>
        <section id="right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wazenie.php)
  19. Krok 19: Blok lewy: nagłówek „Kontakt”

    ok. 1 min
    Polecenie z arkusza

    Nagłówek drugiego stopnia o treści: „Kontakt”

    Drugi <h2> w bloku lewym, pod listą.

    wazenie.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Ważenie samochodów ciężarowych</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="banner1">
            <h1>Ważenie pojazdów we Wrocławiu</h1>
        </header>
        <header id="banner2">
            <img src="obraz1.png" alt="waga">
        </header>
        <section id="left">
            <h2>Lokalizacje wag</h2>
            <ol>
            </ol>
            <h2>Kontakt</h2>
        </section>
        <section id="middle">
        </section>
        <section id="right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wazenie.php)
  20. Krok 20: Blok lewy: odnośnik pocztowy

    Kryteria:

    R.3.2 Odnośnik zapisano jako pocztowy (zastosowano "mailto:" ), prowadzi on do adresu [email protected]

    ok. 1 min
    Polecenie z arkusza

    Odnośnik pocztowy o treści „napisz” prowadzący do adresu [email protected]

    Odnośnik pocztowy ma w href przedrostek mailto: - kliknięcie otwiera program pocztowy z gotowym adresem odbiorcy zamiast strony WWW.

    Typowe błędy

    href="[email protected]" bez mailto: - przeglądarka szuka pliku o takiej nazwie obok strony.

    wazenie.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Ważenie samochodów ciężarowych</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="banner1">
            <h1>Ważenie pojazdów we Wrocławiu</h1>
        </header>
        <header id="banner2">
            <img src="obraz1.png" alt="waga">
        </header>
        <section id="left">
            <h2>Lokalizacje wag</h2>
            <ol>
            </ol>
            <h2>Kontakt</h2>
            <a href="mailto:[email protected]">napisz</a>
        </section>
        <section id="middle">
        </section>
        <section id="right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wazenie.php)
  21. Krok 21: Blok środkowy: nagłówek

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku środkowego: Nagłówek drugiego stopnia o treści: „Alerty”

    <h2> na początku bloku środkowego.

    wazenie.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Ważenie samochodów ciężarowych</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="banner1">
            <h1>Ważenie pojazdów we Wrocławiu</h1>
        </header>
        <header id="banner2">
            <img src="obraz1.png" alt="waga">
        </header>
        <section id="left">
            <h2>Lokalizacje wag</h2>
            <ol>
            </ol>
            <h2>Kontakt</h2>
            <a href="mailto:[email protected]">napisz</a>
        </section>
        <section id="middle">
            <h2>Alerty</h2>
        </section>
        <section id="right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wazenie.php)
  22. Krok 22: Blok środkowy: tabela z wierszem nagłówkowym

    Kryteria:

    R.2.9 Pierwszy wiersz tabeli zawiera komórki nagłówkowe o treści, kolejno: „rejestracja”, „ulica”, „waga”, „dzień”, „czas”, zastosowano znaczniki <th>

    ok. 2 min
    Polecenie z arkusza

    Tabela o pięciu kolumnach wypełniona danymi: pierwszy wiersz zawiera komórki nagłówkowe o treści kolejno: „rejestracja”, „ulica”, „waga”, „dzień”, „czas”, kolejne wiersze wypełnione są przez skrypt 2 zgodnie z obrazem 2

    Pierwszy wiersz <tr> z pięcioma komórkami nagłówkowymi <th> - małymi literami, jak w arkuszu („dzień” z polską literą, choć kolumna w bazie to dzien). Wiersze z danymi dopisze Skrypt 2 przed </table>.

    wazenie.php PHP zmienione: 9 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Ważenie samochodów ciężarowych</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="banner1">
            <h1>Ważenie pojazdów we Wrocławiu</h1>
        </header>
        <header id="banner2">
            <img src="obraz1.png" alt="waga">
        </header>
        <section id="left">
            <h2>Lokalizacje wag</h2>
            <ol>
            </ol>
            <h2>Kontakt</h2>
            <a href="mailto:[email protected]">napisz</a>
        </section>
        <section id="middle">
            <h2>Alerty</h2>
            <table>
                <tr>
                    <th>rejestracja</th>
                    <th>ulica</th>
                    <th>waga</th>
                    <th>dzień</th>
                    <th>czas</th>
                </tr>
            </table>
        </section>
        <section id="right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wazenie.php)
  23. Krok 23: Blok środkowy: miejsce na Skrypt 3

    ok. 1 min
    Polecenie z arkusza

    Efekt działania skryptu 3

    Skrypt 3 nic nie wypisuje - dopisuje pomiar do bazy i każe przeglądarce odświeżyć stronę. Stanie pod tabelą, w części o PHP.

    Podgląd strony bez zmian - taki jak po kroku 22.

  24. Krok 24: Blok prawy: zdjęcie ciężarówki

    Kryteria:

    R.2.10 W drugim banerze umieszczono obraz z limitem wagi z tekstem alternatywnym "waga" oraz w bloku prawym umieszczono obraz z ciężarówką z tekstem alternatywnym "tir"

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku prawego: obraz2.jpg z tekstem alternatywnym o treści: „tir”

    Obraz dostaje identyfikator truck - arkusz stylów ma dać szerokość i marginesy „jedynie dla obrazu o nazwie obraz2.jpg”, a znak w banerze to też <img>. Ten krok zamyka R.2.10: znak z tekstem „waga” i ciężarówka z tekstem „tir”.

    wazenie.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Ważenie samochodów ciężarowych</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="banner1">
            <h1>Ważenie pojazdów we Wrocławiu</h1>
        </header>
        <header id="banner2">
            <img src="obraz1.png" alt="waga">
        </header>
        <section id="left">
            <h2>Lokalizacje wag</h2>
            <ol>
            </ol>
            <h2>Kontakt</h2>
            <a href="mailto:[email protected]">napisz</a>
        </section>
        <section id="middle">
            <h2>Alerty</h2>
            <table>
                <tr>
                    <th>rejestracja</th>
                    <th>ulica</th>
                    <th>waga</th>
                    <th>dzień</th>
                    <th>czas</th>
                </tr>
            </table>
        </section>
        <section id="right">
            <img src="obraz2.jpg" alt="tir" id="truck">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wazenie.php)
  25. Krok 25: Stopka

    Kryteria:

    R.2.6 W pierwszym banerze zapisano nagłówek h1: "Ważenie pojazdów we Wrocławiu" , w bloku lewym h2: "Lokalizacje wag" i "Kontakt" , w bloku środkowym h2: "Alerty" oraz w stopce paragraf z numerem zdającego

    ok. 1 min
    Polecenie z arkusza

    Zawartość stopki: akapit (paragraf) o treści: „Stronę wykonał: ”, następnie numer zdającego.

    Akapit w <footer>. Na egzaminie po dwukropku wpisuje się swój numer zdającego (PESEL) - tutaj stoi imię i nazwisko autora rozwiązania. Z tym krokiem są wszystkie nagłówki i akapit z R.2.6.

    wazenie.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Ważenie samochodów ciężarowych</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="banner1">
            <h1>Ważenie pojazdów we Wrocławiu</h1>
        </header>
        <header id="banner2">
            <img src="obraz1.png" alt="waga">
        </header>
        <section id="left">
            <h2>Lokalizacje wag</h2>
            <ol>
            </ol>
            <h2>Kontakt</h2>
            <a href="mailto:[email protected]">napisz</a>
        </section>
        <section id="middle">
            <h2>Alerty</h2>
            <table>
                <tr>
                    <th>rejestracja</th>
                    <th>ulica</th>
                    <th>waga</th>
                    <th>dzień</th>
                    <th>czas</th>
                </tr>
            </table>
        </section>
        <section id="right">
            <img src="obraz2.jpg" alt="tir" id="truck">
        </section>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wazenie.php)
  26. Etap 3: Styl CSS

    Kroki 26-38 · po tym etapie masz 27 z 37 kryteriów (pkt)

    Krok 26: Plik styl.css: krój Tahoma

    Kryteria:

    R.4.1 Ustawiono domyślne formatowanie wszystkich selektorów (dla *): krój czcionki Tahoma

    ok. 1 min
    Polecenie z arkusza

    Domyślne formatowanie wszystkich selektorów: krój czcionki Tahoma

    Selektor uniwersalny *.

    styl.css CSS nowy plik
    * {
        font-family: Tahoma;
    }
    Podgląd strony po tym kroku (wazenie.php)
  27. Krok 27: Banery: wspólne cechy

    ok. 1 min
    Polecenie z arkusza

    Wspólne dla obu bloków banera: kolor tła #519657, biały kolor czcionki, wyrównanie tekstu do środka, wysokość 150 px

    Selektor znacznika header łapie oba banery naraz. text-align: center wyśrodkowuje także obraz w drugim banerze - <img> jest elementem liniowym, więc zachowuje się jak tekst.

    styl.css CSS zmienione: 6 linii
    * {
        font-family: Tahoma;
    }
    header {
        background-color: #519657;
        color: white;
        text-align: center;
        height: 150px;
    }
    Podgląd strony po tym kroku (wazenie.php)
  28. Krok 28: Banery: szerokości

    ok. 1 min
    Polecenie z arkusza

    Dodatkowo pierwszy baner ma szerokość 70%, drugi 30%

    Tu przydają się identyfikatory. Razem 100% - po ustawieniu bloków obok siebie banery zajmą cały wiersz.

    styl.css CSS zmienione: 6 linii
    * {
        font-family: Tahoma;
    }
    header {
        background-color: #519657;
        color: white;
        text-align: center;
        height: 150px;
    }
    #banner1 {
        width: 70%;
    }
    #banner2 {
        width: 30%;
    }
    Podgląd strony po tym kroku (wazenie.php)
  29. Krok 29: Trzy bloki: tło i wysokość

    Kryteria:

    R.4.3 Ustawiono wysokość obu banerów na 150px, bloków lewego, środkowego i prawego na 450px

    ok. 1 min
    Polecenie z arkusza

    Wspólne dla bloku lewego, środkowego i prawego: kolor tła #E1E1E1, wysokość 450 px

    Selektor section - trzy bloki naraz. Z tą regułą komplet wysokości z R.4.3: 150 px banerów i 450 px bloków.

    styl.css CSS zmienione: 4 linie
    * {
        font-family: Tahoma;
    }
    header {
        background-color: #519657;
        color: white;
        text-align: center;
        height: 150px;
    }
    #banner1 {
        width: 70%;
    }
    #banner2 {
        width: 30%;
    }
    section {
        background-color: #E1E1E1;
        height: 450px;
    }
    Podgląd strony po tym kroku (wazenie.php)
  30. Krok 30: Bloki boczne: szerokość

    ok. 1 min
    Polecenie z arkusza

    Dodatkowo bloki lewy i prawy mają szerokość 25%

    Dwa identyfikatory po przecinku - jedna reguła dla dwóch bloków.

    styl.css CSS zmienione: 3 linie
    * {
        font-family: Tahoma;
    }
    header {
        background-color: #519657;
        color: white;
        text-align: center;
        height: 150px;
    }
    #banner1 {
        width: 70%;
    }
    #banner2 {
        width: 30%;
    }
    section {
        background-color: #E1E1E1;
        height: 450px;
    }
    #left, #right {
        width: 25%;
    }
    Podgląd strony po tym kroku (wazenie.php)
  31. Krok 31: Blok środkowy: szerokość i paski przewijania

    Kryteria:

    R.4.7 Ustawiono dla bloku środkowego automatyczne paski przewijania (overflow: auto lub scroll )

    ok. 2 min
    Polecenie z arkusza

    Dodatkowo blok środkowy ma szerokość 50% oraz paski przewijania, które pojawiają się jedynie, gdy zawartość nie mieści się w bloku

    overflow: auto - pasek przewijania pojawia się tylko wtedy, gdy treść jest wyższa (albo szersza) niż blok. Tutaj to realna potrzeba: Skrypt 3 co 10 sekund dopisuje pomiar, więc tabela alertów rośnie i po kilku minutach przestaje się mieścić w 450 px. overflow: scroll pokazywałby paski zawsze, także przy krótkiej tabeli.

    styl.css CSS zmienione: 4 linie
    * {
        font-family: Tahoma;
    }
    header {
        background-color: #519657;
        color: white;
        text-align: center;
        height: 150px;
    }
    #banner1 {
        width: 70%;
    }
    #banner2 {
        width: 30%;
    }
    section {
        background-color: #E1E1E1;
        height: 450px;
    }
    #left, #right {
        width: 25%;
    }
    #middle {
        width: 50%;
        overflow: auto;
    }
    Podgląd strony po tym kroku (wazenie.php)
  32. Krok 32: Stopka

    Kryteria: ,

    R.4.2 Ustawiono kolor tła #519657 dla obu banerów, #E1E1E1 dla bloku lewego, środkowego i prawego oraz #80C683 dla stopki oraz biały kolor czcionki dla obu banerów

    R.4.5 Ustawiono wyrównanie tekstu do środka dla obu banerów i stopki

    ok. 1 min
    Polecenie z arkusza

    Dla stopki: kolor tła #80C683, wyrównanie tekstu do środka

    Z tą regułą są wszystkie kolory z R.4.2 (tło banerów, bloków i stopki oraz biel czcionki banerów) i wyśrodkowanie tekstu banerów i stopki (R.4.5).

    styl.css CSS zmienione: 4 linie
    * {
        font-family: Tahoma;
    }
    header {
        background-color: #519657;
        color: white;
        text-align: center;
        height: 150px;
    }
    #banner1 {
        width: 70%;
    }
    #banner2 {
        width: 30%;
    }
    section {
        background-color: #E1E1E1;
        height: 450px;
    }
    #left, #right {
        width: 25%;
    }
    #middle {
        width: 50%;
        overflow: auto;
    }
    footer {
        background-color: #80C683;
        text-align: center;
    }
    Podgląd strony po tym kroku (wazenie.php)
  33. Krok 33: Zdjęcie ciężarówki: szerokość i odstęp

    Kryteria:

    R.4.4 Ustawiono szerokość pierwszego banera 70%, drugiego banera 30%, bloku lewego i prawego na 25%, bloku środkowego 50% (width lub grid-template-columns lub flex ) oraz 100% szerokości jedynie dla obrazu o nazwie obraz2.jpg

    ok. 2 min
    Polecenie z arkusza

    Jedynie dla obrazu o nazwie obraz2.jpg: szerokość 100%, marginesy wewnętrzne górny i dolny 100 px, pozostałe 0

    Selektor #truck trafia tylko w zdjęcie ciężarówki. Skrót padding: 100px 0 - pierwsza wartość to góra i dół, druga to lewa i prawa strona. Dopełnienie odsuwa zdjęcie od górnej krawędzi bloku, więc ciężarówka stoi mniej więcej na środku wysokości - jak na obrazie 2. Ta reguła zamyka szerokości z R.4.4: banery 70% i 30%, bloki 25%, 50%, 25% i zdjęcie 100%.

    Typowe błędy

    Reguła dla selektora img objęłaby też znak w banerze - rozciągnęłaby go na całą szerokość drugiego banera.

    styl.css CSS zmienione: 4 linie
    * {
        font-family: Tahoma;
    }
    header {
        background-color: #519657;
        color: white;
        text-align: center;
        height: 150px;
    }
    #banner1 {
        width: 70%;
    }
    #banner2 {
        width: 30%;
    }
    section {
        background-color: #E1E1E1;
        height: 450px;
    }
    #left, #right {
        width: 25%;
    }
    #middle {
        width: 50%;
        overflow: auto;
    }
    footer {
        background-color: #80C683;
        text-align: center;
    }
    #truck {
        width: 100%;
        padding: 100px 0;
    }
    Podgląd strony po tym kroku (wazenie.php)
  34. Krok 34: Tabela: obramowanie

    Kryteria:

    R.4.8 Ustawiono dla selektora table: obramowanie 1px solid #80C683

    ok. 1 min
    Polecenie z arkusza

    Dla selektora tabeli: obramowanie linią ciągłą o szerokości 1 px i kolorze #80C683

    Selektor znacznika table - uwaga arkusza wyklucza klasy i identyfikatory dla tabeli, wierszy i komórek.

    styl.css CSS zmienione: 3 linie
    * {
        font-family: Tahoma;
    }
    header {
        background-color: #519657;
        color: white;
        text-align: center;
        height: 150px;
    }
    #banner1 {
        width: 70%;
    }
    #banner2 {
        width: 30%;
    }
    section {
        background-color: #E1E1E1;
        height: 450px;
    }
    #left, #right {
        width: 25%;
    }
    #middle {
        width: 50%;
        overflow: auto;
    }
    footer {
        background-color: #80C683;
        text-align: center;
    }
    #truck {
        width: 100%;
        padding: 100px 0;
    }
    table {
        border: 1px solid #80C683;
    }
    Podgląd strony po tym kroku (wazenie.php)
  35. Krok 35: Komórki: dopełnienie

    Kryteria:

    R.4.6 Ustawiono marginesy wewnętrzne (padding) dla selektora td 2px oraz jedynie dla obrazu o nazwie obraz2.jpg : jedynie górny i dolny 100px

    ok. 1 min
    Polecenie z arkusza

    Dla selektora komórki tabeli: marginesy wewnętrzne 2 px

    Komórka tabeli to td. Razem z dopełnieniem zdjęcia to kryterium R.4.6.

    styl.css CSS zmienione: 3 linie
    * {
        font-family: Tahoma;
    }
    header {
        background-color: #519657;
        color: white;
        text-align: center;
        height: 150px;
    }
    #banner1 {
        width: 70%;
    }
    #banner2 {
        width: 30%;
    }
    section {
        background-color: #E1E1E1;
        height: 450px;
    }
    #left, #right {
        width: 25%;
    }
    #middle {
        width: 50%;
        overflow: auto;
    }
    footer {
        background-color: #80C683;
        text-align: center;
    }
    #truck {
        width: 100%;
        padding: 100px 0;
    }
    table {
        border: 1px solid #80C683;
    }
    td {
        padding: 2px;
    }
    Podgląd strony po tym kroku (wazenie.php)
  36. Krok 36: Wiersz pod kursorem

    Kryteria:

    R.4.9 Gdy kursor myszy znajdzie się na wierszu tabeli, kolor tła wiersza zmienia się na #80C683 (dla tr:hover )

    ok. 1 min
    Polecenie z arkusza

    Gdy kursor myszy znajdzie się na wierszu tabeli kolor tła wiersza zmienia się na #80C683

    Pseudoklasa :hover na selektorze tr - obraz 2 pokazuje kursor na trzecim wierszu (pomiar z ulicy Tyskiej) podświetlonym na zielono.

    styl.css CSS zmienione: 3 linie
    * {
        font-family: Tahoma;
    }
    header {
        background-color: #519657;
        color: white;
        text-align: center;
        height: 150px;
    }
    #banner1 {
        width: 70%;
    }
    #banner2 {
        width: 30%;
    }
    section {
        background-color: #E1E1E1;
        height: 450px;
    }
    #left, #right {
        width: 25%;
    }
    #middle {
        width: 50%;
        overflow: auto;
    }
    footer {
        background-color: #80C683;
        text-align: center;
    }
    #truck {
        width: 100%;
        padding: 100px 0;
    }
    table {
        border: 1px solid #80C683;
    }
    td {
        padding: 2px;
    }
    tr:hover {
        background-color: #80C683;
    }
    Podgląd strony po tym kroku (wazenie.php)
  37. Krok 37: Ostatni wiersz na czerwono

    Kryteria:

    R.4.10 Ostatni wiersz tabeli ma tło czerwone np. dla tr:nth-last-child(1)

    ok. 2 min
    Polecenie z arkusza

    Ostatni wiersz tabeli ma tło czerwone

    Pseudoklasa :last-child wybiera element, który jest ostatnim dzieckiem swojego rodzica - tu ostatni wiersz tabeli (klucz podaje równoważne tr:nth-last-child(1)). Wiersze dopisuje skrypt, więc nie da się nadać klasy „ostatniemu” w HTML-u - pseudoklasa sama znajdzie ten, który akurat jest na końcu. Kiedy Skrypt 3 doda pomiar powyżej 5 t, czerwień przejdzie na nowy wiersz (obraz 3).

    styl.css CSS zmienione: 3 linie
    * {
        font-family: Tahoma;
    }
    header {
        background-color: #519657;
        color: white;
        text-align: center;
        height: 150px;
    }
    #banner1 {
        width: 70%;
    }
    #banner2 {
        width: 30%;
    }
    section {
        background-color: #E1E1E1;
        height: 450px;
    }
    #left, #right {
        width: 25%;
    }
    #middle {
        width: 50%;
        overflow: auto;
    }
    footer {
        background-color: #80C683;
        text-align: center;
    }
    #truck {
        width: 100%;
        padding: 100px 0;
    }
    table {
        border: 1px solid #80C683;
    }
    td {
        padding: 2px;
    }
    tr:hover {
        background-color: #80C683;
    }
    tr:last-child {
        background-color: red;
    }
    Podgląd strony po tym kroku (wazenie.php)
  38. Krok 38: Układ bloków zgodny z obrazem 2

    Kryteria:

    R.3.1 Układ bloków po uruchomieniu strony w przeglądarce jest zgodny z obrazem 2 w arkuszu (prawidłowo zastosowano właściwości CSS decydujące o układzie strony, np. float i clear albo display flex albo grid)

    ok. 2 min
    Polecenie z arkusza

    Podział strony na bloki: na górze dwa bloki banera, poniżej trzy bloki: lewy, środkowy i prawy, na dole blok stopki. Podział zrealizowany wyłącznie za pomocą semantycznych znaczników sekcji języka HTML5 tak, aby po uruchomieniu w przeglądarce wygląd układu bloków był zgodny z obrazem 2

    float: left dla banerów i bloków: każdy przesuwa się do lewej i staje obok poprzedniego, dopóki mieści się w wierszu. Banery mają razem 100% szerokości, więc trzeci element (blok lewy) nie zmieści się obok nich i przejdzie do nowego wiersza - tam bloki 25% + 50% + 25% znowu wypełniają całą szerokość. clear: both dla stopki każe jej stanąć pod wszystkimi pływającymi blokami; bez tego wjechałaby pod nie, na samą górę strony.

    Typowe błędy

    Marginesy albo obramowania bloków przy szerokościach sumujących się do 100% - prawy blok spada do następnego wiersza.

    styl.css CSS zmienione: 6 linii
    * {
        font-family: Tahoma;
    }
    header {
        background-color: #519657;
        color: white;
        text-align: center;
        height: 150px;
    }
    #banner1 {
        width: 70%;
    }
    #banner2 {
        width: 30%;
    }
    section {
        background-color: #E1E1E1;
        height: 450px;
    }
    #left, #right {
        width: 25%;
    }
    #middle {
        width: 50%;
        overflow: auto;
    }
    footer {
        background-color: #80C683;
        text-align: center;
    }
    #truck {
        width: 100%;
        padding: 100px 0;
    }
    table {
        border: 1px solid #80C683;
    }
    td {
        padding: 2px;
    }
    tr:hover {
        background-color: #80C683;
    }
    tr:last-child {
        background-color: red;
    }
    header, section {
        float: left;
    }
    footer {
        clear: both;
    }
    Podgląd strony po tym kroku (wazenie.php)
  39. Etap 4: Skrypty PHP

    Kroki 39-46 · po tym etapie masz 37 z 37 kryteriów (pkt)

    Krok 39: Połączenie z bazą i zamknięcie na końcu

    Kryteria: ,

    R.5.1 Skrypt zawiera działające połączenie z serwerem bazy danych i wybór bazy wazenietirow

    R.5.2 Ostatnią operacją na bazie jest jej zamknięcie (zgodne ze składnią)

    ok. 2 min
    Polecenie z arkusza

    Skrypty łączą się z serwerem bazodanowym na localhost, użytkownik root bez hasła, baza danych o nazwie wazenietirow. Na końcu jest zamykane połączenie z serwerem.

    Pierwszy skrypt na stronie stoi w liście bloku lewego, więc tam otwiera się połączenie: mysqli_connect łączy się z serwerem i od razu wybiera bazę. Uchwyt w zmiennej $connection posłuży wszystkim trzem skryptom. Ostatni blok PHP, pod tabelą w bloku środkowym, na razie tylko zamyka połączenie - Skrypt 3 stanie nad tą linią. Od tego kroku podgląd to wynik prawdziwego uruchomienia strony.

    wazenie.php PHP zmienione: 6 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Ważenie samochodów ciężarowych</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="banner1">
            <h1>Ważenie pojazdów we Wrocławiu</h1>
        </header>
        <header id="banner2">
            <img src="obraz1.png" alt="waga">
        </header>
        <section id="left">
            <h2>Lokalizacje wag</h2>
            <ol>
            <?php
                $connection = mysqli_connect("localhost", "root", "", "wazenietirow");
            ?>
            </ol>
            <h2>Kontakt</h2>
            <a href="mailto:[email protected]">napisz</a>
        </section>
        <section id="middle">
            <h2>Alerty</h2>
            <table>
                <tr>
                    <th>rejestracja</th>
                    <th>ulica</th>
                    <th>waga</th>
                    <th>dzień</th>
                    <th>czas</th>
                </tr>
            </table>
            <?php
                mysqli_close($connection);
            ?>
        </section>
        <section id="right">
            <img src="obraz2.jpg" alt="tir" id="truck">
        </section>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wazenie.php)
  40. Krok 40: Skrypt 1: zapytanie 2

    Kryteria:

    R.5.3 Skrypt 1 wysyła do bazy danych zapytanie 2 lub skrypt 2 wysyła zapytanie 4 lub skrypt 3 wysyła zapytanie 3

    ok. 2 min
    Polecenie z arkusza

    Skrypt 1 wysyła do bazy danych zapytanie 2

    Zapytanie 2 w zmiennej $query, mysqli_query wysyła je do bazy, a wynik czeka w $result. Skrypt stoi między <ol> a </ol> - to, co wypisze, stanie się elementami listy.

    wazenie.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Ważenie samochodów ciężarowych</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="banner1">
            <h1>Ważenie pojazdów we Wrocławiu</h1>
        </header>
        <header id="banner2">
            <img src="obraz1.png" alt="waga">
        </header>
        <section id="left">
            <h2>Lokalizacje wag</h2>
            <ol>
            <?php
                $connection = mysqli_connect("localhost", "root", "", "wazenietirow");
                $query = "SELECT ulica FROM lokalizacje;";
                $result = mysqli_query($connection, $query);
            ?>
            </ol>
            <h2>Kontakt</h2>
            <a href="mailto:[email protected]">napisz</a>
        </section>
        <section id="middle">
            <h2>Alerty</h2>
            <table>
                <tr>
                    <th>rejestracja</th>
                    <th>ulica</th>
                    <th>waga</th>
                    <th>dzień</th>
                    <th>czas</th>
                </tr>
            </table>
            <?php
                mysqli_close($connection);
            ?>
        </section>
        <section id="right">
            <img src="obraz2.jpg" alt="tir" id="truck">
        </section>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>

    Podgląd strony bez zmian - taki jak po kroku 39.

  41. Krok 41: Skrypt 1: elementy listy z nazwami ulic

    Kryteria: ,

    R.5.4 Skrypt 1 wyświetla zwrócone zapytaniem nazwy ulic według wzoru: ”ulica <nazwa_ulicy>”, gdzie nawiasy <> oznaczają wartość pobraną z bazy danych

    R.2.7 W bloku lewym umieszczono jedną listę numerowaną z elementami, zastosowano znaczniki <ol>, <li> (listę wygenerowano skryptem lub w HTML)

    ok. 2 min
    Polecenie z arkusza

    Zwrócone nazwy ulic są wyświetlane w elementach listy numerowanej z bloku lewego, według wzoru: ”ulica <nazwa_ulicy>”, gdzie nawiasy <> oznaczają wartość pobraną z bazy danych

    Pętla while pobiera kolejne wiersze; mysqli_fetch_row oddaje wiersz jako tablicę, a $street[0] to jedyne pole - ulica. Słowo „ulica ” jest stałym tekstem przed wartością z bazy. Podgląd: „1. ulica Ślężna”, „2. ulica Tyska” i dalej - numery dopisuje sama lista <ol>.

    wazenie.php PHP zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Ważenie samochodów ciężarowych</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="banner1">
            <h1>Ważenie pojazdów we Wrocławiu</h1>
        </header>
        <header id="banner2">
            <img src="obraz1.png" alt="waga">
        </header>
        <section id="left">
            <h2>Lokalizacje wag</h2>
            <ol>
            <?php
                $connection = mysqli_connect("localhost", "root", "", "wazenietirow");
                $query = "SELECT ulica FROM lokalizacje;";
                $result = mysqli_query($connection, $query);
                while ($street = mysqli_fetch_row($result)) {
                    echo "<li>ulica $street[0]</li>";
                }
            ?>
            </ol>
            <h2>Kontakt</h2>
            <a href="mailto:[email protected]">napisz</a>
        </section>
        <section id="middle">
            <h2>Alerty</h2>
            <table>
                <tr>
                    <th>rejestracja</th>
                    <th>ulica</th>
                    <th>waga</th>
                    <th>dzień</th>
                    <th>czas</th>
                </tr>
            </table>
            <?php
                mysqli_close($connection);
            ?>
        </section>
        <section id="right">
            <img src="obraz2.jpg" alt="tir" id="truck">
        </section>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wazenie.php)
  42. Krok 42: Skrypt 2: zapytanie 4 w tabeli

    ok. 1 min
    Polecenie z arkusza

    Skrypt 2 wysyła do bazy danych zapytanie 4 (kolejność wybieranych pól w zapytaniu zgodna z obrazem 3)

    Skrypt 2 stoi w tabeli, pod wierszem nagłówkowym - wiersze, które wypisze, trafią do środka <table>. Kolejność pól w zapytaniu (rejestracja, ulica, waga, dzień, czas) to kolejność kolumn tabeli, więc komórki wypisze się po prostu po kolei.

    wazenie.php PHP zmienione: 4 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Ważenie samochodów ciężarowych</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="banner1">
            <h1>Ważenie pojazdów we Wrocławiu</h1>
        </header>
        <header id="banner2">
            <img src="obraz1.png" alt="waga">
        </header>
        <section id="left">
            <h2>Lokalizacje wag</h2>
            <ol>
            <?php
                $connection = mysqli_connect("localhost", "root", "", "wazenietirow");
                $query = "SELECT ulica FROM lokalizacje;";
                $result = mysqli_query($connection, $query);
                while ($street = mysqli_fetch_row($result)) {
                    echo "<li>ulica $street[0]</li>";
                }
            ?>
            </ol>
            <h2>Kontakt</h2>
            <a href="mailto:[email protected]">napisz</a>
        </section>
        <section id="middle">
            <h2>Alerty</h2>
            <table>
                <tr>
                    <th>rejestracja</th>
                    <th>ulica</th>
                    <th>waga</th>
                    <th>dzień</th>
                    <th>czas</th>
                </tr>
                <?php
                    $query = "SELECT rejestracja, ulica, waga, dzien, czas FROM wagi JOIN lokalizacje ON wagi.lokalizacje_id = lokalizacje.id WHERE waga > 5;";
                    $result = mysqli_query($connection, $query);
                ?>
            </table>
            <?php
                mysqli_close($connection);
            ?>
        </section>
        <section id="right">
            <img src="obraz2.jpg" alt="tir" id="truck">
        </section>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wazenie.php)
  43. Krok 43: Skrypt 2: wiersze z numerem rejestracyjnym

    ok. 2 min
    Polecenie z arkusza

    Każdy zwrócony zapytaniem wiersz jest wyświetlany w osobnym wierszu tabeli z bloku środkowego

    Każdy pomiar to jeden <tr>. Na razie jedna komórka, żeby sprawdzić pętlę: dziewięć numerów rejestracyjnych, ostatni (DW54N32) na czerwono - działa już reguła tr:last-child.

    wazenie.php PHP zmienione: 5 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Ważenie samochodów ciężarowych</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="banner1">
            <h1>Ważenie pojazdów we Wrocławiu</h1>
        </header>
        <header id="banner2">
            <img src="obraz1.png" alt="waga">
        </header>
        <section id="left">
            <h2>Lokalizacje wag</h2>
            <ol>
            <?php
                $connection = mysqli_connect("localhost", "root", "", "wazenietirow");
                $query = "SELECT ulica FROM lokalizacje;";
                $result = mysqli_query($connection, $query);
                while ($street = mysqli_fetch_row($result)) {
                    echo "<li>ulica $street[0]</li>";
                }
            ?>
            </ol>
            <h2>Kontakt</h2>
            <a href="mailto:[email protected]">napisz</a>
        </section>
        <section id="middle">
            <h2>Alerty</h2>
            <table>
                <tr>
                    <th>rejestracja</th>
                    <th>ulica</th>
                    <th>waga</th>
                    <th>dzień</th>
                    <th>czas</th>
                </tr>
                <?php
                    $query = "SELECT rejestracja, ulica, waga, dzien, czas FROM wagi JOIN lokalizacje ON wagi.lokalizacje_id = lokalizacje.id WHERE waga > 5;";
                    $result = mysqli_query($connection, $query);
                    while ($measurement = mysqli_fetch_row($result)) {
                        echo "<tr>";
                        echo "<td>$measurement[0]</td>";
                        echo "</tr>";
                    }
                ?>
            </table>
            <?php
                mysqli_close($connection);
            ?>
        </section>
        <section id="right">
            <img src="obraz2.jpg" alt="tir" id="truck">
        </section>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wazenie.php)
  44. Krok 44: Skrypt 2: ulica, waga, dzień i czas

    Kryteria: ,

    R.5.5 Skrypt 2 wyświetla zwrócone zapytaniem dane z każdego wybranego z bazy wiersza

    R.2.8 W bloku środkowym umieszczono jedną tabelę o pięciu kolumnach, zastosowano znaczniki <table>, <tr>, <td> (tabelę wygenerowano skryptem lub w HTML)

    ok. 2 min
    Polecenie z arkusza

    Każdy zwrócony zapytaniem wiersz jest wyświetlany w osobnym wierszu tabeli z bloku środkowego

    Pozostałe cztery komórki w kolejności pól z SELECT. Tabela wygląda jak na obrazie 2; pomiary z ulic Tyskiej, Średzkiej i Wilanowskiej mają datę i godzinę wykonania zapytania 1 (tu 2026-10-04, 11:17:40). Ta tabela ma pięć kolumn ze znacznikami <table>, <tr>, <td> (R.2.8).

    wazenie.php PHP zmienione: 4 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Ważenie samochodów ciężarowych</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="banner1">
            <h1>Ważenie pojazdów we Wrocławiu</h1>
        </header>
        <header id="banner2">
            <img src="obraz1.png" alt="waga">
        </header>
        <section id="left">
            <h2>Lokalizacje wag</h2>
            <ol>
            <?php
                $connection = mysqli_connect("localhost", "root", "", "wazenietirow");
                $query = "SELECT ulica FROM lokalizacje;";
                $result = mysqli_query($connection, $query);
                while ($street = mysqli_fetch_row($result)) {
                    echo "<li>ulica $street[0]</li>";
                }
            ?>
            </ol>
            <h2>Kontakt</h2>
            <a href="mailto:[email protected]">napisz</a>
        </section>
        <section id="middle">
            <h2>Alerty</h2>
            <table>
                <tr>
                    <th>rejestracja</th>
                    <th>ulica</th>
                    <th>waga</th>
                    <th>dzień</th>
                    <th>czas</th>
                </tr>
                <?php
                    $query = "SELECT rejestracja, ulica, waga, dzien, czas FROM wagi JOIN lokalizacje ON wagi.lokalizacje_id = lokalizacje.id WHERE waga > 5;";
                    $result = mysqli_query($connection, $query);
                    while ($measurement = mysqli_fetch_row($result)) {
                        echo "<tr>";
                        echo "<td>$measurement[0]</td>";
                        echo "<td>$measurement[1]</td>";
                        echo "<td>$measurement[2]</td>";
                        echo "<td>$measurement[3]</td>";
                        echo "<td>$measurement[4]</td>";
                        echo "</tr>";
                    }
                ?>
            </table>
            <?php
                mysqli_close($connection);
            ?>
        </section>
        <section id="right">
            <img src="obraz2.jpg" alt="tir" id="truck">
        </section>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wazenie.php)
  45. Krok 45: Skrypt 3: zapytanie 3

    Kryteria:

    R.5.7 Skrypt 3 wstawia rekord do bazy (sprawdzić w phpMyAdmin)

    ok. 2 min
    Polecenie z arkusza

    Skrypt 3 wysyła do bazy danych zapytanie 3

    Zapytanie 3 bez zmian: przy każdym wejściu na stronę baza dopisuje pomiar DW12345 z losową wagą. Na stronie nic się nie zmienia - Skrypt 3 stoi pod tabelą, więc nowy pomiar zobaczy dopiero następne wejście (i tylko wtedy, gdy wylosował więcej niż 5 t). Dopisany wiersz sprawdza się w phpMyAdmin.

    wazenie.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Ważenie samochodów ciężarowych</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="banner1">
            <h1>Ważenie pojazdów we Wrocławiu</h1>
        </header>
        <header id="banner2">
            <img src="obraz1.png" alt="waga">
        </header>
        <section id="left">
            <h2>Lokalizacje wag</h2>
            <ol>
            <?php
                $connection = mysqli_connect("localhost", "root", "", "wazenietirow");
                $query = "SELECT ulica FROM lokalizacje;";
                $result = mysqli_query($connection, $query);
                while ($street = mysqli_fetch_row($result)) {
                    echo "<li>ulica $street[0]</li>";
                }
            ?>
            </ol>
            <h2>Kontakt</h2>
            <a href="mailto:[email protected]">napisz</a>
        </section>
        <section id="middle">
            <h2>Alerty</h2>
            <table>
                <tr>
                    <th>rejestracja</th>
                    <th>ulica</th>
                    <th>waga</th>
                    <th>dzień</th>
                    <th>czas</th>
                </tr>
                <?php
                    $query = "SELECT rejestracja, ulica, waga, dzien, czas FROM wagi JOIN lokalizacje ON wagi.lokalizacje_id = lokalizacje.id WHERE waga > 5;";
                    $result = mysqli_query($connection, $query);
                    while ($measurement = mysqli_fetch_row($result)) {
                        echo "<tr>";
                        echo "<td>$measurement[0]</td>";
                        echo "<td>$measurement[1]</td>";
                        echo "<td>$measurement[2]</td>";
                        echo "<td>$measurement[3]</td>";
                        echo "<td>$measurement[4]</td>";
                        echo "</tr>";
                    }
                ?>
            </table>
            <?php
                $query = "INSERT INTO wagi (lokalizacje_id, waga, rejestracja, dzien, czas) VALUES (5, FLOOR(1 + RAND() * 10), 'DW12345', CURDATE(), CURTIME());";
                mysqli_query($connection, $query);
                mysqli_close($connection);
            ?>
        </section>
        <section id="right">
            <img src="obraz2.jpg" alt="tir" id="truck">
        </section>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>

    Podgląd strony bez zmian - taki jak po kroku 44.

  46. Krok 46: Skrypt 3: odświeżanie co 10 sekund

    Kryteria: ,

    R.5.6 Skrypt 3 odświeża aktualną stronę co 10 sekund, np. header("refresh: 10");

    R.5.8 Zastosowano znaczące nazewnictwo dla wszystkich zmiennych lub funkcji w języku polskim lub angielskim. Nazwy odzwierciedlają cel zastosowania

    ok. 2 min
    Polecenie z arkusza

    Odświeża aktualną stronę co 10 sekund.

    header("refresh: 10") wysyła przeglądarce nagłówek HTTP „wczytaj tę stronę ponownie za 10 sekund”. Każde odświeżenie to nowe wejście, więc Skrypt 3 dopisuje kolejny pomiar, a Skrypt 2 pokazuje te z wagą powyżej 5 t - tabela rośnie jak na obrazie 3, a czerwony jest zawsze ostatni wiersz. Podgląd pokazuje stronę po 5 odświeżeniach (pomiary losowe: 2 z nich przekroczyło 5 t). Nagłówek HTTP musi wyjść, zanim strona wypisze treść; tutaj działa, bo XAMPP ma w php.ini bufor wyjścia 4096 bajtów (output_buffering) i wstrzymuje wysyłanie treści, dopóki bufor się nie zapełni. Nazwy zmiennych mówią, co przechowują ($connection, $query, $result, $street, $measurement) - kryterium R.5.8.

    wazenie.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Ważenie samochodów ciężarowych</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="banner1">
            <h1>Ważenie pojazdów we Wrocławiu</h1>
        </header>
        <header id="banner2">
            <img src="obraz1.png" alt="waga">
        </header>
        <section id="left">
            <h2>Lokalizacje wag</h2>
            <ol>
            <?php
                $connection = mysqli_connect("localhost", "root", "", "wazenietirow");
                $query = "SELECT ulica FROM lokalizacje;";
                $result = mysqli_query($connection, $query);
                while ($street = mysqli_fetch_row($result)) {
                    echo "<li>ulica $street[0]</li>";
                }
            ?>
            </ol>
            <h2>Kontakt</h2>
            <a href="mailto:[email protected]">napisz</a>
        </section>
        <section id="middle">
            <h2>Alerty</h2>
            <table>
                <tr>
                    <th>rejestracja</th>
                    <th>ulica</th>
                    <th>waga</th>
                    <th>dzień</th>
                    <th>czas</th>
                </tr>
                <?php
                    $query = "SELECT rejestracja, ulica, waga, dzien, czas FROM wagi JOIN lokalizacje ON wagi.lokalizacje_id = lokalizacje.id WHERE waga > 5;";
                    $result = mysqli_query($connection, $query);
                    while ($measurement = mysqli_fetch_row($result)) {
                        echo "<tr>";
                        echo "<td>$measurement[0]</td>";
                        echo "<td>$measurement[1]</td>";
                        echo "<td>$measurement[2]</td>";
                        echo "<td>$measurement[3]</td>";
                        echo "<td>$measurement[4]</td>";
                        echo "</tr>";
                    }
                ?>
            </table>
            <?php
                $query = "INSERT INTO wagi (lokalizacje_id, waga, rejestracja, dzien, czas) VALUES (5, FLOOR(1 + RAND() * 10), 'DW12345', CURDATE(), CURTIME());";
                mysqli_query($connection, $query);
                header("refresh: 10");
                mysqli_close($connection);
            ?>
        </section>
        <section id="right">
            <img src="obraz2.jpg" alt="tir" id="truck">
        </section>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wazenie.php)
  47. Etap 5: Dobre praktyki (poza kluczem)

    Kroki 47-48 · po tym etapie masz 37 z 37 kryteriów (pkt)

    Krok 47: Nagłówek odświeżania na początku pliku

    ok. 3 min
    Polecenie z arkusza

    Odświeża aktualną stronę co 10 sekund.

    Wersja z egzaminu ma ukrytą wadę, którą widać dopiero po kilku minutach: header() stoi w środku strony i działa tylko dzięki buforowi wyjścia XAMPP-a (4096 bajtów). Każde odświeżenie dopisuje pomiar, tabela rośnie, a treść przed Skryptem 3 w końcu przekracza bufor. Sprawdzone na tej bazie: przy 55. wejściu (tabela miała już 35 wierszy) PHP zgłasza „Cannot modify header information - headers already sent” i strona przestaje się odświeżać. Na serwerze bez bufora błąd pojawiłby się od razu. Poprawka: nagłówek wysyła osobny blok PHP na samym początku pliku, przed <!DOCTYPE html> - wtedy zawsze idzie przed treścią (sprawdzone: 75 wejść z rzędu bez ostrzeżenia). Spacja albo pusta linia przed <?php też jest treścią i zepsułaby nagłówek. Na egzaminie wystarczy wersja wcześniejsza - klucz sprawdza samo odświeżanie.

    Typowe błędy

    Pusta linia albo BOM (znak kodowania zapisany przez edytor) przed <?php - nagłówek nie wychodzi, a strona się nie odświeża.

    wazenie.php PHP zmienione: 4 linie
    <?php
        header("refresh: 10");    // nagłówek HTTP przed jakąkolwiek treścią strony
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Ważenie samochodów ciężarowych</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="banner1">
            <h1>Ważenie pojazdów we Wrocławiu</h1>
        </header>
        <header id="banner2">
            <img src="obraz1.png" alt="waga">
        </header>
        <section id="left">
            <h2>Lokalizacje wag</h2>
            <ol>
            <?php
                $connection = mysqli_connect("localhost", "root", "", "wazenietirow");
                $query = "SELECT ulica FROM lokalizacje;";
                $result = mysqli_query($connection, $query);
                while ($street = mysqli_fetch_row($result)) {
                    echo "<li>ulica $street[0]</li>";
                }
            ?>
            </ol>
            <h2>Kontakt</h2>
            <a href="mailto:[email protected]">napisz</a>
        </section>
        <section id="middle">
            <h2>Alerty</h2>
            <table>
                <tr>
                    <th>rejestracja</th>
                    <th>ulica</th>
                    <th>waga</th>
                    <th>dzień</th>
                    <th>czas</th>
                </tr>
                <?php
                    $query = "SELECT rejestracja, ulica, waga, dzien, czas FROM wagi JOIN lokalizacje ON wagi.lokalizacje_id = lokalizacje.id WHERE waga > 5;";
                    $result = mysqli_query($connection, $query);
                    while ($measurement = mysqli_fetch_row($result)) {
                        echo "<tr>";
                        echo "<td>$measurement[0]</td>";
                        echo "<td>$measurement[1]</td>";
                        echo "<td>$measurement[2]</td>";
                        echo "<td>$measurement[3]</td>";
                        echo "<td>$measurement[4]</td>";
                        echo "</tr>";
                    }
                ?>
            </table>
            <?php
                $query = "INSERT INTO wagi (lokalizacje_id, waga, rejestracja, dzien, czas) VALUES (5, FLOOR(1 + RAND() * 10), 'DW12345', CURDATE(), CURTIME());";
                mysqli_query($connection, $query);
                // header("refresh: 10");  przeniesione na początek pliku, przed <!DOCTYPE html>
                mysqli_close($connection);
            ?>
        </section>
        <section id="right">
            <img src="obraz2.jpg" alt="tir" id="truck">
        </section>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wazenie.php)
  48. Krok 48: Pętla po komórkach i htmlspecialchars

    ok. 3 min
    Polecenie z arkusza

    Każdy zwrócony zapytaniem wiersz jest wyświetlany w osobnym wierszu tabeli z bloku środkowego

    Pięć prawie identycznych linii echo w Skrypcie 2 zastępuje pętla foreach po polach wiersza - kolumn jest tyle, ile pól w zapytaniu, więc po dodaniu pola do SELECT tabela sama dostanie nową komórkę. Wartości z bazy przechodzą przez htmlspecialchars: numer rejestracyjny wpisuje obsługa wagi, a znak < w takim polu rozbiłby tabelę. W Skrypcie 1 mysqli_fetch_assoc pozwala pisać $street["ulica"] zamiast $street[0]. Stare linie zostają w komentarzu. Tabela w podglądzie wygląda tak samo. Na egzaminie wystarczy wersja wcześniejsza - klucz tego nie sprawdza.

    wazenie.php PHP zmienione: 7 linii
    <?php
        header("refresh: 10");    // nagłówek HTTP przed jakąkolwiek treścią strony
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Ważenie samochodów ciężarowych</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="banner1">
            <h1>Ważenie pojazdów we Wrocławiu</h1>
        </header>
        <header id="banner2">
            <img src="obraz1.png" alt="waga">
        </header>
        <section id="left">
            <h2>Lokalizacje wag</h2>
            <ol>
            <?php
                $connection = mysqli_connect("localhost", "root", "", "wazenietirow");
                $query = "SELECT ulica FROM lokalizacje;";
                $result = mysqli_query($connection, $query);
                while ($street = mysqli_fetch_assoc($result)) {
                    echo "<li>ulica " . htmlspecialchars($street["ulica"]) . "</li>";
                }
                // while ($street = mysqli_fetch_row($result)) { echo "<li>ulica $street[0]</li>"; }
            ?>
            </ol>
            <h2>Kontakt</h2>
            <a href="mailto:[email protected]">napisz</a>
        </section>
        <section id="middle">
            <h2>Alerty</h2>
            <table>
                <tr>
                    <th>rejestracja</th>
                    <th>ulica</th>
                    <th>waga</th>
                    <th>dzień</th>
                    <th>czas</th>
                </tr>
                <?php
                    $query = "SELECT rejestracja, ulica, waga, dzien, czas FROM wagi JOIN lokalizacje ON wagi.lokalizacje_id = lokalizacje.id WHERE waga > 5;";
                    $result = mysqli_query($connection, $query);
                    while ($measurement = mysqli_fetch_row($result)) {
                        echo "<tr>";
                        foreach ($measurement as $value) {
                            echo "<td>" . htmlspecialchars($value) . "</td>";
                        }
                        echo "</tr>";
                    }
                    // pięć osobnych linii echo "<td>$measurement[0]</td>"; ... "<td>$measurement[4]</td>";
                ?>
            </table>
            <?php
                $query = "INSERT INTO wagi (lokalizacje_id, waga, rejestracja, dzien, czas) VALUES (5, FLOOR(1 + RAND() * 10), 'DW12345', CURDATE(), CURTIME());";
                mysqli_query($connection, $query);
                // header("refresh: 10");  przeniesione na początek pliku, przed <!DOCTYPE html>
                mysqli_close($connection);
            ?>
        </section>
        <section id="right">
            <img src="obraz2.jpg" alt="tir" id="truck">
        </section>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>

    Podgląd strony bez zmian - taki jak po kroku 47.

  49. Etap 6: Oddanie pracy

    Krok 49 · po tym etapie masz 37 z 37 kryteriów (pkt)

    Krok 49: 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 przeglądarka.txt wpisuje się nazwę przeglądarki, w której sprawdzana była strona.

    W folderze z numerem zdającego: import.png, kw1.jpg - kw4.jpg, kwerendy.txt, obraz1.png (z 5T), obraz2.jpg (odbity, 350 px), przeglądarka.txt, styl.css, wazenie.php. Płytę trzeba nagrać, sprawdzić jej odczyt i opisać numerem zdającego. Uwaga z klucza: przed oceną egzaminator usuwa pomiary dopisane przez stronę (DELETE FROM wagi WHERE id > 22), więc strona może dopisywać je do woli.

    przeglądarka.txt Tekst nowy plik
    Google Chrome

    Podgląd strony bez zmian - taki jak po kroku 47.

Podgląd

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: . 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.