Przejdź do głównej treści
EE.09-06-21.01-SGStyczeń 2021 · 42 kroki · ok. 77 min · 37 kryteriów z klucza

Rozwiązanie krok po kroku: Tablica odlotów z lotniska (Wersja podstawowa)

Aplikacja internetowa portu lotniczego - tablica odlotów: baza egzamin z tabelami odloty, samoloty i przyloty, cztery zapytania (sortowanie malejące, funkcja MIN w przedziale godzin, relacja JOIN i aktualizacja UPDATE), logotyp przeskalowany z zachowaniem przezroczystości oraz strona airport.php: dwa bloki banera, tablica odlotów wypełniana skryptem PHP z bazy i trzy bloki stopki, w których drugi skrypt na podstawie ciasteczka wita gościa przy pierwszej wizycie albo przy powrocie w ciągu godziny.

To arkusz EE.09 ze stycznia 2021 - kwalifikacji formuły 2017, którą zastąpiła INF.03. Jest pokrewny arkuszowi EE.09-05 z tej samej sesji (tablica przylotów, ta sama baza), ale ma inny podział strony, inne zapytania, ciasteczko na godzinę i odwrotne wyróżnienie komunikatów - ma własne rozwiązanie. Kroki idą zdanie po zdaniu za treścią arkusza; skrypty są najpierw napisane najprościej, funkcjami mysqli z tabeli 1 arkusza, a na końcu sprawdzone na prawdziwych błędach i zabezpieczone.

To jest wersja podstawowa. W zakładce „Nowoczesny kod (flex, PDO)” jest drugi sposób rozwiązania tego samego arkusza: znaczniki <header>, <main> i <footer> z układem flex, zmienne CSS, PDO z obsługą wyjątków i ciasteczko z flagami bezpieczeństwa - obie wersje są zgodne z kluczem.

Baza i grafika pochodzą z oryginalnego archiwum CKE z6.zip (załącznik na stronie arkusza, hasło w treści zadania). Zapytania i zrzuty są policzone na MariaDB 10.4 - tej samej, która jest w XAMPP. Podgląd od kroków z PHP to wynik prawdziwego uruchomienia kodu w PHP 8.2, także z ciasteczkiem zapamiętanym między dwoma wejściami na stronę.

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. 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: Folder zdającego i archiwum z6.zip

    ok. 2 min
    Polecenie z arkusza

    Aby wykonać zadanie, zaloguj się na konto Egzamin bez hasła. Na pulpicie znajdziesz archiwum ZIP o nazwie z6.zip zabezpieczone hasłem: @SaMolotY9% Archiwum należy rozpakować. Na pulpicie konta Egzamin utwórz folder. Jako nazwy folderu użyj swojego numeru PESEL. Umieść w tym folderze rozpakowane pliki.

    Na pulpicie tworzysz folder nazwany numerem PESEL - w tym rozwiązaniu w jego miejscu stoi imię i nazwisko autora, Bartosz Bryniarski. Archiwum z6.zip rozpakowujesz do tego folderu, podając hasło @SaMolotY9% (wielkość liter i znaki specjalne mają znaczenie). W środku są dwa pliki: egzamin.sql (baza do importu) i zad6.png (logotyp). Do tego folderu trafia wszystko, co powstanie.

    Typowe błędy

    Pliki zapisane poza folderem zdającego nie trafią na płytę - a ocenia się tylko to, co jest na płycie.

  2. Krok 2: XAMPP, baza egzamin i import egzamin.sql

    ok. 2 min
    Polecenie z arkusza

    Uruchom usługi MySQL i Apache za pomocą XAMPP Control Panel. Za pomocą narzędzia phpMyAdmin wykonaj podane operacje na bazie danych: Utwórz bazę danych o nazwie egzamin. Do bazy egzamin zaimportuj plik egzamin.sql z rozpakowanego archiwum

    W XAMPP Control Panel Start przy Apache i MySQL, w phpMyAdmin (http://localhost/phpmyadmin) Nowa → nazwa egzamin → Utwórz. Potem przy zaznaczonej bazie karta Import, plik egzamin.sql, Wykonaj. Do zadania potrzebne są trzy tabele z obrazu 1: odloty (10 lotów), przyloty (8) i samoloty (4); pole samoloty_id w tabelach lotów wskazuje id samolotu.

  3. Krok 3: Zrzut import.png

    Kryteria:

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

    ok. 2 min
    Polecenie z arkusza

    Wykonaj zrzut ekranu po imporcie. Zrzut zapisz w folderze z numerem PESEL, 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

    Karta Struktura bazy egzamin pokazuje listę tabel z liczbą rekordów - to „elementy wskazujące na poprawnie wykonany import”. Zrzut całego ekranu z paskiem zadań zapisujesz jako import.png.

    Typowe błędy

    Ten zrzut jest w PNG, zrzuty kwerend w JPG - zły format albo wykadrowany zrzut nie jest oceniany.

    Podgląd strony po tym kroku
    Podgląd strony po kroku 3
  4. Krok 4: Zapytanie 1: odloty od najpóźniejszego

    Kryteria: ,

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

    R.1.3 Utworzono zapytanie 1 wybierające jedynie pola id, nr_rejsu, czas, kierunek i status_lotu z tabeli odloty posortowane malejąco według czasu. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT id, nr_rejsu, czas, kierunek, status_lotu FROM odloty ORDER BY czas DESC; oraz wynik działania zapytania udokumentowano zrzutem, na którym jest widocznych dokładnie 10 rekordów, jedynie pola id, nr_rejsu, czas, kierunek, status_lotu. Rekordy są posortowane malejąco wg. czasu

    ok. 3 min
    Polecenie z arkusza

    Zapisz i wykonaj zapytania SQL działające na bazie egzamin. Zapytania zapisz w pliku kwerendy.txt, w folderze z numerem PESEL. Wykonaj zrzuty ekranu przedstawiające wyniki działania kwerend. Zrzuty zapisz w formacie JPG i nadaj im nazwy kw1, kw2, kw3, kw4. Zrzuty powinny obejmować cały ekran monitora z widocznym paskiem zadań. Zapytanie 1: wybierające jedynie pola id, nr_rejsu, czas, kierunek i status_lotu z tabeli odloty posortowane malejąco według czasu

    • SELECT id, nr_rejsu, czas, kierunek, status_lotu - „jedynie” te pięć pól, w kolejności kolumn tablicy na stronie (kolumna „lp.” to id),
    • FROM odloty,
    • ORDER BY czas DESC - DESC odwraca porządek: od najpóźniejszego odlotu.

    Wynik: 10 odlotów. Zapytanie wklejasz do kwerendy.txt, zrzut całego ekranu z wynikiem - kw1.jpg. To samo zapytanie wyśle skrypt 1.

    kwerendy.txt Tekst nowy plik
    -- Zapytanie 1
    SELECT id, nr_rejsu, czas, kierunek, status_lotu FROM odloty ORDER BY czas DESC;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 4
  5. Krok 5: Zapytanie 2: najwcześniejszy odlot między 10:10 a 10:19

    Kryteria:

    R.1.4 Utworzono zapytanie 2 wyznaczające najwcześniejszy (najmniejszy) czas odlotu dla lotów, których czas odlotu jest pomiędzy 10:10 – 10:19. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT MIN(czas) FROM odloty WHERE czas LIKE "10:1%"; możliwe również BETWEEN oraz wynik działania zapytania udokumentowano zrzutem, na którym jest widoczna jedynie wartość 10:13:00, wynikająca z zadanego zapytania

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 2: wyznaczające najwcześniejszy (najmniejszy) czas odlotu dla lotów, których czas odlotu jest pomiędzy 10:10 ÷ 10:19

    • SELECT MIN(czas) - funkcja agregująca zwraca najmniejszą wartość kolumny, czyli najwcześniejszą godzinę,
    • FROM odloty,
    • WHERE czas BETWEEN '10:10:00' AND '10:19:59' - oba końce przedziału wliczone; klucz przyjmuje też WHERE czas LIKE '10:1%'.

    Wynik: 10:13:00. Zrzut: kw2.jpg.

    Typowe błędy

    ORDER BY czas LIMIT 1 też znajdzie ten odlot, ale arkusz każe „wyznaczyć najmniejszy czas” - do tego służy funkcja MIN, której oczekuje klucz.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT id, nr_rejsu, czas, kierunek, status_lotu FROM odloty ORDER BY czas DESC;
    
    -- Zapytanie 2
    SELECT MIN(czas) FROM odloty WHERE czas BETWEEN '10:10:00' AND '10:19:59';
    Podgląd strony po tym kroku
    Podgląd strony po kroku 5
  6. Krok 6: Zapytanie 3: relacja odloty - samoloty

    Kryteria:

    R.1.5 Utworzono zapytanie 3 wybierające jedynie pola nr_rejsu z tabeli odloty oraz linie z tabeli samoloty dla lotów, dla których kierunkiem jest Malta. Zastosowano relację. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT nr_rejsu, samoloty.linie FROM odloty JOIN samoloty ON odloty.samoloty_id = samoloty.id WHERE kierunek = "Malta"; możliwe też INNER JOIN lub bez JOIN (porównanie kluczy w warunku) oraz wynik działania zapytania udokumentowano zrzutem, na którym widoczny jest dokładnie jeden rekord jedynie z danymi: LX5673, SWISS

    ok. 3 min
    Polecenie z arkusza

    Zapytanie 3: wybierające jedynie pola nr_rejsu z tabeli odloty oraz linie z tabeli samoloty, dla lotów których kierunkiem jest Malta; zapytanie wykorzystuje relację

    • SELECT nr_rejsu, linie - numer rejsu z tabeli odloty, linia lotnicza z tabeli samoloty,
    • FROM odloty JOIN samoloty ON odloty.samoloty_id = samoloty.id - relacja z obrazu 1,
    • WHERE kierunek = 'Malta'.

    Wynik: jeden wiersz - LX5673, SWISS. Zrzut: kw3.jpg.

    Typowe błędy

    Bez warunku ON baza łączy lot z każdym samolotem - wynik ma 4 wiersze zamiast jednego.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT id, nr_rejsu, czas, kierunek, status_lotu FROM odloty ORDER BY czas DESC;
    
    -- Zapytanie 2
    SELECT MIN(czas) FROM odloty WHERE czas BETWEEN '10:10:00' AND '10:19:59';
    
    -- Zapytanie 3
    SELECT nr_rejsu, linie FROM odloty JOIN samoloty ON odloty.samoloty_id = samoloty.id WHERE kierunek = 'Malta';
    Podgląd strony po tym kroku
    Podgląd strony po kroku 6
  7. Krok 7: Zapytanie 4: status przylotu LH9829

    Kryteria:

    R.1.6 Utworzono zapytanie 4 aktualizujące w tabeli przyloty pole status_lotu na: „planowy” dla lotu o numerze rejsu LH9829. W pliku z kwerendami lub na zrzucie istnieje zapis np.: UPDATE przyloty SET status_lotu="planowy" WHERE nr_rejsu="LH9829"; oraz wynik działania zapytania udokumentowano zrzutem, na którym widoczne jest poprawne zapytanie lub zmienione dane w tabeli

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 4: aktualizujące w tabeli przyloty pole status_lotu na: „planowy” dla lotu o numerze rejsu LH9829

    Uwaga na tabelę: ta jedyna kwerenda dotyczy przylotów. UPDATE przyloty → SET status_lotu = 'planowy' → WHERE nr_rejsu = 'LH9829' (przylot z Frankfurtu). phpMyAdmin odpowiada „1 wiersz zmieniony” - zrzut kw4.jpg. Tablica odlotów na stronie się nie zmienia.

    Typowe błędy

    UPDATE bez WHERE zmieniłby status wszystkich ośmiu przylotów.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT id, nr_rejsu, czas, kierunek, status_lotu FROM odloty ORDER BY czas DESC;
    
    -- Zapytanie 2
    SELECT MIN(czas) FROM odloty WHERE czas BETWEEN '10:10:00' AND '10:19:59';
    
    -- Zapytanie 3
    SELECT nr_rejsu, linie FROM odloty JOIN samoloty ON odloty.samoloty_id = samoloty.id WHERE kierunek = 'Malta';
    
    -- Zapytanie 4
    UPDATE przyloty SET status_lotu = 'planowy' WHERE nr_rejsu = 'LH9829';
    Podgląd strony po tym kroku
    Podgląd strony po kroku 7
  8. Etap 2: Grafika i strona HTML

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

    Krok 8: Grafika: wysokość 150 px z przezroczystością

    Kryteria:

    R.2.1 Plik zad6.png przeskalowano z zachowaniem proporcji do wysokości 150 px, odpowiadająca temu szerokość wynosi 371 px (± 5 px); przezroczystość została zachowana

    ok. 2 min
    Polecenie z arkusza

    Plik zad6.png, wypakowany z archiwum, należy przeskalować z zachowaniem proporcji tak, aby jego wysokość wynosiła dokładnie 150 px. Należy zachować przezroczystość obrazu

    Oryginał ma 640 × 259 px i przezroczyste tło. W GIMP-ie Obraz → Skaluj obraz z zamkniętym łańcuchem proporcji, wysokość 150 px - szerokość: 640 × 150 / 259 = 370,7, czyli 371 px (klucz: 371 ±5). Zapis jako PNG - tylko ten format z dwóch używanych na stronie przechowuje przezroczystość.

    Typowe błędy

    Eksport do JPG zamienia przezroczyste tło na białe - na pomarańczowym tle strony pojawi się biały prostokąt.

    Podgląd strony po tym kroku
    Podgląd strony po kroku 8
  9. Krok 9: Plik airport.php

    ok. 1 min
    Polecenie z arkusza

    Składa się ze strony o nazwie airport.php

    Plik airport.php w folderze zdającego, obok zad6.png. Rozszerzenie .php, bo dojdą skrypty - na razie to czysty HTML. <!DOCTYPE html> oznacza HTML5, a lang="pl" mówi przeglądarce i czytnikom ekranu, że treść jest po polsku (arkusz tego nie wymaga).

    airport.php PHP nowy plik
    <!DOCTYPE html>
    <html lang="pl">
    <head>
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (airport.php)
  10. Krok 10: Kodowanie polskich znaków

    Kryteria:

    R.2.2 Witrynę internetową zapisano w pliku PHP o nazwie airport oraz zastosowano właściwy standard kodowania polskich znaków

    ok. 1 min
    Polecenie z arkusza

    Zastosowany właściwy standard kodowania polskich znaków

    <meta charset="UTF-8"> jako pierwsza rzecz w <head>, a plik zapisany w UTF-8 (w Notepad++ menu Kodowanie). Klucz ocenia nazwę pliku i kodowanie razem (R.2.2) - airport.html albo lotnisko.php to strata punktu.

    airport.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 (airport.php)
  11. Krok 11: Tytuł strony

    Kryteria:

    R.2.3 Nadano tytuł strony: "Odloty samolotów”

    ok. 1 min
    Polecenie z arkusza

    Tytuł strony widoczny na karcie przeglądarki: „Odloty samolotów”

    <title> w <head> - napis na karcie przeglądarki, z polskimi literami.

    airport.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Odloty samolotów</title>
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (airport.php)
  12. Krok 12: Podpięcie arkusza stylów styl6.css

    Kryteria:

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

    ok. 1 min
    Polecenie z arkusza

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

    <link rel="stylesheet" href="styl6.css"> w <head>. Plik stylów powstanie po HTML-u.

    Typowe błędy

    Klucz uznaje R.3.4 tylko wtedy, gdy wszystkie selektory trafiają w bloki - kropka zamiast # odbiera punkt.

    airport.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Odloty samolotów</title>
        <link rel="stylesheet" href="styl6.css">
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (airport.php)
  13. Krok 13: Sześć bloków: dwa banera, główny, trzy stopki

    Kryteria:

    R.2.4 Wygląd strony zdefiniowano dzieląc ją na bloki: dwa bloki banera, blok główny, trzy bloki stopki. Zastosowano znaczniki sekcji

    ok. 2 min
    Polecenie z arkusza

    Podział strony na bloki: dwa bloki banera, poniżej blok główny, następnie trzy bloki stopki. Podział zrealizowany za pomocą znaczników sekcji, zgodnie z obrazem 2

    Sześć znaczników <section> w kolejności z obrazu 2, każdy z identyfikatorem (nazwy po angielsku - arkusz ich nie narzuca): bloki banera title i logo, blok główny main, bloki stopki download (odnośnik do zrzutu), status (komunikat skryptu 2) i author. Obok siebie ustawi je CSS.

    airport.php PHP zmienione: 12 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Odloty samolotów</title>
        <link rel="stylesheet" href="styl6.css">
    </head>
    <body>
        <section id="title">
        </section>
        <section id="logo">
        </section>
        <section id="main">
        </section>
        <section id="download">
        </section>
        <section id="status">
        </section>
        <section id="author">
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (airport.php)
  14. Krok 14: Pierwszy blok banera: nagłówek „Odloty z lotniska”

    ok. 1 min
    Polecenie z arkusza

    Zawartość pierwszego bloku banera: nagłówek drugiego stopnia o treści „Odloty z lotniska”

    Drugiego stopnia to <h2>. Na tej stronie nie ma <h1> - poziomy nagłówków narzuca arkusz.

    airport.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Odloty samolotów</title>
        <link rel="stylesheet" href="styl6.css">
    </head>
    <body>
        <section id="title">
            <h2>Odloty z lotniska</h2>
        </section>
        <section id="logo">
        </section>
        <section id="main">
        </section>
        <section id="download">
        </section>
        <section id="status">
        </section>
        <section id="author">
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (airport.php)
  15. Krok 15: Drugi blok banera: logotyp

    Kryteria:

    R.2.6 W drugim bloku banera umieszczono obraz zad6.png z tekstem alternatywnym: "logotyp", gdy obraz nie istnieje powinien wyświetlać się tekst alternatywny

    ok. 1 min
    Polecenie z arkusza

    Zawartość drugiego bloku banera: obraz zad6.png z tekstem alternatywnym „logotyp”

    <img> z przeskalowanym plikiem i atrybutem alt - tekstem, który zobaczy gość, gdy obraz się nie wczyta, i który przeczyta czytnik ekranu.

    airport.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Odloty samolotów</title>
        <link rel="stylesheet" href="styl6.css">
    </head>
    <body>
        <section id="title">
            <h2>Odloty z lotniska</h2>
        </section>
        <section id="logo">
            <img src="zad6.png" alt="logotyp">
        </section>
        <section id="main">
        </section>
        <section id="download">
        </section>
        <section id="status">
        </section>
        <section id="author">
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (airport.php)
  16. Krok 16: Blok główny: nagłówek „tabela odlotów”

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku głównego: Nagłówek czwartego stopnia o treści: „tabela odlotów”

    Czwartego stopnia to <h4>. Tekst małymi literami, jak w arkuszu - wielkie litery z obrazu 2 da CSS.

    airport.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Odloty samolotów</title>
        <link rel="stylesheet" href="styl6.css">
    </head>
    <body>
        <section id="title">
            <h2>Odloty z lotniska</h2>
        </section>
        <section id="logo">
            <img src="zad6.png" alt="logotyp">
        </section>
        <section id="main">
            <h4>tabela odlotów</h4>
        </section>
        <section id="download">
        </section>
        <section id="status">
        </section>
        <section id="author">
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (airport.php)
  17. Krok 17: Tabela z wierszem nagłówkowym

    Kryteria:

    R.2.8 Umieszczono w tabeli wiersz nagłówkowy, zastosowano pięć znaczników <th> (opcjonalnie <thead> i <td>) oraz ich zamknięcia wewnątrz pierwszego wiersza tabeli

    ok. 2 min
    Polecenie z arkusza

    Tabela o pięciu kolumnach. Nagłówki kolumn mają podpisy: „lp.”, „numer rejsu”, „czas”, „kierunek”, „status”

    <table> z pierwszym wierszem <tr> i pięcioma komórkami nagłówkowymi <th>. Kolejność kolumn jest taka jak pól w zapytaniu 1 (id, nr_rejsu, czas, kierunek, status_lotu) - kolumnę „lp.” wypełni pole id. Kolejne wiersze („Zawartość tabeli jest wypełniana skryptem 1”) wstawi skrypt przed </table>.

    airport.php PHP zmienione: 9 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Odloty samolotów</title>
        <link rel="stylesheet" href="styl6.css">
    </head>
    <body>
        <section id="title">
            <h2>Odloty z lotniska</h2>
        </section>
        <section id="logo">
            <img src="zad6.png" alt="logotyp">
        </section>
        <section id="main">
            <h4>tabela odlotów</h4>
            <table>
                <tr>
                    <th>lp.</th>
                    <th>numer rejsu</th>
                    <th>czas</th>
                    <th>kierunek</th>
                    <th>status</th>
                </tr>
            </table>
        </section>
        <section id="download">
        </section>
        <section id="status">
        </section>
        <section id="author">
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (airport.php)
  18. Krok 18: Pierwszy blok stopki: odnośnik do kw1.jpg

    Kryteria: ,

    R.3.2 Na stronie umieszczono odnośnik, którego wybranie prowadzi do dowolnego pliku ze zrzutem

    R.3.3 Odnośnik otwiera się w nowym oknie / karcie przeglądarki

    ok. 1 min
    Polecenie z arkusza

    Zawartość pierwszego bloku stopki: Odnośnik o treści „Pobierz obraz” otwierający plik kw1.jpg w nowym oknie

    <a href="kw1.jpg"> prowadzi do zrzutu wyniku zapytania 1 z tego samego folderu (R.3.2), a target="_blank" otwiera go w nowym oknie albo karcie (R.3.3).

    airport.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Odloty samolotów</title>
        <link rel="stylesheet" href="styl6.css">
    </head>
    <body>
        <section id="title">
            <h2>Odloty z lotniska</h2>
        </section>
        <section id="logo">
            <img src="zad6.png" alt="logotyp">
        </section>
        <section id="main">
            <h4>tabela odlotów</h4>
            <table>
                <tr>
                    <th>lp.</th>
                    <th>numer rejsu</th>
                    <th>czas</th>
                    <th>kierunek</th>
                    <th>status</th>
                </tr>
            </table>
        </section>
        <section id="download">
            <a href="kw1.jpg" target="_blank">Pobierz obraz</a>
        </section>
        <section id="status">
        </section>
        <section id="author">
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (airport.php)
  19. Krok 19: Trzeci blok stopki: autor

    ok. 1 min
    Polecenie z arkusza

    Zawartość trzeciego bloku stopki: tekst: „Autor: ”, dalej wstawiony numer PESEL zdającego

    Na egzaminie po „Autor: ” wpisujesz swój numer PESEL. W tym rozwiązaniu w jego miejscu stoi imię i nazwisko autora: Bartosz Bryniarski. Drugi blok stopki zostaje pusty - wypełni go skrypt 2.

    airport.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Odloty samolotów</title>
        <link rel="stylesheet" href="styl6.css">
    </head>
    <body>
        <section id="title">
            <h2>Odloty z lotniska</h2>
        </section>
        <section id="logo">
            <img src="zad6.png" alt="logotyp">
        </section>
        <section id="main">
            <h4>tabela odlotów</h4>
            <table>
                <tr>
                    <th>lp.</th>
                    <th>numer rejsu</th>
                    <th>czas</th>
                    <th>kierunek</th>
                    <th>status</th>
                </tr>
            </table>
        </section>
        <section id="download">
            <a href="kw1.jpg" target="_blank">Pobierz obraz</a>
        </section>
        <section id="status">
        </section>
        <section id="author">
            Autor: Bartosz Bryniarski
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (airport.php)
  20. Etap 3: Styl CSS

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

    Krok 20: Plik styl6.css: pierwszy blok banera

    ok. 1 min
    Polecenie z arkusza

    Cechy formatowania CSS: Dla pierwszego bloku banera: wyrównanie tekstu do środka, szerokość 75%, wysokość 150 px, rozmiar czcionki 200%

    Nowy plik styl6.css w folderze zdającego - od teraz każda reguła trafia tutaj. Selektor identyfikatora z krzyżykiem #title. font-size: 200% liczy się od czcionki rodzica, a nagłówek <h2> jest jeszcze półtora raza większy od tekstu swojego bloku.

    styl6.css CSS nowy plik
    #title {
        text-align: center;
        width: 75%;
        height: 150px;
        font-size: 200%;
    }
    Podgląd strony po tym kroku (airport.php)
  21. Krok 21: Drugi blok banera

    Kryteria:

    R.4.4 Ustawiono wysokość wszystkich bloków banera na 150px

    ok. 1 min
    Polecenie z arkusza

    Dla drugiego bloku banera: szerokość 25%, wysokość 150 px

    Szerokości banera sumują się do 100% (75 + 25), oba bloki mają 150 px - tyle co logotyp (R.4.4). Logotyp ma 371 px szerokości, więc mieści się w bloku 25% dopiero w oknie szerszym niż ok. 1500 px (na monitorze Full HD); w węższym oknie wystaje poza blok - tak wynika z wymiarów podanych w arkuszu.

    styl6.css CSS zmienione: 4 linie
    #title {
        text-align: center;
        width: 75%;
        height: 150px;
        font-size: 200%;
    }
    #logo {
        width: 25%;
        height: 150px;
    }
    Podgląd strony po tym kroku (airport.php)
  22. Krok 22: Blok główny: tło, marginesy wewnętrzne, wielkie litery

    ok. 1 min
    Polecenie z arkusza

    Dla bloku głównego: tło koloru RGB 128, 0, 0; marginesy wewnętrzne 50 px, tekst wielkimi literami (niezależnie od tego jak tekst został zapisany w HTML, wymagana transformacja na wielkie litery)

    rgb(128, 0, 0) to ciemna czerwień (#800000, nazwa maroon). text-transform: uppercase zmienia tylko wygląd - nagłówek, podpisy kolumn i dane z bazy wyświetlą się wielkimi literami, choć zapisane są małymi.

    styl6.css CSS zmienione: 5 linii
    #title {
        text-align: center;
        width: 75%;
        height: 150px;
        font-size: 200%;
    }
    #logo {
        width: 25%;
        height: 150px;
    }
    #main {
        background-color: rgb(128, 0, 0);
        padding: 50px;
        text-transform: uppercase;
    }
    Podgląd strony po tym kroku (airport.php)
  23. Krok 23: Pierwszy i trzeci blok stopki

    ok. 1 min
    Polecenie z arkusza

    Dla pierwszego i trzeciego bloku stopki: szerokość 20%, margines wewnętrzny górny: 90 px (tylko górny)

    Wspólna reguła dla dwóch bloków. „Tylko górny” to padding-top - margines od góry nie zmienia szerokości bloku, więc trzy bloki stopki zmieszczą się w rzędzie (20 + 60 + 20). Dzięki niemu odnośnik i autor stoją na wysokości dołu paragrafu ze środkowego bloku.

    styl6.css CSS zmienione: 4 linie
    #title {
        text-align: center;
        width: 75%;
        height: 150px;
        font-size: 200%;
    }
    #logo {
        width: 25%;
        height: 150px;
    }
    #main {
        background-color: rgb(128, 0, 0);
        padding: 50px;
        text-transform: uppercase;
    }
    #download, #author {
        width: 20%;
        padding-top: 90px;
    }
    Podgląd strony po tym kroku (airport.php)
  24. Krok 24: Drugi blok stopki

    Kryteria:

    R.4.6 Ustawiono wyrównanie tekstu do środka dla pierwszego bloku banera i drugiego bloku stopki

    ok. 1 min
    Polecenie z arkusza

    Dla drugiego bloku stopki: wyrównanie tekstu do środka, szerokość 60%

    Blok #status, w którym skrypt 2 wypisze komunikat. Wyrównania tekstu do środka są gotowe (R.4.6).

    styl6.css CSS zmienione: 4 linie
    #title {
        text-align: center;
        width: 75%;
        height: 150px;
        font-size: 200%;
    }
    #logo {
        width: 25%;
        height: 150px;
    }
    #main {
        background-color: rgb(128, 0, 0);
        padding: 50px;
        text-transform: uppercase;
    }
    #download, #author {
        width: 20%;
        padding-top: 90px;
    }
    #status {
        text-align: center;
        width: 60%;
    }
    Podgląd strony po tym kroku (airport.php)
  25. Krok 25: Selektor body: krój, tło, biały tekst

    Kryteria: , ,

    R.4.1 Ustawiono krój czcionki Arial dla selektora body lub kontenera całej strony

    R.4.2 Ustawiono kolor tła rgb(244, 164, 96) dla selektora body lub kontenera całej strony, oraz kolor tła rgb(128, 0, 0) dla bloku głównego

    R.4.3 Ustawiono biały kolor czcionki dla selektora body lub kontenera całej strony

    ok. 1 min
    Polecenie z arkusza

    Dla selektora body: krój czcionki Arial, kolor tła RGB 244, 164, 96; biały kolor czcionki

    Reguła body na początku pliku - dziedziczą ją wszystkie bloki. rgb(244, 164, 96) to piaskowy pomarańcz (#F4A460, nazwa sandybrown), tekst biały. Tło bloku głównego już jest, więc R.4.2 ma oba kolory.

    styl6.css CSS zmienione: 5 linii
    body {
        font-family: Arial;
        background-color: rgb(244, 164, 96);
        color: white;
    }
    #title {
        text-align: center;
        width: 75%;
        height: 150px;
        font-size: 200%;
    }
    #logo {
        width: 25%;
        height: 150px;
    }
    #main {
        background-color: rgb(128, 0, 0);
        padding: 50px;
        text-transform: uppercase;
    }
    #download, #author {
        width: 20%;
        padding-top: 90px;
    }
    #status {
        text-align: center;
        width: 60%;
    }
    Podgląd strony po tym kroku (airport.php)
  26. Krok 26: Paragraf: czcionka i obramowanie

    Kryteria:

    R.4.10 Ustawiono rozmiar czcionki 200% dla pierwszego bloku banera, 150% dla selektora p oraz tekst wielkimi literami (text-transform: uppercase;) dla bloku głównego

    ok. 1 min
    Polecenie z arkusza

    Dla selektora paragrafu (akapitu): rozmiar czcionki 150%, obramowanie 2 px, linią kropkowaną koloru RGB 169, 169, 169

    „Linia kropkowana” to dotted (dashed to kreski). rgb(169, 169, 169) to szary (#A9A9A9, darkgray). Rozmiary czcionek i wielkie litery bloku głównego są gotowe (R.4.10).

    styl6.css CSS zmienione: 4 linie
    body {
        font-family: Arial;
        background-color: rgb(244, 164, 96);
        color: white;
    }
    #title {
        text-align: center;
        width: 75%;
        height: 150px;
        font-size: 200%;
    }
    #logo {
        width: 25%;
        height: 150px;
    }
    #main {
        background-color: rgb(128, 0, 0);
        padding: 50px;
        text-transform: uppercase;
    }
    #download, #author {
        width: 20%;
        padding-top: 90px;
    }
    #status {
        text-align: center;
        width: 60%;
    }
    p {
        font-size: 150%;
        border: 2px dotted rgb(169, 169, 169);
    }
    Podgląd strony po tym kroku (airport.php)
  27. Krok 27: Paragraf po najechaniu kursorem

    Kryteria:

    R.4.9 W momencie najechania kursorem na paragraf, kolor jego tła zmienia się na rgb(169, 169, 169) np. hover

    ok. 1 min
    Polecenie z arkusza

    W momencie najechania kursorem na paragraf, jego kolor tła zmienia się na RGB 169, 169, 169

    Pseudoklasa :hover - reguła działa tylko wtedy, gdy kursor jest nad paragrafem.

    styl6.css CSS zmienione: 3 linie
    body {
        font-family: Arial;
        background-color: rgb(244, 164, 96);
        color: white;
    }
    #title {
        text-align: center;
        width: 75%;
        height: 150px;
        font-size: 200%;
    }
    #logo {
        width: 25%;
        height: 150px;
    }
    #main {
        background-color: rgb(128, 0, 0);
        padding: 50px;
        text-transform: uppercase;
    }
    #download, #author {
        width: 20%;
        padding-top: 90px;
    }
    #status {
        text-align: center;
        width: 60%;
    }
    p {
        font-size: 150%;
        border: 2px dotted rgb(169, 169, 169);
    }
    p:hover {
        background-color: rgb(169, 169, 169);
    }
    Podgląd strony po tym kroku (airport.php)
  28. Krok 28: Tabela: szerokość i połączone obramowanie

    Kryteria:

    R.4.5 Ustawiono szerokość pierwszego bloku banera 75%, drugiego bloku banera na 25%, drugiego bloku stopki 60%, pierwszego i trzeciego bloku stopki 20% oraz szerokość tabeli na 100%

    ok. 1 min
    Polecenie z arkusza

    Dla selektora tabeli: szerokość 100%, obramowanie tabeli i komórki ma być połączone (collapse)

    Tabela na całą szerokość bloku głównego, border-collapse: collapse - jedna wspólna linia między sąsiednimi komórkami. Szerokości wszystkich bloków i tabeli są gotowe (R.4.5).

    styl6.css CSS zmienione: 4 linie
    body {
        font-family: Arial;
        background-color: rgb(244, 164, 96);
        color: white;
    }
    #title {
        text-align: center;
        width: 75%;
        height: 150px;
        font-size: 200%;
    }
    #logo {
        width: 25%;
        height: 150px;
    }
    #main {
        background-color: rgb(128, 0, 0);
        padding: 50px;
        text-transform: uppercase;
    }
    #download, #author {
        width: 20%;
        padding-top: 90px;
    }
    #status {
        text-align: center;
        width: 60%;
    }
    p {
        font-size: 150%;
        border: 2px dotted rgb(169, 169, 169);
    }
    p:hover {
        background-color: rgb(169, 169, 169);
    }
    table {
        width: 100%;
        border-collapse: collapse;
    }
    Podgląd strony po tym kroku (airport.php)
  29. Krok 29: Komórki tabeli: obramowanie i marginesy

    Kryteria: ,

    R.4.7 Ustawiono marginesy wewnętrzne (padding): 50px dla bloku głównego, 5px dla selektora td lub th oraz jedynie margines wewnętrzny górny (padding-top) 90px dla pierwszego i trzeciego bloku stopki

    R.4.8 Ustawiono obramowanie selektora p 2px linią kropkowaną koloru rgb(169, 169, 169); dla td lub th: 1px linią ciągłą rgb(192, 192, 192) oraz połączone obramowanie dla selektora tabeli (border-collapse: collapse;)

    ok. 1 min
    Polecenie z arkusza

    Dla selektora komórki danych i komórki nagłówkowej tabeli: obramowanie 1 px, linią ciągłą o kolorze RGB 192, 192, 192; marginesy wewnętrzne 5 px

    Jedna reguła dla td i th: linia ciągła (solid) w kolorze jasnoszarym (#C0C0C0) i 5 px marginesu wewnętrznego. Obramowania (R.4.8) i marginesy wewnętrzne (R.4.7) są gotowe.

    styl6.css CSS zmienione: 4 linie
    body {
        font-family: Arial;
        background-color: rgb(244, 164, 96);
        color: white;
    }
    #title {
        text-align: center;
        width: 75%;
        height: 150px;
        font-size: 200%;
    }
    #logo {
        width: 25%;
        height: 150px;
    }
    #main {
        background-color: rgb(128, 0, 0);
        padding: 50px;
        text-transform: uppercase;
    }
    #download, #author {
        width: 20%;
        padding-top: 90px;
    }
    #status {
        text-align: center;
        width: 60%;
    }
    p {
        font-size: 150%;
        border: 2px dotted rgb(169, 169, 169);
    }
    p:hover {
        background-color: rgb(169, 169, 169);
    }
    table {
        width: 100%;
        border-collapse: collapse;
    }
    td, th {
        border: 1px solid rgb(192, 192, 192);
        padding: 5px;
    }
    Podgląd strony po tym kroku (airport.php)
  30. Krok 30: Układ bloków zgodny z obrazem 2

    Kryteria:

    R.3.1 Wygląd układu bloków po uruchomieniu strony w przeglądarce jest w pełni zgodny z obrazem 2 w arkuszu egzaminacyjnym

    ok. 3 min
    Polecenie z arkusza

    Podział strony na bloki: dwa bloki banera, poniżej blok główny, następnie trzy bloki stopki. Podział zrealizowany za pomocą znaczników sekcji, zgodnie z obrazem 2

    Pięć bloków o zadanej szerokości dostaje float: left: dwa bloki banera stają w jednym rzędzie (75% + 25%), trzy bloki stopki w drugim (20% + 60% + 20%). Blok główny ma clear: both - zaczyna się pod banerem i zajmuje całą szerokość, a bloki stopki ustawiają się pod nim. Klucz R.3.1 ocenia wygląd w przeglądarce - wersja nowoczesna pokazuje ten sam układ na flex.

    Typowe błędy

    Bloki o sumie szerokości 100% nie mogą mieć bocznych marginesów ani obramowań - ostatni blok rzędu spadłby niżej. Dlatego bloki stopki mają wyłącznie padding-top.

    styl6.css CSS zmienione: 6 linii
    body {
        font-family: Arial;
        background-color: rgb(244, 164, 96);
        color: white;
    }
    #title {
        text-align: center;
        width: 75%;
        height: 150px;
        font-size: 200%;
    }
    #logo {
        width: 25%;
        height: 150px;
    }
    #main {
        background-color: rgb(128, 0, 0);
        padding: 50px;
        text-transform: uppercase;
    }
    #download, #author {
        width: 20%;
        padding-top: 90px;
    }
    #status {
        text-align: center;
        width: 60%;
    }
    p {
        font-size: 150%;
        border: 2px dotted rgb(169, 169, 169);
    }
    p:hover {
        background-color: rgb(169, 169, 169);
    }
    table {
        width: 100%;
        border-collapse: collapse;
    }
    td, th {
        border: 1px solid rgb(192, 192, 192);
        padding: 5px;
    }
    #title, #logo, #download, #status, #author {
        float: left;
    }
    #main {
        clear: both;
    }
    Podgląd strony po tym kroku (airport.php)
  31. Etap 4: Skrypt PHP

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

    Krok 31: Skrypt 1: połączenie z bazą egzamin

    Kryteria: ,

    R.5.1 Skrypt napisano w języku PHP i zawiera on co najmniej jedną instrukcję poprawną składniowo

    R.5.2 Skrypt1 realizuje połączenie z serwerem bazy danych i wybór bazy egzamin

    ok. 3 min
    Polecenie z arkusza

    Oba skrypty napisane w języku PHP, w pliku airport.php. Działanie skryptu 1: Skrypt łączy się z serwerem bazodanowym na localhost, użytkownik root bez hasła, baza danych o nazwie egzamin

    Skrypt 1 wypełnia tabelę, więc jego blok PHP stoi wewnątrz <table>, zaraz pod wierszem nagłówkowym - to, co wypisze, trafi dokładnie tam. Kod piszesz między <?php a ?>; serwer wykona go, zanim strona trafi do przeglądarki.

    Pierwsza instrukcja: mysqli_connect z tabeli 1 arkusza - serwer localhost, użytkownik root, puste hasło '' i baza egzamin (połączenie i wybór bazy w jednej funkcji, R.5.1, R.5.2). Połączenie trafia do zmiennej $connection.

    Od tego kroku podgląd to wynik działania strony na serwerze (prawdziwe uruchomienie w PHP 8.2). Stronę sprawdzasz przez http://localhost/… - przeglądarka sama nie wykona PHP.

    airport.php PHP zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Odloty samolotów</title>
        <link rel="stylesheet" href="styl6.css">
    </head>
    <body>
        <section id="title">
            <h2>Odloty z lotniska</h2>
        </section>
        <section id="logo">
            <img src="zad6.png" alt="logotyp">
        </section>
        <section id="main">
            <h4>tabela odlotów</h4>
            <table>
                <tr>
                    <th>lp.</th>
                    <th>numer rejsu</th>
                    <th>czas</th>
                    <th>kierunek</th>
                    <th>status</th>
                </tr>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'egzamin');
    ?>
            </table>
        </section>
        <section id="download">
            <a href="kw1.jpg" target="_blank">Pobierz obraz</a>
        </section>
        <section id="status">
        </section>
        <section id="author">
            Autor: Bartosz Bryniarski
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (airport.php)
  32. Krok 32: Skrypt 1: zapytanie 1

    Kryteria:

    R.5.4 Skrypt 1 wysyła do bazy zapytanie nr 1

    ok. 2 min
    Polecenie z arkusza

    Skrypt wysyła do bazy danych zapytanie 1

    mysqli_query wysyła zapytanie 1 przepisane z kwerendy.txt (R.5.4). Wynik - dziesięć wierszy - trafia do zmiennej $result; trzeba je jeszcze z niego pobrać.

    airport.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Odloty samolotów</title>
        <link rel="stylesheet" href="styl6.css">
    </head>
    <body>
        <section id="title">
            <h2>Odloty z lotniska</h2>
        </section>
        <section id="logo">
            <img src="zad6.png" alt="logotyp">
        </section>
        <section id="main">
            <h4>tabela odlotów</h4>
            <table>
                <tr>
                    <th>lp.</th>
                    <th>numer rejsu</th>
                    <th>czas</th>
                    <th>kierunek</th>
                    <th>status</th>
                </tr>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'egzamin');
    $result = mysqli_query($connection, 'SELECT id, nr_rejsu, czas, kierunek, status_lotu FROM odloty ORDER BY czas DESC;');
    ?>
            </table>
        </section>
        <section id="download">
            <a href="kw1.jpg" target="_blank">Pobierz obraz</a>
        </section>
        <section id="status">
        </section>
        <section id="author">
            Autor: Bartosz Bryniarski
        </section>
    </body>
    </html>

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

  33. Krok 33: Skrypt 1: pętla po wierszach i pierwsza komórka

    ok. 3 min
    Polecenie z arkusza

    Dane otrzymane z bazy są umieszczane w kolejnych wierszach tabeli, w odpowiednich komórkach, tak jak na Obrazie 2

    • mysqli_fetch_row($result) pobiera kolejny wiersz wyniku jako tablicę numerowaną od zera: $row[0] to id, $row[1] numer rejsu, $row[2] czas, $row[3] kierunek, $row[4] status,
    • while powtarza to, dopóki funkcja zwraca wiersz,
    • echo wypisuje wiersz <tr> z pierwszą komórką <td> - w napisie w cudzysłowie "…" PHP podstawia wartość $row[0], a \n kończy linię w źródle strony.

    Podgląd: dziesięć wierszy z samą liczbą porządkową - kolejne kolumny dojdą w następnym kroku.

    airport.php PHP zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Odloty samolotów</title>
        <link rel="stylesheet" href="styl6.css">
    </head>
    <body>
        <section id="title">
            <h2>Odloty z lotniska</h2>
        </section>
        <section id="logo">
            <img src="zad6.png" alt="logotyp">
        </section>
        <section id="main">
            <h4>tabela odlotów</h4>
            <table>
                <tr>
                    <th>lp.</th>
                    <th>numer rejsu</th>
                    <th>czas</th>
                    <th>kierunek</th>
                    <th>status</th>
                </tr>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'egzamin');
    $result = mysqli_query($connection, 'SELECT id, nr_rejsu, czas, kierunek, status_lotu FROM odloty ORDER BY czas DESC;');
    while ($row = mysqli_fetch_row($result)) {
        echo "            <tr><td>$row[0]</td></tr>\n";
    }
    ?>
            </table>
        </section>
        <section id="download">
            <a href="kw1.jpg" target="_blank">Pobierz obraz</a>
        </section>
        <section id="status">
        </section>
        <section id="author">
            Autor: Bartosz Bryniarski
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (airport.php)
  34. Krok 34: Skrypt 1: komplet komórek w wierszu

    Kryteria: ,

    R.2.7 W bloku głównym umieszczono tabelę o pięciu kolumnach, zastosowano znaczniki <table>, <tr>, <td> i ich zamknięcia, generowane skryptem lub HTML

    R.5.5 Dane otrzymane z bazy są wyświetlane w kolejnych wierszach tabeli, w odpowiednich komórkach, tak jak na Obrazie 2

    ok. 2 min
    Polecenie z arkusza

    Dane otrzymane z bazy są umieszczane w kolejnych wierszach tabeli, w odpowiednich komórkach, tak jak na Obrazie 2

    Do wiersza dochodzą cztery kolejne komórki. Każdy wiersz ma teraz pięć komórek <td> pod pięcioma nagłówkami (R.2.7), a dane stoją w odpowiednich kolumnach, od najpóźniejszego odlotu - jak na obrazie 2 (R.5.5).

    airport.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Odloty samolotów</title>
        <link rel="stylesheet" href="styl6.css">
    </head>
    <body>
        <section id="title">
            <h2>Odloty z lotniska</h2>
        </section>
        <section id="logo">
            <img src="zad6.png" alt="logotyp">
        </section>
        <section id="main">
            <h4>tabela odlotów</h4>
            <table>
                <tr>
                    <th>lp.</th>
                    <th>numer rejsu</th>
                    <th>czas</th>
                    <th>kierunek</th>
                    <th>status</th>
                </tr>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'egzamin');
    $result = mysqli_query($connection, 'SELECT id, nr_rejsu, czas, kierunek, status_lotu FROM odloty ORDER BY czas DESC;');
    while ($row = mysqli_fetch_row($result)) {
        echo "            <tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td><td>$row[3]</td><td>$row[4]</td></tr>\n";
    }
    ?>
            </table>
        </section>
        <section id="download">
            <a href="kw1.jpg" target="_blank">Pobierz obraz</a>
        </section>
        <section id="status">
        </section>
        <section id="author">
            Autor: Bartosz Bryniarski
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (airport.php)
  35. Krok 35: Skrypt 1: zamknięcie połączenia

    Kryteria:

    R.5.3 Po wykonaniu operacji na bazie zastosowano funkcję zamknięcia bazy

    ok. 1 min
    Polecenie z arkusza

    Po wykonaniu operacji na bazie skrypt zamyka połączenie z serwerem

    mysqli_close($connection) po pętli - wszystkie wiersze są już wypisane (R.5.3).

    Typowe błędy

    mysqli_close przed pętlą zamknie połączenie, zanim wiersze zostaną pobrane.

    airport.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Odloty samolotów</title>
        <link rel="stylesheet" href="styl6.css">
    </head>
    <body>
        <section id="title">
            <h2>Odloty z lotniska</h2>
        </section>
        <section id="logo">
            <img src="zad6.png" alt="logotyp">
        </section>
        <section id="main">
            <h4>tabela odlotów</h4>
            <table>
                <tr>
                    <th>lp.</th>
                    <th>numer rejsu</th>
                    <th>czas</th>
                    <th>kierunek</th>
                    <th>status</th>
                </tr>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'egzamin');
    $result = mysqli_query($connection, 'SELECT id, nr_rejsu, czas, kierunek, status_lotu FROM odloty ORDER BY czas DESC;');
    while ($row = mysqli_fetch_row($result)) {
        echo "            <tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td><td>$row[3]</td><td>$row[4]</td></tr>\n";
    }
    mysqli_close($connection);
    ?>
            </table>
        </section>
        <section id="download">
            <a href="kw1.jpg" target="_blank">Pobierz obraz</a>
        </section>
        <section id="status">
        </section>
        <section id="author">
            Autor: Bartosz Bryniarski
        </section>
    </body>
    </html>

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

  36. Krok 36: Skrypt 2: ciasteczko na godzinę

    Kryteria:

    R.5.7 Gdy odwiedzający jest na stronie pierwszy raz zakładane jest ciasteczko z czasem trwania 1 godzina od utworzenia, np. time() + 3600

    ok. 3 min
    Polecenie z arkusza

    Działanie skryptu 2: W oparciu o mechanizm ciasteczek skrypt wypisuje na stronie komunikaty: Gdy odwiedzający wejdzie na stronę pierwszy raz zakładane jest ciasteczko z czasem trwania 1 godzina od utworzenia oraz wyświetlany jest w paragrafie, czcionką pochyloną, komunikat: „Dzień dobry! Sprawdź regulamin naszej strony”

    Ciasteczko to porcja danych zapisana przez serwer w przeglądarce, którą przeglądarka odsyła przy każdym kolejnym wejściu - w PHP przysłane ciasteczka są w tablicy $_COOKIE.

    • isset($_COOKIE['odloty']) - prawdziwe, gdy gość już tu był; wykrzyknik ! odwraca warunek, więc blok wykona się przy pierwszej wizycie,
    • setcookie('odloty', 'odwiedzono', time() + 3600) - nazwa, wartość i czas wygaśnięcia: bieżący czas w sekundach plus godzina, czyli 60 × 60 = 3600 sekund (R.5.7).

    Blok stoi na samej górze pliku, przed <!DOCTYPE html>: opis setcookie na ostatniej stronie arkusza mówi, że ciasteczko trzeba wysłać przed jakąkolwiek treścią strony. Komunikaty wypisze drugi blok, w stopce.

    Typowe błędy

    time() + 60 to minuta, nie godzina - czas w setcookie podaje się w sekundach.

    airport.php PHP zmienione: 5 linii
    <?php
    if (!isset($_COOKIE['odloty'])) {
        setcookie('odloty', 'odwiedzono', time() + 3600);
    }
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Odloty samolotów</title>
        <link rel="stylesheet" href="styl6.css">
    </head>
    <body>
        <section id="title">
            <h2>Odloty z lotniska</h2>
        </section>
        <section id="logo">
            <img src="zad6.png" alt="logotyp">
        </section>
        <section id="main">
            <h4>tabela odlotów</h4>
            <table>
                <tr>
                    <th>lp.</th>
                    <th>numer rejsu</th>
                    <th>czas</th>
                    <th>kierunek</th>
                    <th>status</th>
                </tr>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'egzamin');
    $result = mysqli_query($connection, 'SELECT id, nr_rejsu, czas, kierunek, status_lotu FROM odloty ORDER BY czas DESC;');
    while ($row = mysqli_fetch_row($result)) {
        echo "            <tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td><td>$row[3]</td><td>$row[4]</td></tr>\n";
    }
    mysqli_close($connection);
    ?>
            </table>
        </section>
        <section id="download">
            <a href="kw1.jpg" target="_blank">Pobierz obraz</a>
        </section>
        <section id="status">
        </section>
        <section id="author">
            Autor: Bartosz Bryniarski
        </section>
    </body>
    </html>

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

  37. Krok 37: Skrypt 2: komunikat przy pierwszej wizycie

    Kryteria:

    R.2.5 W pierwszym bloku banera zapisano nagłówek h2: "Odloty z lotniska", w bloku głównym nagłówek h4: "tabela odlotów" oraz w drugim bloku stopki zapisano paragraf (kodem HTML lub skryptem)

    ok. 2 min
    Polecenie z arkusza

    Gdy odwiedzający wejdzie na stronę pierwszy raz zakładane jest ciasteczko z czasem trwania 1 godzina od utworzenia oraz wyświetlany jest w paragrafie, czcionką pochyloną, komunikat: „Dzień dobry! Sprawdź regulamin naszej strony”

    W drugim bloku stopki drugi blok PHP z tym samym warunkiem: przy pierwszej wizycie echo wypisuje komunikat w paragrafie <p> (R.2.5), pochylony znacznikiem <i>. Warunek działa tak samo w obu blokach, bo setcookie nie zmienia $_COOKIE w bieżącym wykonaniu - ciasteczko wróci od przeglądarki dopiero przy następnym wejściu. Podgląd: pierwsza wizyta, „Dzień dobry! Sprawdź regulamin naszej strony” kursywą.

    airport.php PHP zmienione: 5 linii
    <?php
    if (!isset($_COOKIE['odloty'])) {
        setcookie('odloty', 'odwiedzono', time() + 3600);
    }
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Odloty samolotów</title>
        <link rel="stylesheet" href="styl6.css">
    </head>
    <body>
        <section id="title">
            <h2>Odloty z lotniska</h2>
        </section>
        <section id="logo">
            <img src="zad6.png" alt="logotyp">
        </section>
        <section id="main">
            <h4>tabela odlotów</h4>
            <table>
                <tr>
                    <th>lp.</th>
                    <th>numer rejsu</th>
                    <th>czas</th>
                    <th>kierunek</th>
                    <th>status</th>
                </tr>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'egzamin');
    $result = mysqli_query($connection, 'SELECT id, nr_rejsu, czas, kierunek, status_lotu FROM odloty ORDER BY czas DESC;');
    while ($row = mysqli_fetch_row($result)) {
        echo "            <tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td><td>$row[3]</td><td>$row[4]</td></tr>\n";
    }
    mysqli_close($connection);
    ?>
            </table>
        </section>
        <section id="download">
            <a href="kw1.jpg" target="_blank">Pobierz obraz</a>
        </section>
        <section id="status">
    <?php
    if (!isset($_COOKIE['odloty'])) {
        echo '<p><i>Dzień dobry! Sprawdź regulamin naszej strony</i></p>';
    }
    ?>
        </section>
        <section id="author">
            Autor: Bartosz Bryniarski
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (airport.php)
  38. Krok 38: Skrypt 2: komunikat przy kolejnej wizycie

    Kryteria: , ,

    R.2.9 W drugim bloku stopki gdy wyświetlany jest tekst "Dzień dobry!..." czcionka jest pochylona lub gdy wyświetlony jest tekst "Miło nam..." czcionka jest pogrubiona (dowolną metodą)

    R.5.6 Skrypt 2 wykorzystuje mechanizm ciasteczek, zastosowano funkcje setcookie, isset oraz tablicę $_COOKIE, zapis musi być poprawny składniowo i logicznie

    R.5.8 Gdy odwiedzający jest na stronie pierwszy raz wyświetlany jest komunikat "Dzień dobry! Sprawdź regulamin naszej strony” w przeciwnym wypadku komunikat „Miło nam że nas znowu odwiedziłeś"

    ok. 3 min
    Polecenie z arkusza

    Jeżeli odwiedzający w ciągu godziny od poprzedniego wejścia wejdzie ponownie na stronę wyświetlany jest w paragrafie, czcionką pogrubioną, komunikat „Miło nam, że nas znowu odwiedziłeś”

    Gałąź else - ciasteczko jest, czyli gość wrócił w ciągu godziny: komunikat w paragrafie, pogrubiony znacznikiem <b>. Skrypt korzysta z setcookie, isset i $_COOKIE (R.5.6), wypisuje oba komunikaty (R.5.8), jeden pochylony, drugi pogrubiony (R.2.9).

    Sprawdzone na prawdziwym serwerze dwoma wejściami tej samej przeglądarki: pierwsze dało „Dzień dobry! Sprawdź regulamin naszej strony”, drugie - „Miło nam, że nas znowu odwiedziłeś”, a ciasteczko wygasa 3600 s po utworzeniu. Podgląd pokazuje drugą wizytę, jak na obrazie 2. W przeglądarce „pierwszą wizytę” powtórzysz, usuwając ciasteczko (F12, karta Aplikacja) albo w oknie prywatnym.

    Typowe błędy

    Formatowanie jest tu odwrotne niż w arkuszu z tablicą przylotów z tej samej sesji: pierwsza wizyta - pochylenie, kolejna - pogrubienie.

    airport.php PHP zmienione: 2 linie
    <?php
    if (!isset($_COOKIE['odloty'])) {
        setcookie('odloty', 'odwiedzono', time() + 3600);
    }
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Odloty samolotów</title>
        <link rel="stylesheet" href="styl6.css">
    </head>
    <body>
        <section id="title">
            <h2>Odloty z lotniska</h2>
        </section>
        <section id="logo">
            <img src="zad6.png" alt="logotyp">
        </section>
        <section id="main">
            <h4>tabela odlotów</h4>
            <table>
                <tr>
                    <th>lp.</th>
                    <th>numer rejsu</th>
                    <th>czas</th>
                    <th>kierunek</th>
                    <th>status</th>
                </tr>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'egzamin');
    $result = mysqli_query($connection, 'SELECT id, nr_rejsu, czas, kierunek, status_lotu FROM odloty ORDER BY czas DESC;');
    while ($row = mysqli_fetch_row($result)) {
        echo "            <tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td><td>$row[3]</td><td>$row[4]</td></tr>\n";
    }
    mysqli_close($connection);
    ?>
            </table>
        </section>
        <section id="download">
            <a href="kw1.jpg" target="_blank">Pobierz obraz</a>
        </section>
        <section id="status">
    <?php
    if (!isset($_COOKIE['odloty'])) {
        echo '<p><i>Dzień dobry! Sprawdź regulamin naszej strony</i></p>';
    } else {
        echo '<p><b>Miło nam, że nas znowu odwiedziłeś</b></p>';
    }
    ?>
        </section>
        <section id="author">
            Autor: Bartosz Bryniarski
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (airport.php)
  39. Etap 5: Dobre praktyki (poza kluczem)

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

    Krok 39: Zabezpieczenie: htmlspecialchars na danych z bazy

    ok. 3 min
    Polecenie z arkusza

    Dane otrzymane z bazy są umieszczane w kolejnych wierszach tabeli, w odpowiednich komórkach, tak jak na Obrazie 2

    Skrypt wkleja do strony wszystko, co jest w bazie - także znaczniki HTML. Sprawdzone: status lotu LX5673 zmieniony na opoznienie <s>10</s> 20 min wersja z poprzednich kroków wyświetla z przekreśloną liczbą. Tak samo trafiłby na stronę znacznik <script> - kod JavaScript uruchomiony u każdego gościa tablicy odlotów (atak XSS).

    htmlspecialchars zamienia <, >, & i cudzysłowy na encje, więc przeglądarka pokazuje je jako tekst; array_map przepuszcza przez nią wszystkie komórki wiersza naraz. Podgląd: ten sam status widać dosłownie. Stara linia zostaje w komentarzu; na egzaminie klucz tego nie sprawdza.

    airport.php PHP zmienione: 3 linie
    <?php
    if (!isset($_COOKIE['odloty'])) {
        setcookie('odloty', 'odwiedzono', time() + 3600);
    }
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Odloty samolotów</title>
        <link rel="stylesheet" href="styl6.css">
    </head>
    <body>
        <section id="title">
            <h2>Odloty z lotniska</h2>
        </section>
        <section id="logo">
            <img src="zad6.png" alt="logotyp">
        </section>
        <section id="main">
            <h4>tabela odlotów</h4>
            <table>
                <tr>
                    <th>lp.</th>
                    <th>numer rejsu</th>
                    <th>czas</th>
                    <th>kierunek</th>
                    <th>status</th>
                </tr>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'egzamin');
    $result = mysqli_query($connection, 'SELECT id, nr_rejsu, czas, kierunek, status_lotu FROM odloty ORDER BY czas DESC;');
    while ($row = mysqli_fetch_row($result)) {
        // echo "            <tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td><td>$row[3]</td><td>$row[4]</td></tr>\n";
        $cells = array_map('htmlspecialchars', $row);
        echo "            <tr><td>$cells[0]</td><td>$cells[1]</td><td>$cells[2]</td><td>$cells[3]</td><td>$cells[4]</td></tr>\n";
    }
    mysqli_close($connection);
    ?>
            </table>
        </section>
        <section id="download">
            <a href="kw1.jpg" target="_blank">Pobierz obraz</a>
        </section>
        <section id="status">
    <?php
    if (!isset($_COOKIE['odloty'])) {
        echo '<p><i>Dzień dobry! Sprawdź regulamin naszej strony</i></p>';
    } else {
        echo '<p><b>Miło nam, że nas znowu odwiedziłeś</b></p>';
    }
    ?>
        </section>
        <section id="author">
            Autor: Bartosz Bryniarski
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (airport.php)
  40. Krok 40: Zabezpieczenie: błąd bazy bez szczegółów serwera

    ok. 3 min
    Polecenie z arkusza

    Skrypt łączy się z serwerem bazodanowym na localhost, użytkownik root bez hasła, baza danych o nazwie egzamin

    Od PHP 8.1 funkcje mysqli przy błędzie rzucają wyjątek. Sprawdzone: bez bazy egzamin strona urywa się w połowie tabeli, a zamiast reszty pojawia się „Fatal error: Uncaught mysqli_sql_exception: Unknown database 'egzamin'” z pełną ścieżką do pliku na serwerze - informacja przydatna dla włamywacza, bezużyteczna dla gościa.

    Skrypt 1 trafia do bloku try, a catch (mysqli_sql_exception $exception) wypisuje jeden wiersz tabeli z neutralnym komunikatem (colspan="5" - komórka na całą szerokość). Stopka i komunikat o ciasteczku działają dalej. Podgląd: strona uruchomiona bez bazy.

    airport.php PHP zmienione: 11 linii
    <?php
    if (!isset($_COOKIE['odloty'])) {
        setcookie('odloty', 'odwiedzono', time() + 3600);
    }
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Odloty samolotów</title>
        <link rel="stylesheet" href="styl6.css">
    </head>
    <body>
        <section id="title">
            <h2>Odloty z lotniska</h2>
        </section>
        <section id="logo">
            <img src="zad6.png" alt="logotyp">
        </section>
        <section id="main">
            <h4>tabela odlotów</h4>
            <table>
                <tr>
                    <th>lp.</th>
                    <th>numer rejsu</th>
                    <th>czas</th>
                    <th>kierunek</th>
                    <th>status</th>
                </tr>
    <?php
    try {
        $connection = mysqli_connect('localhost', 'root', '', 'egzamin');
        $result = mysqli_query($connection, 'SELECT id, nr_rejsu, czas, kierunek, status_lotu FROM odloty ORDER BY czas DESC;');
        while ($row = mysqli_fetch_row($result)) {
            // echo "            <tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td><td>$row[3]</td><td>$row[4]</td></tr>\n";
            $cells = array_map('htmlspecialchars', $row);
            echo "            <tr><td>$cells[0]</td><td>$cells[1]</td><td>$cells[2]</td><td>$cells[3]</td><td>$cells[4]</td></tr>\n";
        }
        mysqli_close($connection);
    } catch (mysqli_sql_exception $exception) {
        echo '            <tr><td colspan="5">Tablica odlotów jest chwilowo niedostępna</td></tr>' . "\n";
    }
    ?>
            </table>
        </section>
        <section id="download">
            <a href="kw1.jpg" target="_blank">Pobierz obraz</a>
        </section>
        <section id="status">
    <?php
    if (!isset($_COOKIE['odloty'])) {
        echo '<p><i>Dzień dobry! Sprawdź regulamin naszej strony</i></p>';
    } else {
        echo '<p><b>Miło nam, że nas znowu odwiedziłeś</b></p>';
    }
    ?>
        </section>
        <section id="author">
            Autor: Bartosz Bryniarski
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (airport.php)
  41. Krok 41: Zabezpieczenie: flagi ciasteczka

    ok. 3 min
    Polecenie z arkusza

    Gdy odwiedzający wejdzie na stronę pierwszy raz zakładane jest ciasteczko z czasem trwania 1 godzina od utworzenia

    Opis setcookie w arkuszu wymienia parametr httponly: ciasteczka z tą flagą nie odczyta JavaScript na stronie, więc nie wykradnie go wstrzyknięty skrypt. Od PHP 7.3 parametry podaje się czytelniej, tablicą opcji: expires (to samo time() + 3600), httponly i samesite - Lax nie dołącza ciasteczka do żądań wysyłanych z obcych stron.

    Sprawdzone w zapisie ciasteczek przeglądarki testowej: po zmianie wpis odloty ma oznaczenie HttpOnly. Wartości ciasteczka nie wolno ufać (gość może ją zmienić) i nie zapisuje się w nim danych poufnych - arkusz też to mówi. Podgląd: druga wizyta.

    airport.php PHP zmienione: 6 linii
    <?php
    if (!isset($_COOKIE['odloty'])) {
        // setcookie('odloty', 'odwiedzono', time() + 3600);
        setcookie('odloty', 'odwiedzono', [
            'expires' => time() + 3600,
            'httponly' => true,
            'samesite' => 'Lax',
        ]);
    }
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Odloty samolotów</title>
        <link rel="stylesheet" href="styl6.css">
    </head>
    <body>
        <section id="title">
            <h2>Odloty z lotniska</h2>
        </section>
        <section id="logo">
            <img src="zad6.png" alt="logotyp">
        </section>
        <section id="main">
            <h4>tabela odlotów</h4>
            <table>
                <tr>
                    <th>lp.</th>
                    <th>numer rejsu</th>
                    <th>czas</th>
                    <th>kierunek</th>
                    <th>status</th>
                </tr>
    <?php
    try {
        $connection = mysqli_connect('localhost', 'root', '', 'egzamin');
        $result = mysqli_query($connection, 'SELECT id, nr_rejsu, czas, kierunek, status_lotu FROM odloty ORDER BY czas DESC;');
        while ($row = mysqli_fetch_row($result)) {
            // echo "            <tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td><td>$row[3]</td><td>$row[4]</td></tr>\n";
            $cells = array_map('htmlspecialchars', $row);
            echo "            <tr><td>$cells[0]</td><td>$cells[1]</td><td>$cells[2]</td><td>$cells[3]</td><td>$cells[4]</td></tr>\n";
        }
        mysqli_close($connection);
    } catch (mysqli_sql_exception $exception) {
        echo '            <tr><td colspan="5">Tablica odlotów jest chwilowo niedostępna</td></tr>' . "\n";
    }
    ?>
            </table>
        </section>
        <section id="download">
            <a href="kw1.jpg" target="_blank">Pobierz obraz</a>
        </section>
        <section id="status">
    <?php
    if (!isset($_COOKIE['odloty'])) {
        echo '<p><i>Dzień dobry! Sprawdź regulamin naszej strony</i></p>';
    } else {
        echo '<p><b>Miło nam, że nas znowu odwiedziłeś</b></p>';
    }
    ?>
        </section>
        <section id="author">
            Autor: Bartosz Bryniarski
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (airport.php)
  42. Etap 6: Oddanie pracy

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

    Krok 42: Plik przeglądarka.txt i nagranie płyty

    ok. 5 min
    Polecenie z arkusza

    Po zakończeniu pracy utwórz plik tekstowy. Zapisz w nim nazwę przeglądarki internetowej, w której weryfikowałeś poprawność działania witryny, zapisz go w folderze z numerem PESEL, jako przeglądarka.txt. Nagraj płytę z rezultatami pracy.

    W przeglądarka.txt wpisujesz nazwę przeglądarki, w której sprawdzasz stronę przez http://localhost/…. W folderze zdającego muszą być: airport.php, import.png, kw1.jpg, kw2.jpg, kw3.jpg, kw4.jpg, kwerendy.txt, przeglądarka.txt, styl6.css i przeskalowany zad6.png. Nagraj płytę, sprawdź jej odczyt i opisz ją numerem PESEL.

    przeglądarka.txt Tekst nowy plik
    Google Chrome

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

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.

Potwierdzenie

Informacja