Przejdź do głównej treści
EE.09-01-23.01-SGStyczeń 2023 · 55 kroków · ok. 96 min · 37 kryteriów z klucza

Rozwiązanie krok po kroku: Akta pracownicze dla sekretariatu firmy (Wersja podstawowa)

Aplikacja sekretariatu firmy: baza firma z tabelami pracownicy i stanowiska, cztery zapytania (jeden pracownik, liczba pracowników, złączenie z nazwą stanowiska), zdjęcie pracownika przeskalowane do 400 px i strona index.php z trzema skryptami PHP - karta pracownika z adresem i statusem dokumentów RODO i badań, liczba zatrudnionych oraz zdjęcie, imię i nazwisko i stanowisko. Do tego style w styl.css z cieniem bloków (box-shadow).

To arkusz EE.09 ze stycznia 2023 - kwalifikacji formuły 2017, którą zastąpiła INF.03. 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 są najpierw napisane najprościej, funkcjami mysqli z tabeli 1 arkusza, a na końcu sprawdzone na prawdziwych atakach i zabezpieczone.

To jest wersja podstawowa. W zakładce „Nowoczesny kod (grid, PDO)” jest drugi sposób rozwiązania tego samego arkusza: siatka CSS zamiast float, PHP na PDO na górze pliku z zapytaniami przygotowanymi i funkcją do bezpiecznego wypisywania danych - obie wersje są zgodne z kluczem.

Baza, zdjęcie i plik cv.txt pochodzą z oryginalnego archiwum CKE zad1.zip (załącznik do pobrania na stronie arkusza, hasło w treści zadania). Zapytania i zrzuty są policzone na MariaDB 10.4 - tej samej, która jest w XAMPP, a podgląd od kroków z PHP to wynik prawdziwego uruchomienia kodu w PHP 8.2 (klucz każe sprawdzać w XAMPP 8.1.2 - użyte funkcje działają w obu wersjach).

Jak liczą się punkty. Klucz ma 37 kryteriów (R.1.1 - R.5.9), 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: Folder zdającego i archiwum zad1.zip

    ok. 2 min
    Polecenie z arkusza

    Na pulpicie konta Egzamin należy utworzyć folder. Jako nazwy folderu należy użyć numeru zdającego, którym został podpisany arkusz. Rozpakowane pliki należy umieścić w tym folderze. Zaleca się, aby rozpakowane pliki znajdowały się w tym samym folderze, co pliki strony. Po skończonej pracy wszystkie wyniki należy zapisać w tym folderze.

    Na pulpicie tworzysz folder nazwany numerem PESEL - w tym rozwiązaniu w jego miejscu stoi imię i nazwisko autora, Bartosz Bryniarski. Archiwum zad1.zip rozpakowujesz do tego folderu z hasłem AKt@PR@cownicZE (wielkość liter i znaki @ mają znaczenie). W środku: baza.sql (tabele do importu), 2.jpg (zdjęcie pracownika) i cv.txt (plik, do którego poprowadzi odnośnik „Pobierz”).

    Strona index.php zadziała tylko przez serwer Apache, czyli z folderu C:\xampp\htdocs. Wygodnie jest więc pracować w folderze w htdocs (np. htdocs\egzamin), a na koniec skopiować całość do folderu z numerem na pulpicie - albo odwrotnie. Zdjęcie i cv.txt muszą leżeć obok index.php, bo strona odwołuje się do nich samą nazwą pliku.

    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 i baza firma

    ok. 2 min
    Polecenie z arkusza

    Za pomocą narzędzia phpMyAdmin wykonaj operacje na bazie danych: Utwórz bazę danych o nazwie firma

    W XAMPP Control Panel klikasz Start przy Apache i MySQL, potem http://localhost/phpmyadmin. Nowa w lewym panelu, nazwa firma, porównywanie napisów np. utf8_unicode_ci albo utf8mb4_polish_ci, Utwórz. Nazwę bazy wpisze później skrypt - musi być identyczna.

  3. Krok 3: Import tabel z pliku baza.sql i zrzut import.jpg

    Kryteria:

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

    ok. 3 min
    Polecenie z arkusza

    Do bazy firma zaimportuj tabele z pliku baza.sql z rozpakowanego archiwum. Wykonaj zrzut ekranu po imporcie. Zrzut zapisz w formacie JPEG i nazwij import. Nie kadruj zrzutu. Powinien on obejmować cały ekran monitora, z widocznym paskiem zadań. Na zrzucie powinny być widoczne elementy wskazujące na poprawnie wykonany import tabel

    Zaznacz bazę firma, karta Import, Wybierz plik → baza.sql, Wykonaj. Powstają dwie tabele z obrazu 1: pracownicy (9 osób) i stanowiska (4 stanowiska). Kolumna stanowiska_id w tabeli pracownicy to klucz obcy - numer wiersza z tabeli stanowiska; na nim opiera się zapytanie 4. Pola czyRODO i czyBadania przyjmują tylko 1 albo 0.

    Zielony komunikat o sukcesie i dwie tabele w lewym panelu na zrzucie całego ekranu: import.jpg.

    Typowe błędy

    Zrzut importu w JPEG (import.jpg), zrzuty zapytań w PNG (kw1.png - kw4.png). Wykadrowany zrzut albo zrzut bez paska zadań nie jest oceniany.

    Podgląd strony po tym kroku
    Podgląd strony po kroku 3
  4. Krok 4: Zapytanie 1: dane pracownika o id 2

    Kryteria: ,

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

    R.1.3 Utworzono zapytanie 1 wybierające jedynie pola imie, nazwisko, adres, miasto, czyRODO, czyBadania z tabeli pracownicy dla wiersza o id równym 2. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT imie, nazwisko, adres, miasto, czyRODO, czyBadania FROM pracownicy WHERE id=2; oraz wynik działania zapytania udokumentowano zrzutem, na którym widoczny jest jedynie rekord z danymi: Anna, Nowak, ul. Piekarska 6, Bytom, 1, 1

    ok. 3 min
    Polecenie z arkusza

    Wykonaj zapytania SQL działające na bazie firma. Zapytania zapisz w pliku kwerendy.txt. Wykonaj zrzuty ekranu przedstawiające wyniki działania kwerend. Zrzuty zapisz w formacie PNG i nadaj im nazwy kw1, kw2, kw3, kw4. Zrzuty powinny obejmować cały ekran monitora z widocznym paskiem zadań. Zapytanie 1: wybierające jedynie pola imie, nazwisko, adres, miasto, czyRODO, czyBadania z tabeli pracownicy dla wiersza o id równym 2

    Zaznacz bazę firma, karta SQL:

    • SELECT imie, nazwisko, adres, miasto, czyRODO, czyBadania - sześć pól w kolejności z arkusza; „jedynie” oznacza: bez * i bez id,
    • FROM pracownicy - tabela,
    • WHERE id = 2 - jeden konkretny wiersz.

    Wynik: Anna, Nowak, ul. Piekarska 6, Bytom, 1, 1 - jak w kluczu. Zapytanie kopiujesz do pliku kwerendy.txt (z tego pliku przekopiujesz je później do skryptu), a zrzut całego ekranu zapisujesz jako kw1.png.

    kwerendy.txt Tekst nowy plik
    -- Zapytanie 1
    SELECT imie, nazwisko, adres, miasto, czyRODO, czyBadania FROM pracownicy WHERE id = 2;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 4
  5. Krok 5: Zapytanie 2: liczba pracowników

    Kryteria:

    R.1.4 Utworzono zapytanie 2 zliczające wszystkie rekordy w tabeli pracownicy . W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT COUNT(*) FROM pracownicy; (możliwa też nazwa dowolnego pola zamiast *) oraz wynik działania zapytania udokumentowano zrzutem, na którym widoczna jest wartość 9

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 2: wybierające liczbę wszystkich rekordów w tabeli pracownicy

    Funkcja agregująca COUNT(*) liczy wiersze tabeli. Wynik: jedna komórka z liczbą 9. Zrzut: kw2.png.

    Typowe błędy

    SELECT * FROM pracownicy pokazuje 9 wierszy, ale nie „wybiera liczby” - skrypt 2 musiałby je sam policzyć, a klucz R.1.4 wymaga COUNT.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT imie, nazwisko, adres, miasto, czyRODO, czyBadania FROM pracownicy WHERE id = 2;
    
    -- Zapytanie 2
    SELECT COUNT(*) FROM pracownicy;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 5
  6. Krok 6: Zapytanie 3: id, imię i nazwisko pracownika o id 2

    Kryteria:

    R.1.5 Utworzono zapytanie 3 wybierające jedynie pola id, imie, nazwisko z tabeli pracownicy dla wiersza o id równym 2. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT id, imie, nazwisko FROM pracownicy WHERE id = 2; oraz wynik działania zapytania udokumentowano zrzutem, na którym widoczny jest jedynie jeden rekord z danymi: 2, Anna, Nowak

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 3: wybierające jedynie pola id, imie, nazwisko z tabeli pracownicy dla wiersza o id równym 2

    Trzy pola, ten sam warunek co w zapytaniu 1. Wynik: 2, Anna, Nowak. Pole id jest tu potrzebne skryptowi 3 - z niego powstanie nazwa pliku zdjęcia 2.jpg. Zrzut: kw3.png.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT imie, nazwisko, adres, miasto, czyRODO, czyBadania FROM pracownicy WHERE id = 2;
    
    -- Zapytanie 2
    SELECT COUNT(*) FROM pracownicy;
    
    -- Zapytanie 3
    SELECT id, imie, nazwisko FROM pracownicy WHERE id = 2;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 6
  7. Krok 7: Zapytanie 4: stanowisko pracownika przez relację

    Kryteria:

    R.1.6 Utworzono zapytanie 4 wybierające jedynie pole id z tabeli pracownicy i odpowiadające mu pola nazwa i opis z tabeli stanowiska dla wiersza tabeli pracownicy o id równym 2. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT pracownicy.id, nazwa, opis FROM pracownicy JOIN stanowiska ON pracownicy.stanowiska_id = stanowiska.id WHERE pracownicy.id = 2; (możliwe też INNER JOIN lub bez JOIN z porównaniem kluczy w sekcji WHERE) oraz wynik działania zapytania udokumentowano zrzutem, na którym widoczny jest jedynie jeden rekord z danymi: 2, kierownik, kierownik grupy programistow

    ok. 4 min
    Polecenie z arkusza

    Zapytanie 4: wybierające jedynie id z tabeli pracownicy i odpowiadające mu pola nazwa i opis z tabeli stanowiska dla wiersza tabeli pracownicy o id równym 2. Należy posłużyć się relacją

    • SELECT pracownicy.id, nazwa, opis - kolumnę id mają obie tabele, więc przed nią stoi nazwa tabeli; nazwa i opis są tylko w stanowiska,
    • FROM pracownicy JOIN stanowiska ON pracownicy.stanowiska_id = stanowiska.id - relacja: klucz obcy pracownika równa się kluczowi głównemu stanowiska,
    • WHERE pracownicy.id = 2 - znów z nazwą tabeli, inaczej baza zgłosi błąd „Column 'id' in where clause is ambiguous”.

    Wynik: 2, kierownik, kierownik grupy programistow. Zrzut: kw4.png.

    Typowe błędy

    Samo id bez nazwy tabeli - w SELECT i w WHERE - kończy się błędem niejednoznacznej kolumny.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT imie, nazwisko, adres, miasto, czyRODO, czyBadania FROM pracownicy WHERE id = 2;
    
    -- Zapytanie 2
    SELECT COUNT(*) FROM pracownicy;
    
    -- Zapytanie 3
    SELECT id, imie, nazwisko FROM pracownicy WHERE id = 2;
    
    -- Zapytanie 4
    SELECT pracownicy.id, nazwa, opis FROM pracownicy JOIN stanowiska ON pracownicy.stanowiska_id = stanowiska.id WHERE pracownicy.id = 2;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 7
  8. Etap 2: Grafika i strona HTML

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

    Krok 8: Zdjęcie 2.jpg przeskalowane do 400 px

    Kryteria:

    R.2.1 Plik 2 .jpg przeskalowano z zachowaniem proporcji do szerokości 400 px, odpowiadająca temu wysokość wynosi 267 px (± 5 px)

    ok. 2 min
    Polecenie z arkusza

    Plik 2.jpg, wypakowany z archiwum, należy przeskalować z zachowaniem proporcji do szerokości 400 px

    Oryginał ma 500 × 334 px. W GIMP-ie Obraz → Skaluj obraz, łańcuch zamknięty (zachowanie proporcji), szerokość 400 - wysokość przelicza się sama: 334 × 400 / 500 = 267,2, czyli 267 px (klucz: 267 ±5). Zapis pod tą samą nazwą: Plik → Nadpisz 2.jpg - skrypt 3 będzie szukał pliku właśnie o nazwie 2.jpg.

    Typowe błędy

    Eksport pod nową nazwą (np. 2_male.jpg) zostawia w folderze oryginał - strona pokaże niezmienione zdjęcie, bo skrypt zbuduje nazwę 2.jpg.

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

    Kryteria:

    R.2.2 Witrynę internetową zapisano w pliku PHP o nazwie index

    ok. 1 min
    Polecenie z arkusza

    Cechy witryny: Składa się ze strony o nazwie index.php

    Nowy plik index.php w folderze ze zdjęciem i cv.txt. Rozszerzenie .php jest konieczne: tylko taki plik serwer przepuszcza przez PHP, zanim wyśle go przeglądarce. Do etapu skryptów plik zawiera sam HTML - podgląd pokazuje go wprost.

    index.php PHP nowy plik
    Podgląd strony po tym kroku (index.php)
  10. Krok 10: Szkielet HTML5

    ok. 1 min
    Polecenie z arkusza

    Zapisana w języku HTML5

    <!DOCTYPE html> w pierwszej linii i szkielet <html>, <head>, <body>.

    index.php PHP zmienione: 7 linii
    <!DOCTYPE html>
    <html>
    <head>
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  11. Krok 11: Kodowanie polskich znaków

    ok. 1 min
    Polecenie z arkusza

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

    <meta charset="UTF-8"> w <head>, a plik zapisany w edytorze w UTF-8. Baza wysyła dane w UTF-8, więc „Liczba zatrudnionych pracowników” i dane z bazy wyświetlą się poprawnie.

    index.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  12. Krok 12: Język strony

    Kryteria:

    R.2.3 Zastosowano deklarację języka HTML5, jawnie zapisano standard kodowania polskich znaków oraz zadeklarowano język witryny (np. <html lang = 'pl'>)

    ok. 1 min
    Polecenie z arkusza

    Zadeklarowany język witryny: polski

    lang="pl" w znaczniku <html>. Deklaracja HTML5, kodowanie i język dają razem R.2.3.

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

    Kryteria:

    R.2.4 Nadano tytuł stronie: "Sekretariat"

    ok. 1 min
    Polecenie z arkusza

    Tytuł strony widoczny na karcie przeglądarki: „Sekretariat”

    <title> w <head>.

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

    Kryteria:

    R.3.3 Strona zawiera działające połączenie z zewnętrznym arkuszem stylów o nazwie styl.css , formatowanie pochodzi jedynie z tego arkusza Uwaga: kryterium to nie jest spełnione również, gdy 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

    <link rel="stylesheet" href="styl.css"> - całe formatowanie strony trafi do tego pliku, bez atrybutów style w HTML-u ani w skryptach (R.3.3).

    Typowe błędy

    Kropka zamiast # przed identyfikatorem bloku w CSS odbiera punkt R.3.3 - klucz uznaje połączenie tylko wtedy, gdy każdy selektor trafia w swój blok.

    index.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sekretariat</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  15. Krok 15: Bloki: lewy, prawy i stopka

    Kryteria:

    R.2.5 Wygląd strony zdefiniowano dzieląc ją na bloki: lewy, prawy i stopkę. Zastosowano znaczniki sekcji

    ok. 2 min
    Polecenie z arkusza

    Podział strony na bloki: lewy, prawy, stopka. Podział zrealizowany za pomocą znaczników sekcji tak, aby wygląd układu bloków strony po uruchomieniu w przeglądarce, był zgodny z Obrazem 2

    Bloki lewy i prawy to <section> z identyfikatorami left i right (nazwy po angielsku - arkusz ich nie narzuca), stopka - <footer>. Strona nie ma banera. Obok siebie ustawi bloki dopiero CSS.

    index.php PHP zmienione: 6 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sekretariat</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <section id="left">
        </section>
        <section id="right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  16. Krok 16: Blok lewy: nagłówek „Akta Pracownicze”

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku lewego: nagłówek pierwszego stopnia o treści „Akta Pracownicze”

    <h1> na początku bloku lewego. Zaraz pod nim stanie skrypt 1 z danymi pracownika - napiszesz go w etapie PHP, po stylach.

    index.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sekretariat</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <section id="left">
            <h1>Akta Pracownicze</h1>
        </section>
        <section id="right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  17. Krok 17: Blok lewy: linia horyzontalna

    ok. 1 min
    Polecenie z arkusza

    linia horyzontalna

    <hr> - pozioma linia oddzielająca dane pracownika od dokumentów. Na obrazie 2 to trzecia linia w bloku: dwie pierwsze wypisze skrypt 1, między nagłówkiem a tą linią. <hr> nie ma znacznika zamykającego.

    index.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sekretariat</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <section id="left">
            <h1>Akta Pracownicze</h1>
            <hr>
        </section>
        <section id="right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  18. Krok 18: Blok lewy: nagłówek „Dokumenty pracownika”

    ok. 1 min
    Polecenie z arkusza

    nagłówek trzeciego stopnia o treści: „Dokumenty pracownika”

    Trzeciego stopnia to <h3>.

    index.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sekretariat</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <section id="left">
            <h1>Akta Pracownicze</h1>
            <hr>
            <h3>Dokumenty pracownika</h3>
        </section>
        <section id="right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  19. Krok 19: Blok lewy: odnośnik „Pobierz” do pliku cv.txt

    Kryteria:

    R.3.2 Na stronie umieszczono odnośnik, którego kliknięcie otwiera / pobiera plik cv.txt

    ok. 1 min
    Polecenie z arkusza

    odnośnik o treści „Pobierz” do pliku cv.txt

    <a href="cv.txt"> - plik z tego samego folderu co strona. Przeglądarka otworzy go jako tekst albo pobierze, zależnie od ustawień - obie reakcje spełniają R.3.2. Atrybut download wymusiłby pobranie, ale arkusz go nie wymaga. Plik cv.txt z archiwum zawiera jedno zdanie zastępujące prawdziwe CV. Na obrazie 2 odnośnik stoi przy samej krawędzi bloku - nie jest w paragrafie, więc nie dostaje wcięcia z reguły dla p.

    cv.txt Tekst nowy plik
    plik z CV pracownika
    index.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sekretariat</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <section id="left">
            <h1>Akta Pracownicze</h1>
            <hr>
            <h3>Dokumenty pracownika</h3>
            <a href="cv.txt">Pobierz</a>
        </section>
        <section id="right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  20. Krok 20: Blok lewy: nagłówek „Liczba zatrudnionych pracowników”

    ok. 1 min
    Polecenie z arkusza

    nagłówek pierwszego stopnia o treści „Liczba zatrudnionych pracowników”

    Drugi <h1> w bloku. Na obrazie 2 ma ten sam niebieski pasek co „Akta Pracownicze” - oba nagłówki sformatuje jedna reguła dla selektora h1.

    index.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sekretariat</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <section id="left">
            <h1>Akta Pracownicze</h1>
            <hr>
            <h3>Dokumenty pracownika</h3>
            <a href="cv.txt">Pobierz</a>
            <h1>Liczba zatrudnionych pracowników</h1>
        </section>
        <section id="right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  21. Krok 21: Blok lewy: paragraf na wynik skryptu 2

    ok. 1 min
    Polecenie z arkusza

    paragraf, a w nim efekt wykonania skryptu 2

    Pusty <p> - skrypt 2 wpisze do niego liczbę pracowników. Paragraf stoi w HTML-u, a nie w skrypcie, więc skrypt wypisze samą liczbę.

    index.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sekretariat</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <section id="left">
            <h1>Akta Pracownicze</h1>
            <hr>
            <h3>Dokumenty pracownika</h3>
            <a href="cv.txt">Pobierz</a>
            <h1>Liczba zatrudnionych pracowników</h1>
            <p>
            </p>
        </section>
        <section id="right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  22. Krok 22: Stopka: napis z autorem aplikacji

    Kryteria:

    R.2.9 W stopce umieszczono napis "Autorem aplikacji jest: "

    ok. 1 min
    Polecenie z arkusza

    Zawartość stopki: napis o treści „Autorem aplikacji jest: ”, dalej wstawiony numer zdającego

    Na egzaminie po dwukropku wpisujesz swój numer PESEL, w tym rozwiązaniu w jego miejscu stoi Bartosz Bryniarski. Napis stoi w stopce bez paragrafu: reguła dla p dodałaby mu 30 px wcięcia, a na obrazie 2 zaczyna się równo z listą.

    index.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sekretariat</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <section id="left">
            <h1>Akta Pracownicze</h1>
            <hr>
            <h3>Dokumenty pracownika</h3>
            <a href="cv.txt">Pobierz</a>
            <h1>Liczba zatrudnionych pracowników</h1>
            <p>
            </p>
        </section>
        <section id="right">
        </section>
        <footer>
            Autorem aplikacji jest: Bartosz Bryniarski
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  23. Krok 23: Stopka: lista punktowana

    Kryteria:

    R.2.7 W bloku stopki umieszczono listę punktowaną z dwoma elementami, zastosowano znaczniki <ul>, <li>

    ok. 1 min
    Polecenie z arkusza

    lista punktowana (nieuporządkowana) o elementach: „skontaktuj się”, „poznaj naszą firmę”

    Lista nieuporządkowana to <ul>, każdy element w <li> - kropki dopisuje przeglądarka.

    Typowe błędy

    <ol> to lista numerowana - klucz wymaga znaczników <ul> i <li>.

    index.php PHP zmienione: 4 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sekretariat</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <section id="left">
            <h1>Akta Pracownicze</h1>
            <hr>
            <h3>Dokumenty pracownika</h3>
            <a href="cv.txt">Pobierz</a>
            <h1>Liczba zatrudnionych pracowników</h1>
            <p>
            </p>
        </section>
        <section id="right">
        </section>
        <footer>
            Autorem aplikacji jest: Bartosz Bryniarski
            <ul>
                <li>skontaktuj się</li>
                <li>poznaj naszą firmę</li>
            </ul>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  24. Etap 3: Styl CSS

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

    Krok 24: Plik styl.css: krój, tło i kolor tekstu strony

    Kryteria:

    R.4.1 Ustawiono dla selektora strony (body lub html lub kontener strony) krój czcionki Helvetica, kolor tła #DDD, kolor czcionki #546E7A

    ok. 1 min
    Polecenie z arkusza

    Styl CSS powinien być zdefiniowany jedynie w zewnętrznym pliku CSS. Dla selektora strony: krój czcionki Helvetica, kolor tła #DDD, kolor czcionki #546E7A

    Nowy plik styl.css. „Selektor strony” to body - krój i kolor tekstu dziedziczą wszystkie elementy w środku. #DDD to skrót od #DDDDDD (jasnoszary): każda z trzech cyfr szesnastkowych jest powtórzona (R.4.1).

    styl.css CSS nowy plik
    body {
        font-family: Helvetica;
        background-color: #DDD;
        color: #546E7A;
    }
    Podgląd strony po tym kroku (index.php)
  25. Krok 25: Bloki lewy i prawy: tło, wysokość, marginesy i cień

    Kryteria: ,

    R.4.4 Ustawiono wysokość bloku lewego i prawego: 600px

    R.4.8 Ustawiono dla bloku lewego i prawego cień o cechach: przesunięcie poziome i pionowe 0, rozmycie 20px kolor szary (dowolny odcień) np. box-shadow: 0 0 20px grey; (lub 0 0 20px 0 grey, lub gray, lub inny dowolny szary)

    ok. 3 min
    Polecenie z arkusza

    Wspólne dla bloku lewego i prawego: biały kolor tła, wysokość 600 px, marginesy zewnętrzne 20 px, cień bloku bez przesunięcia pionowego i poziomego, rozmycie 20 px i kolor szary

    Jedna reguła dla dwóch selektorów rozdzielonych przecinkiem: #left, #right. Marginesy zewnętrzne to margin, a cień - box-shadow. Kolejność wartości jest w pomocy z w3schools pod tabelą 1 arkusza: przesunięcie poziome, pionowe, rozmycie, kolor - czyli 0 0 20px gray. Zera bez jednostek są poprawne, a cień bez przesunięcia otacza blok równo ze wszystkich stron (R.4.4, R.4.8).

    Typowe błędy

    box-shadow: 20px gray to przesunięcie poziome 20 px bez rozmycia - cień przesunięty w prawo. Wartość rozmycia jest trzecia, po dwóch przesunięciach.

    styl.css CSS zmienione: 6 linii
    body {
        font-family: Helvetica;
        background-color: #DDD;
        color: #546E7A;
    }
    #left, #right {
        background-color: white;
        height: 600px;
        margin: 20px;
        box-shadow: 0 0 20px gray;
    }
    Podgląd strony po tym kroku (index.php)
  26. Krok 26: Blok lewy: szerokość 50%

    ok. 1 min
    Polecenie z arkusza

    Dla bloku lewego: szerokość 50%

    Osobna reguła #left - wspólne cechy są już w regule obu bloków.

    styl.css CSS zmienione: 3 linie
    body {
        font-family: Helvetica;
        background-color: #DDD;
        color: #546E7A;
    }
    #left, #right {
        background-color: white;
        height: 600px;
        margin: 20px;
        box-shadow: 0 0 20px gray;
    }
    #left {
        width: 50%;
    }
    Podgląd strony po tym kroku (index.php)
  27. Krok 27: Blok prawy: szerokość 30%

    Kryteria:

    R.4.5 Ustawiono szerokość bloku lewego: 50%, prawego 30% (width lub grid-template-columns lub flex)

    ok. 1 min
    Polecenie z arkusza

    Dla bloku prawego: szerokość 30%

    Szerokości obu bloków ustawione (R.4.5). Razem 80% szerokości okna, a cztery marginesy po 20 px zabierają jeszcze 80 px - do prawej krawędzi zostaje wolny pasek tła strony, jak na obrazie 2.

    styl.css CSS zmienione: 3 linie
    body {
        font-family: Helvetica;
        background-color: #DDD;
        color: #546E7A;
    }
    #left, #right {
        background-color: white;
        height: 600px;
        margin: 20px;
        box-shadow: 0 0 20px gray;
    }
    #left {
        width: 50%;
    }
    #right {
        width: 30%;
    }
    Podgląd strony po tym kroku (index.php)
  28. Krok 28: 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 egzaminacyjnym (prawidłowo zastosowano właściwości css układające bloki na stronie, np. float i clear albo display flex albo grid)

    ok. 2 min
    Polecenie z arkusza

    Podział strony na bloki: lewy, prawy, stopka. Podział zrealizowany za pomocą znaczników sekcji tak, aby wygląd układu bloków strony po uruchomieniu w przeglądarce, był zgodny z Obrazem 2

    Obie sekcje z float: left stają obok siebie, a stopka z clear: both zaczyna się pod nimi, na całej szerokości (R.3.1). Bez clear stopka wsunęłaby się pod pływające bloki.

    styl.css CSS zmienione: 6 linii
    body {
        font-family: Helvetica;
        background-color: #DDD;
        color: #546E7A;
    }
    #left, #right {
        background-color: white;
        height: 600px;
        margin: 20px;
        box-shadow: 0 0 20px gray;
    }
    #left {
        width: 50%;
    }
    #right {
        width: 30%;
    }
    section {
        float: left;
    }
    footer {
        clear: both;
    }
    Podgląd strony po tym kroku (index.php)
  29. Krok 29: Stopka: tło, biały tekst i marginesy wewnętrzne

    ok. 1 min
    Polecenie z arkusza

    Dla stopki: kolor tła #5C6BC0, biały kolor czcionki, marginesy wewnętrzne 30px

    Druga reguła footer - mogłaby też być jedną z clear: both; przeglądarka i tak łączy wszystkie reguły dla tego samego selektora.

    styl.css CSS zmienione: 5 linii
    body {
        font-family: Helvetica;
        background-color: #DDD;
        color: #546E7A;
    }
    #left, #right {
        background-color: white;
        height: 600px;
        margin: 20px;
        box-shadow: 0 0 20px gray;
    }
    #left {
        width: 50%;
    }
    #right {
        width: 30%;
    }
    section {
        float: left;
    }
    footer {
        clear: both;
    }
    footer {
        background-color: #5C6BC0;
        color: white;
        padding: 30px;
    }
    Podgląd strony po tym kroku (index.php)
  30. Krok 30: Obraz: szerokość 100%

    Kryteria:

    R.4.9 Ustawiono dla selektora obrazu szerokość 100%

    ok. 1 min
    Polecenie z arkusza

    Dla selektora obrazu: szerokość 100%

    Selektor znacznika img - zdjęcie wypełni szerokość bloku prawego i zmniejszy się razem z nim przy węższym oknie (R.4.9). Arkusz zastrzega selektory znaczników dla obrazu, nagłówków i paragrafu, bez klas.

    styl.css CSS zmienione: 3 linie
    body {
        font-family: Helvetica;
        background-color: #DDD;
        color: #546E7A;
    }
    #left, #right {
        background-color: white;
        height: 600px;
        margin: 20px;
        box-shadow: 0 0 20px gray;
    }
    #left {
        width: 50%;
    }
    #right {
        width: 30%;
    }
    section {
        float: left;
    }
    footer {
        clear: both;
    }
    footer {
        background-color: #5C6BC0;
        color: white;
        padding: 30px;
    }
    img {
        width: 100%;
    }
    Podgląd strony po tym kroku (index.php)
  31. Krok 31: Nagłówek pierwszego stopnia: pasek w kolorze stopki

    Kryteria: , ,

    R.4.2 Ustawiono kolor tła: biały dla bloku lewego i prawego, #5C6BC0 dla stopki oraz dla selektora h1

    R.4.3 Ustawiono biały kolor czcionki dla stopki oraz h1

    R.4.10 Ustawiono dla h1 grubość czcionki na 300

    ok. 2 min
    Polecenie z arkusza

    Dla selektora nagłówka pierwszego stopnia: kolor tła #5C6BC0, biały kolor czcionki, marginesy wewnętrzne 10 px, brak marginesów zewnętrznych, grubość czcionki 300

    • tło #5C6BC0 i biały tekst - komplet kolorów tła (R.4.2) i białej czcionki (R.4.3),
    • padding: 10px odsuwa napis od brzegów paska, a margin: 0 usuwa domyślne marginesy nagłówka: pasek przylega do góry bloku,
    • font-weight: 300 - cieńsze litery niż zwykłe (400); nagłówki domyślnie są pogrubione (700) (R.4.10). Jeśli w systemie nie ma cienkiej odmiany kroju, przeglądarka pokaże zwykłą.
    styl.css CSS zmienione: 7 linii
    body {
        font-family: Helvetica;
        background-color: #DDD;
        color: #546E7A;
    }
    #left, #right {
        background-color: white;
        height: 600px;
        margin: 20px;
        box-shadow: 0 0 20px gray;
    }
    #left {
        width: 50%;
    }
    #right {
        width: 30%;
    }
    section {
        float: left;
    }
    footer {
        clear: both;
    }
    footer {
        background-color: #5C6BC0;
        color: white;
        padding: 30px;
    }
    img {
        width: 100%;
    }
    h1 {
        background-color: #5C6BC0;
        color: white;
        padding: 10px;
        margin: 0;
        font-weight: 300;
    }
    Podgląd strony po tym kroku (index.php)
  32. Krok 32: Nagłówki trzeciego stopnia i paragrafy: wcięcie 30 px

    Kryteria:

    R.4.7 Ustawiono marginesy zewnętrzne (margin) 20px dla bloku lewego i prawego; 0 dla h1 oraz marginesy wewnętrzne (padding) 30px dla stopki; 10px dla h1; lewy 30px (padding-left) dla selektora h3 i selektora p (wystarczy 5 z 7 cech)

    ok. 1 min
    Polecenie z arkusza

    Dla selektora nagłówka trzeciego stopnia i paragrafu (akapitu): margines wewnętrzny lewy 30 px

    padding-left: 30px - napisy „dane”, „adres”, dane pracownika i liczba odsuwają się od lewej krawędzi bloku. Marginesy zewnętrzne i wewnętrzne z arkusza są kompletne (R.4.7).

    styl.css CSS zmienione: 3 linie
    body {
        font-family: Helvetica;
        background-color: #DDD;
        color: #546E7A;
    }
    #left, #right {
        background-color: white;
        height: 600px;
        margin: 20px;
        box-shadow: 0 0 20px gray;
    }
    #left {
        width: 50%;
    }
    #right {
        width: 30%;
    }
    section {
        float: left;
    }
    footer {
        clear: both;
    }
    footer {
        background-color: #5C6BC0;
        color: white;
        padding: 30px;
    }
    img {
        width: 100%;
    }
    h1 {
        background-color: #5C6BC0;
        color: white;
        padding: 10px;
        margin: 0;
        font-weight: 300;
    }
    h3, p {
        padding-left: 30px;
    }
    Podgląd strony po tym kroku (index.php)
  33. Krok 33: Nagłówki drugiego i czwartego stopnia: wyśrodkowanie

    Kryteria:

    R.4.6 Ustawiono wyrównanie tekstu do środka dla selektora h2 i h4

    ok. 1 min
    Polecenie z arkusza

    Dla selektora nagłówka drugiego i czwartego stopnia: wyrównanie tekstu do środka

    Imię i nazwisko (h2) i nazwa stanowiska (h4) w bloku prawym będą na środku; opis stanowiska w h5 zostaje przy lewej krawędzi, jak na obrazie 2 (R.4.6). Efekt zobaczysz po napisaniu skryptu 3.

    styl.css CSS zmienione: 3 linie
    body {
        font-family: Helvetica;
        background-color: #DDD;
        color: #546E7A;
    }
    #left, #right {
        background-color: white;
        height: 600px;
        margin: 20px;
        box-shadow: 0 0 20px gray;
    }
    #left {
        width: 50%;
    }
    #right {
        width: 30%;
    }
    section {
        float: left;
    }
    footer {
        clear: both;
    }
    footer {
        background-color: #5C6BC0;
        color: white;
        padding: 30px;
    }
    img {
        width: 100%;
    }
    h1 {
        background-color: #5C6BC0;
        color: white;
        padding: 10px;
        margin: 0;
        font-weight: 300;
    }
    h3, p {
        padding-left: 30px;
    }
    h2, h4 {
        text-align: center;
    }
    Podgląd strony po tym kroku (index.php)
  34. Etap 4: Skrypty PHP

    Kroki 34-51 · po tym etapie masz 37 z 37 kryteriów (pkt)

    Krok 34: Skrypt 1: połączenie z bazą firma

    Kryteria:

    R.5.1 Skrypt realizuje połączenie z serwerem bazy danych i wybór bazy firma

    ok. 3 min
    Polecenie z arkusza

    Skrypt: Napisany w języku PHP. Skrypt łączy się z serwerem bazy danych na localhost, użytkownik root bez hasła, baza danych o nazwie firma

    Dane pracownika mają stać pod nagłówkiem „Akta Pracownicze”, więc tam zaczyna się skrypt 1 - między <?php a ?>. Pierwsza instrukcja to mysqli_connect z tabeli 1 arkusza: serwer localhost, użytkownik root, puste hasło '' i nazwa bazy firma jako czwarty argument - to od razu wybór bazy, mysqli_select_db nie jest potrzebne (R.5.1). Połączenie trafia do zmiennej $connection; skorzystają z niej wszystkie trzy skrypty.

    Od tego kroku podgląd to wynik działania strony na serwerze (prawdziwe uruchomienie w PHP 8.2) - na razie wygląda jak wcześniej. Stronę otwierasz przez http://localhost/…/index.php, a nie z dysku: przeglądarka sama nie wykona PHP.

    index.php PHP zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sekretariat</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <section id="left">
            <h1>Akta Pracownicze</h1>
            <?php
            $connection = mysqli_connect('localhost', 'root', '', 'firma');
            ?>
            <hr>
            <h3>Dokumenty pracownika</h3>
            <a href="cv.txt">Pobierz</a>
            <h1>Liczba zatrudnionych pracowników</h1>
            <p>
            </p>
        </section>
        <section id="right">
        </section>
        <footer>
            Autorem aplikacji jest: Bartosz Bryniarski
            <ul>
                <li>skontaktuj się</li>
                <li>poznaj naszą firmę</li>
            </ul>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  35. Krok 35: Skrypt 1: zapytanie 1 i wiersz wyniku

    Kryteria:

    R.5.3 Przynajmniej jedno zapytanie zostało wysłane do bazy: skrypt 1 - zapytanie 1 lub skrypt 2 - zapytanie 2 lub skrypt 3 - zapytanie 3 lub 4

    ok. 3 min
    Polecenie z arkusza

    Skrypt 1 wysyła do bazy zapytanie 1 i zwrócone zapytaniem dane wypisuje według schematu:

    • mysqli_query($connection, '…') wysyła zapytanie 1 przekopiowane z kwerendy.txt i zwraca wynik (R.5.3),
    • mysqli_fetch_row($result) pobiera z wyniku jeden wiersz jako tablicę numerowaną od zera: $row[0] to imię, $row[1] nazwisko, $row[2] adres, $row[3] miasto, $row[4] czyRODO, $row[5] czyBadania - kolejność jak w SELECT.

    Zapytanie zwraca jeden wiersz (warunek id = 2), więc pętla nie jest potrzebna. Strona jeszcze niczego nie wypisuje.

    index.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sekretariat</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <section id="left">
            <h1>Akta Pracownicze</h1>
            <?php
            $connection = mysqli_connect('localhost', 'root', '', 'firma');
            $result = mysqli_query($connection, 'SELECT imie, nazwisko, adres, miasto, czyRODO, czyBadania FROM pracownicy WHERE id = 2;');
            $row = mysqli_fetch_row($result);
            ?>
            <hr>
            <h3>Dokumenty pracownika</h3>
            <a href="cv.txt">Pobierz</a>
            <h1>Liczba zatrudnionych pracowników</h1>
            <p>
            </p>
        </section>
        <section id="right">
        </section>
        <footer>
            Autorem aplikacji jest: Bartosz Bryniarski
            <ul>
                <li>skontaktuj się</li>
                <li>poznaj naszą firmę</li>
            </ul>
        </footer>
    </body>
    </html>

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

  36. Krok 36: Skrypt 1: nagłówek „dane”

    ok. 1 min
    Polecenie z arkusza

    Nagłówek trzeciego stopnia o treści „dane”

    echo wypisuje tekst do strony - także znaczniki HTML. Przeglądarka dostaje gotowy <h3>dane</h3> i nie wie, że wypisał go skrypt.

    index.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sekretariat</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <section id="left">
            <h1>Akta Pracownicze</h1>
            <?php
            $connection = mysqli_connect('localhost', 'root', '', 'firma');
            $result = mysqli_query($connection, 'SELECT imie, nazwisko, adres, miasto, czyRODO, czyBadania FROM pracownicy WHERE id = 2;');
            $row = mysqli_fetch_row($result);
            echo "<h3>dane</h3>";
            ?>
            <hr>
            <h3>Dokumenty pracownika</h3>
            <a href="cv.txt">Pobierz</a>
            <h1>Liczba zatrudnionych pracowników</h1>
            <p>
            </p>
        </section>
        <section id="right">
        </section>
        <footer>
            Autorem aplikacji jest: Bartosz Bryniarski
            <ul>
                <li>skontaktuj się</li>
                <li>poznaj naszą firmę</li>
            </ul>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  37. Krok 37: Skrypt 1: imię i nazwisko w paragrafie

    ok. 2 min
    Polecenie z arkusza

    Paragraf z imieniem i nazwiskiem wybranymi z bazy

    W napisie w cudzysłowach PHP podstawia wartości zmiennych: "<p>$row[0] $row[1]</p>" daje <p>Anna Nowak</p>. Spacja między zmiennymi to spacja między imieniem a nazwiskiem. W apostrofach podstawienie nie działa - na stronie pojawiłby się napis $row[0].

    Typowe błędy

    $row[0]$row[1] bez spacji daje „AnnaNowak”.

    index.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sekretariat</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <section id="left">
            <h1>Akta Pracownicze</h1>
            <?php
            $connection = mysqli_connect('localhost', 'root', '', 'firma');
            $result = mysqli_query($connection, 'SELECT imie, nazwisko, adres, miasto, czyRODO, czyBadania FROM pracownicy WHERE id = 2;');
            $row = mysqli_fetch_row($result);
            echo "<h3>dane</h3>";
            echo "<p>$row[0] $row[1]</p>";
            ?>
            <hr>
            <h3>Dokumenty pracownika</h3>
            <a href="cv.txt">Pobierz</a>
            <h1>Liczba zatrudnionych pracowników</h1>
            <p>
            </p>
        </section>
        <section id="right">
        </section>
        <footer>
            Autorem aplikacji jest: Bartosz Bryniarski
            <ul>
                <li>skontaktuj się</li>
                <li>poznaj naszą firmę</li>
            </ul>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  38. Krok 38: Skrypt 1: pierwsza linia horyzontalna

    ok. 1 min
    Polecenie z arkusza

    Linia horyzontalna

    echo "<hr>"; - linia pod imieniem i nazwiskiem.

    index.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sekretariat</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <section id="left">
            <h1>Akta Pracownicze</h1>
            <?php
            $connection = mysqli_connect('localhost', 'root', '', 'firma');
            $result = mysqli_query($connection, 'SELECT imie, nazwisko, adres, miasto, czyRODO, czyBadania FROM pracownicy WHERE id = 2;');
            $row = mysqli_fetch_row($result);
            echo "<h3>dane</h3>";
            echo "<p>$row[0] $row[1]</p>";
            echo "<hr>";
            ?>
            <hr>
            <h3>Dokumenty pracownika</h3>
            <a href="cv.txt">Pobierz</a>
            <h1>Liczba zatrudnionych pracowników</h1>
            <p>
            </p>
        </section>
        <section id="right">
        </section>
        <footer>
            Autorem aplikacji jest: Bartosz Bryniarski
            <ul>
                <li>skontaktuj się</li>
                <li>poznaj naszą firmę</li>
            </ul>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  39. Krok 39: Skrypt 1: nagłówek „adres”

    ok. 1 min
    Polecenie z arkusza

    Nagłówek trzeciego stopnia o treści „adres”

    Drugi nagłówek <h3> wypisany przez skrypt.

    index.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sekretariat</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <section id="left">
            <h1>Akta Pracownicze</h1>
            <?php
            $connection = mysqli_connect('localhost', 'root', '', 'firma');
            $result = mysqli_query($connection, 'SELECT imie, nazwisko, adres, miasto, czyRODO, czyBadania FROM pracownicy WHERE id = 2;');
            $row = mysqli_fetch_row($result);
            echo "<h3>dane</h3>";
            echo "<p>$row[0] $row[1]</p>";
            echo "<hr>";
            echo "<h3>adres</h3>";
            ?>
            <hr>
            <h3>Dokumenty pracownika</h3>
            <a href="cv.txt">Pobierz</a>
            <h1>Liczba zatrudnionych pracowników</h1>
            <p>
            </p>
        </section>
        <section id="right">
        </section>
        <footer>
            Autorem aplikacji jest: Bartosz Bryniarski
            <ul>
                <li>skontaktuj się</li>
                <li>poznaj naszą firmę</li>
            </ul>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  40. Krok 40: Skrypt 1: adres i miasto w osobnych paragrafach

    ok. 1 min
    Polecenie z arkusza

    Paragraf z adresem oraz paragraf z miastem wybranymi z bazy

    Dwa paragrafy: $row[2] (ul. Piekarska 6) i $row[3] (Bytom) - jak na obrazie 2, każde w osobnej linii.

    index.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sekretariat</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <section id="left">
            <h1>Akta Pracownicze</h1>
            <?php
            $connection = mysqli_connect('localhost', 'root', '', 'firma');
            $result = mysqli_query($connection, 'SELECT imie, nazwisko, adres, miasto, czyRODO, czyBadania FROM pracownicy WHERE id = 2;');
            $row = mysqli_fetch_row($result);
            echo "<h3>dane</h3>";
            echo "<p>$row[0] $row[1]</p>";
            echo "<hr>";
            echo "<h3>adres</h3>";
            echo "<p>$row[2]</p>";
            echo "<p>$row[3]</p>";
            ?>
            <hr>
            <h3>Dokumenty pracownika</h3>
            <a href="cv.txt">Pobierz</a>
            <h1>Liczba zatrudnionych pracowników</h1>
            <p>
            </p>
        </section>
        <section id="right">
        </section>
        <footer>
            Autorem aplikacji jest: Bartosz Bryniarski
            <ul>
                <li>skontaktuj się</li>
                <li>poznaj naszą firmę</li>
            </ul>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  41. Krok 41: Skrypt 1: druga linia horyzontalna

    Kryteria:

    R.5.4 Skrypt 1 wyświetla w bloku lewym imię, nazwisko, adres i miasto oraz linie horyzontalne zgodne z obrazem 2 w arkuszu egzaminacyjnym

    ok. 1 min
    Polecenie z arkusza

    Linia horyzontalna

    Druga linia ze skryptu. Imię, nazwisko, adres, miasto i obie linie są na swoich miejscach - zgodnie z obrazem 2 (R.5.4).

    index.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sekretariat</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <section id="left">
            <h1>Akta Pracownicze</h1>
            <?php
            $connection = mysqli_connect('localhost', 'root', '', 'firma');
            $result = mysqli_query($connection, 'SELECT imie, nazwisko, adres, miasto, czyRODO, czyBadania FROM pracownicy WHERE id = 2;');
            $row = mysqli_fetch_row($result);
            echo "<h3>dane</h3>";
            echo "<p>$row[0] $row[1]</p>";
            echo "<hr>";
            echo "<h3>adres</h3>";
            echo "<p>$row[2]</p>";
            echo "<p>$row[3]</p>";
            echo "<hr>";
            ?>
            <hr>
            <h3>Dokumenty pracownika</h3>
            <a href="cv.txt">Pobierz</a>
            <h1>Liczba zatrudnionych pracowników</h1>
            <p>
            </p>
        </section>
        <section id="right">
        </section>
        <footer>
            Autorem aplikacji jest: Bartosz Bryniarski
            <ul>
                <li>skontaktuj się</li>
                <li>poznaj naszą firmę</li>
            </ul>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  42. Krok 42: Skrypt 1: status dokumentu RODO

    Kryteria:

    R.5.5 W skrypcie 1 zastosowano przynajmniej jedną instrukcję warunkową lub wyboru do sprawdzenia wartości zmiennej czyRODO lub czyBadania. Na stronie wyświetlony jest przynajmniej jeden komunikat zgodnie z wartością zmiennej logicznej

    ok. 2 min
    Polecenie z arkusza

    Paragraf o treści „RODO: podpisano” lub „RODO: niepodpisano” w zależności od wartości pola czyRODO zwróconego zapytaniem. Operacja musi mieć charakter uniwersalny niezależnie od wartości zwracanej kwerendą 1

    Instrukcja warunkowa if … else: gdy pole czyRODO ($row[4]) jest równe 1 - „podpisano”, w każdym innym przypadku - „niepodpisano”. To jest ten „uniwersalny charakter”: napis zależy od wartości z bazy, a nie jest wpisany na stałe dla Anny Nowak (R.5.5). Sprawdzone na pracowniku o id 3 (Katarzyna Kowalska, czyRODO = 0): strona wypisuje „RODO: niepodpisano”.

    Typowe błędy

    Samo echo "<p>RODO: podpisano</p>"; daje dla Anny Nowak ten sam obraz strony, ale nie spełnia R.5.5 - klucz wymaga instrukcji warunkowej.

    index.php PHP zmienione: 5 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sekretariat</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <section id="left">
            <h1>Akta Pracownicze</h1>
            <?php
            $connection = mysqli_connect('localhost', 'root', '', 'firma');
            $result = mysqli_query($connection, 'SELECT imie, nazwisko, adres, miasto, czyRODO, czyBadania FROM pracownicy WHERE id = 2;');
            $row = mysqli_fetch_row($result);
            echo "<h3>dane</h3>";
            echo "<p>$row[0] $row[1]</p>";
            echo "<hr>";
            echo "<h3>adres</h3>";
            echo "<p>$row[2]</p>";
            echo "<p>$row[3]</p>";
            echo "<hr>";
            if ($row[4] == 1) {
                echo "<p>RODO: podpisano</p>";
            } else {
                echo "<p>RODO: niepodpisano</p>";
            }
            ?>
            <hr>
            <h3>Dokumenty pracownika</h3>
            <a href="cv.txt">Pobierz</a>
            <h1>Liczba zatrudnionych pracowników</h1>
            <p>
            </p>
        </section>
        <section id="right">
        </section>
        <footer>
            Autorem aplikacji jest: Bartosz Bryniarski
            <ul>
                <li>skontaktuj się</li>
                <li>poznaj naszą firmę</li>
            </ul>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  43. Krok 43: Skrypt 1: status badań pracowniczych

    ok. 2 min
    Polecenie z arkusza

    Paragraf o treści „Badania: aktualne” lub „Badania: nieaktualne” w zależności od wartości pola czyBadania zwróconego zapytaniem. Operacja musi mieć charakter uniwersalny niezależnie od wartości zwracanej kwerendą 1

    Ta sama konstrukcja dla $row[5] (czyBadania). Sprawdzone na pracowniku o id 4 (Ewelina Rak, czyBadania = 0): „Badania: nieaktualne”. Pod skryptem stoi linia <hr> z HTML-u - trzecia linia z obrazu 2.

    index.php PHP zmienione: 5 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sekretariat</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <section id="left">
            <h1>Akta Pracownicze</h1>
            <?php
            $connection = mysqli_connect('localhost', 'root', '', 'firma');
            $result = mysqli_query($connection, 'SELECT imie, nazwisko, adres, miasto, czyRODO, czyBadania FROM pracownicy WHERE id = 2;');
            $row = mysqli_fetch_row($result);
            echo "<h3>dane</h3>";
            echo "<p>$row[0] $row[1]</p>";
            echo "<hr>";
            echo "<h3>adres</h3>";
            echo "<p>$row[2]</p>";
            echo "<p>$row[3]</p>";
            echo "<hr>";
            if ($row[4] == 1) {
                echo "<p>RODO: podpisano</p>";
            } else {
                echo "<p>RODO: niepodpisano</p>";
            }
            if ($row[5] == 1) {
                echo "<p>Badania: aktualne</p>";
            } else {
                echo "<p>Badania: nieaktualne</p>";
            }
            ?>
            <hr>
            <h3>Dokumenty pracownika</h3>
            <a href="cv.txt">Pobierz</a>
            <h1>Liczba zatrudnionych pracowników</h1>
            <p>
            </p>
        </section>
        <section id="right">
        </section>
        <footer>
            Autorem aplikacji jest: Bartosz Bryniarski
            <ul>
                <li>skontaktuj się</li>
                <li>poznaj naszą firmę</li>
            </ul>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  44. Krok 44: Skrypt 2: liczba pracowników w paragrafie

    Kryteria:

    R.5.6 Skrypt 2 wyświetla wartość zwróconą zapytaniem 2

    ok. 2 min
    Polecenie z arkusza

    Skrypt 2 wysyła do bazy zapytanie 2 i wypisuje liczbę wybraną zapytaniem

    Skrypt 2 stoi wewnątrz przygotowanego paragrafu. Połączenie $connection z poprzedniego skryptu nadal działa - wszystkie bloki <?php jednej strony to jeden program, a zmienne przechodzą z bloku do bloku. Zapytanie 2 zwraca jeden wiersz z jedną kolumną, więc liczba to $row[0]: 9 (R.5.6).

    index.php PHP zmienione: 5 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sekretariat</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <section id="left">
            <h1>Akta Pracownicze</h1>
            <?php
            $connection = mysqli_connect('localhost', 'root', '', 'firma');
            $result = mysqli_query($connection, 'SELECT imie, nazwisko, adres, miasto, czyRODO, czyBadania FROM pracownicy WHERE id = 2;');
            $row = mysqli_fetch_row($result);
            echo "<h3>dane</h3>";
            echo "<p>$row[0] $row[1]</p>";
            echo "<hr>";
            echo "<h3>adres</h3>";
            echo "<p>$row[2]</p>";
            echo "<p>$row[3]</p>";
            echo "<hr>";
            if ($row[4] == 1) {
                echo "<p>RODO: podpisano</p>";
            } else {
                echo "<p>RODO: niepodpisano</p>";
            }
            if ($row[5] == 1) {
                echo "<p>Badania: aktualne</p>";
            } else {
                echo "<p>Badania: nieaktualne</p>";
            }
            ?>
            <hr>
            <h3>Dokumenty pracownika</h3>
            <a href="cv.txt">Pobierz</a>
            <h1>Liczba zatrudnionych pracowników</h1>
            <p>
                <?php
                $result = mysqli_query($connection, 'SELECT COUNT(*) FROM pracownicy;');
                $row = mysqli_fetch_row($result);
                echo $row[0];
                ?>
            </p>
        </section>
        <section id="right">
        </section>
        <footer>
            Autorem aplikacji jest: Bartosz Bryniarski
            <ul>
                <li>skontaktuj się</li>
                <li>poznaj naszą firmę</li>
            </ul>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  45. Krok 45: Skrypt 3: zapytanie 3 i nazwa pliku ze zdjęciem

    ok. 3 min
    Polecenie z arkusza

    Zawartość bloku prawego: efekt działania skryptu 3. Skrypt 3 wysyła do bazy zapytanie 3 a następnie: Ustala nazwę pliku obrazu według schematu: „<id>.jpg” gdzie <id> oznacza id zwrócone zapytaniem, a operacja ma charakter uniwersalny niezależnie od zwróconej wartości

    Skrypt 3 w bloku prawym wysyła zapytanie 3: $row[0] to id, $row[1] imię, $row[2] nazwisko. Nazwa pliku powstaje z id i rozszerzenia - operator kropka skleja napisy w PHP: $row[0] . ".jpg" daje "2.jpg". Dla pracownika o id 7 byłoby to 7.jpg - stąd „charakter uniwersalny”.

    index.php PHP zmienione: 5 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sekretariat</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <section id="left">
            <h1>Akta Pracownicze</h1>
            <?php
            $connection = mysqli_connect('localhost', 'root', '', 'firma');
            $result = mysqli_query($connection, 'SELECT imie, nazwisko, adres, miasto, czyRODO, czyBadania FROM pracownicy WHERE id = 2;');
            $row = mysqli_fetch_row($result);
            echo "<h3>dane</h3>";
            echo "<p>$row[0] $row[1]</p>";
            echo "<hr>";
            echo "<h3>adres</h3>";
            echo "<p>$row[2]</p>";
            echo "<p>$row[3]</p>";
            echo "<hr>";
            if ($row[4] == 1) {
                echo "<p>RODO: podpisano</p>";
            } else {
                echo "<p>RODO: niepodpisano</p>";
            }
            if ($row[5] == 1) {
                echo "<p>Badania: aktualne</p>";
            } else {
                echo "<p>Badania: nieaktualne</p>";
            }
            ?>
            <hr>
            <h3>Dokumenty pracownika</h3>
            <a href="cv.txt">Pobierz</a>
            <h1>Liczba zatrudnionych pracowników</h1>
            <p>
                <?php
                $result = mysqli_query($connection, 'SELECT COUNT(*) FROM pracownicy;');
                $row = mysqli_fetch_row($result);
                echo $row[0];
                ?>
            </p>
        </section>
        <section id="right">
            <?php
            $result = mysqli_query($connection, 'SELECT id, imie, nazwisko FROM pracownicy WHERE id = 2;');
            $row = mysqli_fetch_row($result);
            $file = $row[0] . ".jpg";
            ?>
        </section>
        <footer>
            Autorem aplikacji jest: Bartosz Bryniarski
            <ul>
                <li>skontaktuj się</li>
                <li>poznaj naszą firmę</li>
            </ul>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  46. Krok 46: Skrypt 3: zdjęcie z tekstem alternatywnym

    Kryteria: ,

    R.2.8 W bloku prawym umieszczono obraz z tekstem alternatywnym "pracownik" (w skrypcie lub HTML)

    R.5.7 W skrypcie 3 ustalono nazwę pliku na podstawie wartości id zwróconej zapytaniem np. $wiersz[0] = (string) $wiersz[0] . ".jpg"; oraz wyświetlono obraz z pliku o tej nazwie

    ok. 2 min
    Polecenie z arkusza

    Wyświetla obraz o ustalonej nazwie pliku z tekstem alternatywnym o treści „pracownik”

    echo wypisuje znacznik <img> ze zmienną $file w atrybucie src. Wartości atrybutów są w apostrofach, bo cały napis jest w cudzysłowach - drugi cudzysłów zakończyłby napis PHP. Przeglądarka dostaje <img src='2.jpg' alt='pracownik'> (R.2.8) i wczytuje przeskalowane zdjęcie z folderu strony (R.5.7).

    index.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sekretariat</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <section id="left">
            <h1>Akta Pracownicze</h1>
            <?php
            $connection = mysqli_connect('localhost', 'root', '', 'firma');
            $result = mysqli_query($connection, 'SELECT imie, nazwisko, adres, miasto, czyRODO, czyBadania FROM pracownicy WHERE id = 2;');
            $row = mysqli_fetch_row($result);
            echo "<h3>dane</h3>";
            echo "<p>$row[0] $row[1]</p>";
            echo "<hr>";
            echo "<h3>adres</h3>";
            echo "<p>$row[2]</p>";
            echo "<p>$row[3]</p>";
            echo "<hr>";
            if ($row[4] == 1) {
                echo "<p>RODO: podpisano</p>";
            } else {
                echo "<p>RODO: niepodpisano</p>";
            }
            if ($row[5] == 1) {
                echo "<p>Badania: aktualne</p>";
            } else {
                echo "<p>Badania: nieaktualne</p>";
            }
            ?>
            <hr>
            <h3>Dokumenty pracownika</h3>
            <a href="cv.txt">Pobierz</a>
            <h1>Liczba zatrudnionych pracowników</h1>
            <p>
                <?php
                $result = mysqli_query($connection, 'SELECT COUNT(*) FROM pracownicy;');
                $row = mysqli_fetch_row($result);
                echo $row[0];
                ?>
            </p>
        </section>
        <section id="right">
            <?php
            $result = mysqli_query($connection, 'SELECT id, imie, nazwisko FROM pracownicy WHERE id = 2;');
            $row = mysqli_fetch_row($result);
            $file = $row[0] . ".jpg";
            echo "<img src='$file' alt='pracownik'>";
            ?>
        </section>
        <footer>
            Autorem aplikacji jest: Bartosz Bryniarski
            <ul>
                <li>skontaktuj się</li>
                <li>poznaj naszą firmę</li>
            </ul>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  47. Krok 47: Skrypt 3: imię i nazwisko w nagłówku

    Kryteria:

    R.5.8 Skrypt 3 wyświetla imię i nazwisko zwrócone zapytaniem

    ok. 1 min
    Polecenie z arkusza

    Wyświetla w nagłówku drugiego stopnia imię i nazwisko zwrócone zapytaniem

    <h2> z imieniem i nazwiskiem z zapytania 3 - wyśrodkowany regułą h2, h4 (R.5.8).

    index.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sekretariat</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <section id="left">
            <h1>Akta Pracownicze</h1>
            <?php
            $connection = mysqli_connect('localhost', 'root', '', 'firma');
            $result = mysqli_query($connection, 'SELECT imie, nazwisko, adres, miasto, czyRODO, czyBadania FROM pracownicy WHERE id = 2;');
            $row = mysqli_fetch_row($result);
            echo "<h3>dane</h3>";
            echo "<p>$row[0] $row[1]</p>";
            echo "<hr>";
            echo "<h3>adres</h3>";
            echo "<p>$row[2]</p>";
            echo "<p>$row[3]</p>";
            echo "<hr>";
            if ($row[4] == 1) {
                echo "<p>RODO: podpisano</p>";
            } else {
                echo "<p>RODO: niepodpisano</p>";
            }
            if ($row[5] == 1) {
                echo "<p>Badania: aktualne</p>";
            } else {
                echo "<p>Badania: nieaktualne</p>";
            }
            ?>
            <hr>
            <h3>Dokumenty pracownika</h3>
            <a href="cv.txt">Pobierz</a>
            <h1>Liczba zatrudnionych pracowników</h1>
            <p>
                <?php
                $result = mysqli_query($connection, 'SELECT COUNT(*) FROM pracownicy;');
                $row = mysqli_fetch_row($result);
                echo $row[0];
                ?>
            </p>
        </section>
        <section id="right">
            <?php
            $result = mysqli_query($connection, 'SELECT id, imie, nazwisko FROM pracownicy WHERE id = 2;');
            $row = mysqli_fetch_row($result);
            $file = $row[0] . ".jpg";
            echo "<img src='$file' alt='pracownik'>";
            echo "<h2>$row[1] $row[2]</h2>";
            ?>
        </section>
        <footer>
            Autorem aplikacji jest: Bartosz Bryniarski
            <ul>
                <li>skontaktuj się</li>
                <li>poznaj naszą firmę</li>
            </ul>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  48. Krok 48: Skrypt 3: zapytanie 4

    ok. 2 min
    Polecenie z arkusza

    Wysyła do bazy zapytanie 4

    Kolejne zapytanie w tym samym skrypcie: zmienne $result i $row dostają nowe wartości - $row[0] to id, $row[1] nazwa stanowiska, $row[2] opis. Imię i nazwisko są już wypisane, więc stare wartości nie są potrzebne.

    index.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sekretariat</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <section id="left">
            <h1>Akta Pracownicze</h1>
            <?php
            $connection = mysqli_connect('localhost', 'root', '', 'firma');
            $result = mysqli_query($connection, 'SELECT imie, nazwisko, adres, miasto, czyRODO, czyBadania FROM pracownicy WHERE id = 2;');
            $row = mysqli_fetch_row($result);
            echo "<h3>dane</h3>";
            echo "<p>$row[0] $row[1]</p>";
            echo "<hr>";
            echo "<h3>adres</h3>";
            echo "<p>$row[2]</p>";
            echo "<p>$row[3]</p>";
            echo "<hr>";
            if ($row[4] == 1) {
                echo "<p>RODO: podpisano</p>";
            } else {
                echo "<p>RODO: niepodpisano</p>";
            }
            if ($row[5] == 1) {
                echo "<p>Badania: aktualne</p>";
            } else {
                echo "<p>Badania: nieaktualne</p>";
            }
            ?>
            <hr>
            <h3>Dokumenty pracownika</h3>
            <a href="cv.txt">Pobierz</a>
            <h1>Liczba zatrudnionych pracowników</h1>
            <p>
                <?php
                $result = mysqli_query($connection, 'SELECT COUNT(*) FROM pracownicy;');
                $row = mysqli_fetch_row($result);
                echo $row[0];
                ?>
            </p>
        </section>
        <section id="right">
            <?php
            $result = mysqli_query($connection, 'SELECT id, imie, nazwisko FROM pracownicy WHERE id = 2;');
            $row = mysqli_fetch_row($result);
            $file = $row[0] . ".jpg";
            echo "<img src='$file' alt='pracownik'>";
            echo "<h2>$row[1] $row[2]</h2>";
            $result = mysqli_query($connection, 'SELECT pracownicy.id, nazwa, opis FROM pracownicy JOIN stanowiska ON pracownicy.stanowiska_id = stanowiska.id WHERE pracownicy.id = 2;');
            $row = mysqli_fetch_row($result);
            ?>
        </section>
        <footer>
            Autorem aplikacji jest: Bartosz Bryniarski
            <ul>
                <li>skontaktuj się</li>
                <li>poznaj naszą firmę</li>
            </ul>
        </footer>
    </body>
    </html>

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

  49. Krok 49: Skrypt 3: nazwa stanowiska

    ok. 1 min
    Polecenie z arkusza

    Wyświetla nazwę stanowiska w nagłówku czwartego stopnia

    <h4> z nazwą „kierownik”, wyśrodkowany.

    index.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sekretariat</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <section id="left">
            <h1>Akta Pracownicze</h1>
            <?php
            $connection = mysqli_connect('localhost', 'root', '', 'firma');
            $result = mysqli_query($connection, 'SELECT imie, nazwisko, adres, miasto, czyRODO, czyBadania FROM pracownicy WHERE id = 2;');
            $row = mysqli_fetch_row($result);
            echo "<h3>dane</h3>";
            echo "<p>$row[0] $row[1]</p>";
            echo "<hr>";
            echo "<h3>adres</h3>";
            echo "<p>$row[2]</p>";
            echo "<p>$row[3]</p>";
            echo "<hr>";
            if ($row[4] == 1) {
                echo "<p>RODO: podpisano</p>";
            } else {
                echo "<p>RODO: niepodpisano</p>";
            }
            if ($row[5] == 1) {
                echo "<p>Badania: aktualne</p>";
            } else {
                echo "<p>Badania: nieaktualne</p>";
            }
            ?>
            <hr>
            <h3>Dokumenty pracownika</h3>
            <a href="cv.txt">Pobierz</a>
            <h1>Liczba zatrudnionych pracowników</h1>
            <p>
                <?php
                $result = mysqli_query($connection, 'SELECT COUNT(*) FROM pracownicy;');
                $row = mysqli_fetch_row($result);
                echo $row[0];
                ?>
            </p>
        </section>
        <section id="right">
            <?php
            $result = mysqli_query($connection, 'SELECT id, imie, nazwisko FROM pracownicy WHERE id = 2;');
            $row = mysqli_fetch_row($result);
            $file = $row[0] . ".jpg";
            echo "<img src='$file' alt='pracownik'>";
            echo "<h2>$row[1] $row[2]</h2>";
            $result = mysqli_query($connection, 'SELECT pracownicy.id, nazwa, opis FROM pracownicy JOIN stanowiska ON pracownicy.stanowiska_id = stanowiska.id WHERE pracownicy.id = 2;');
            $row = mysqli_fetch_row($result);
            echo "<h4>$row[1]</h4>";
            ?>
        </section>
        <footer>
            Autorem aplikacji jest: Bartosz Bryniarski
            <ul>
                <li>skontaktuj się</li>
                <li>poznaj naszą firmę</li>
            </ul>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  50. Krok 50: Skrypt 3: opis stanowiska

    Kryteria: ,

    R.2.6 W bloku lewym zapisano: jeden z nagłówków h1: "Akta Pracownicze" lub "Liczba zatrudnionych pracowników"; przynajmniej jeden nagłówek h3: "dane", "adres", "Dokumenty pracownika" (w skrypcie lub HTML) oraz przynajmniej jeden paragraf. W bloku prawym zapisano nagłówki h2, h4, h5 (w skrypcie lub HTML)

    R.5.9 Skrypt 3 wyświetla nazwę stanowiska oraz opis stanowiska zwrócone zapytaniem

    ok. 1 min
    Polecenie z arkusza

    Wyświetla opis stanowiska w nagłówku piątego stopnia

    <h5> z opisem - bez wyśrodkowania, przy lewej krawędzi bloku, jak na obrazie 2. Komplet nagłówków w obu blokach jest na stronie (R.2.6, R.5.9).

    index.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sekretariat</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <section id="left">
            <h1>Akta Pracownicze</h1>
            <?php
            $connection = mysqli_connect('localhost', 'root', '', 'firma');
            $result = mysqli_query($connection, 'SELECT imie, nazwisko, adres, miasto, czyRODO, czyBadania FROM pracownicy WHERE id = 2;');
            $row = mysqli_fetch_row($result);
            echo "<h3>dane</h3>";
            echo "<p>$row[0] $row[1]</p>";
            echo "<hr>";
            echo "<h3>adres</h3>";
            echo "<p>$row[2]</p>";
            echo "<p>$row[3]</p>";
            echo "<hr>";
            if ($row[4] == 1) {
                echo "<p>RODO: podpisano</p>";
            } else {
                echo "<p>RODO: niepodpisano</p>";
            }
            if ($row[5] == 1) {
                echo "<p>Badania: aktualne</p>";
            } else {
                echo "<p>Badania: nieaktualne</p>";
            }
            ?>
            <hr>
            <h3>Dokumenty pracownika</h3>
            <a href="cv.txt">Pobierz</a>
            <h1>Liczba zatrudnionych pracowników</h1>
            <p>
                <?php
                $result = mysqli_query($connection, 'SELECT COUNT(*) FROM pracownicy;');
                $row = mysqli_fetch_row($result);
                echo $row[0];
                ?>
            </p>
        </section>
        <section id="right">
            <?php
            $result = mysqli_query($connection, 'SELECT id, imie, nazwisko FROM pracownicy WHERE id = 2;');
            $row = mysqli_fetch_row($result);
            $file = $row[0] . ".jpg";
            echo "<img src='$file' alt='pracownik'>";
            echo "<h2>$row[1] $row[2]</h2>";
            $result = mysqli_query($connection, 'SELECT pracownicy.id, nazwa, opis FROM pracownicy JOIN stanowiska ON pracownicy.stanowiska_id = stanowiska.id WHERE pracownicy.id = 2;');
            $row = mysqli_fetch_row($result);
            echo "<h4>$row[1]</h4>";
            echo "<h5>$row[2]</h5>";
            ?>
        </section>
        <footer>
            Autorem aplikacji jest: Bartosz Bryniarski
            <ul>
                <li>skontaktuj się</li>
                <li>poznaj naszą firmę</li>
            </ul>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  51. Krok 51: Zamknięcie połączenia

    Kryteria:

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

    ok. 1 min
    Polecenie z arkusza

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

    mysqli_close($connection) jako ostatnia instrukcja skryptu 3 - ostatniego miejsca na stronie, które korzysta z bazy (R.5.2). Gdyby zamknięcie stało w skrypcie 1, skrypty 2 i 3 nie miałyby już połączenia.

    index.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sekretariat</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <section id="left">
            <h1>Akta Pracownicze</h1>
            <?php
            $connection = mysqli_connect('localhost', 'root', '', 'firma');
            $result = mysqli_query($connection, 'SELECT imie, nazwisko, adres, miasto, czyRODO, czyBadania FROM pracownicy WHERE id = 2;');
            $row = mysqli_fetch_row($result);
            echo "<h3>dane</h3>";
            echo "<p>$row[0] $row[1]</p>";
            echo "<hr>";
            echo "<h3>adres</h3>";
            echo "<p>$row[2]</p>";
            echo "<p>$row[3]</p>";
            echo "<hr>";
            if ($row[4] == 1) {
                echo "<p>RODO: podpisano</p>";
            } else {
                echo "<p>RODO: niepodpisano</p>";
            }
            if ($row[5] == 1) {
                echo "<p>Badania: aktualne</p>";
            } else {
                echo "<p>Badania: nieaktualne</p>";
            }
            ?>
            <hr>
            <h3>Dokumenty pracownika</h3>
            <a href="cv.txt">Pobierz</a>
            <h1>Liczba zatrudnionych pracowników</h1>
            <p>
                <?php
                $result = mysqli_query($connection, 'SELECT COUNT(*) FROM pracownicy;');
                $row = mysqli_fetch_row($result);
                echo $row[0];
                ?>
            </p>
        </section>
        <section id="right">
            <?php
            $result = mysqli_query($connection, 'SELECT id, imie, nazwisko FROM pracownicy WHERE id = 2;');
            $row = mysqli_fetch_row($result);
            $file = $row[0] . ".jpg";
            echo "<img src='$file' alt='pracownik'>";
            echo "<h2>$row[1] $row[2]</h2>";
            $result = mysqli_query($connection, 'SELECT pracownicy.id, nazwa, opis FROM pracownicy JOIN stanowiska ON pracownicy.stanowiska_id = stanowiska.id WHERE pracownicy.id = 2;');
            $row = mysqli_fetch_row($result);
            echo "<h4>$row[1]</h4>";
            echo "<h5>$row[2]</h5>";
            mysqli_close($connection);
            ?>
        </section>
        <footer>
            Autorem aplikacji jest: Bartosz Bryniarski
            <ul>
                <li>skontaktuj się</li>
                <li>poznaj naszą firmę</li>
            </ul>
        </footer>
    </body>
    </html>

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

  52. Etap 5: Dobre praktyki (poza kluczem)

    Kroki 52-54 · po tym etapie masz 37 z 37 kryteriów (pkt)

    Krok 52: Zabezpieczenie: htmlspecialchars na danych z bazy

    ok. 4 min
    Polecenie z arkusza

    Skrypt 1 wysyła do bazy zapytanie 1 i zwrócone zapytaniem dane wypisuje według schematu:

    Skrypty wypisują dane z bazy wprost. Sprawdzone: gdy w bazie stoi nazwisko Nowak<script>alert("XSS")</script> (wystarczy, że ktoś wpisze je w formularz kadrowy, który zapisuje dane bez kontroli), strona wysyła ten kod do przeglądarki dwa razy - w paragrafie i w nagłówku <h2> - i przeglądarka go wykonuje. To jest XSS (wstrzyknięcie kodu): skrypt z bazy działa w przeglądarce każdej osoby, która otworzy akta - może np. wysłać komuś jej ciasteczka sesji.

    htmlspecialchars zamienia znaki specjalne HTML na encje: < na &lt;, > na &gt;, cudzysłów na &quot;. Przeglądarka pokazuje je jako zwykłe znaki i niczego nie wykonuje. Zamiast poprawiać każde echo, cały wiersz przechodzi przez funkcję od razu po pobraniu z bazy: array_map wywołuje ją dla każdego elementu tablicy, a fn($value) => … to krótki zapis funkcji jednej linii. (string) zamienia ewentualne NULL z bazy na pusty napis - nowe PHP ostrzega przy htmlspecialchars(null).

    Podgląd tego kroku pokazuje stronę z rekordem-atakiem: kod wyświetla się jako tekst. Dla prawdziwych danych strona wygląda tak samo jak wcześniej.

    Typowe błędy

    htmlspecialchars przy zapisie do bazy zamiast przy wypisywaniu psuje dane (w bazie lądują encje) i nie chroni przed rekordami dopisanymi inną drogą. Zabezpiecza się wyjście - tam, gdzie dane trafiają do HTML-u.

    index.php PHP zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sekretariat</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <section id="left">
            <h1>Akta Pracownicze</h1>
            <?php
            $connection = mysqli_connect('localhost', 'root', '', 'firma');
            $result = mysqli_query($connection, 'SELECT imie, nazwisko, adres, miasto, czyRODO, czyBadania FROM pracownicy WHERE id = 2;');
            $row = mysqli_fetch_row($result);
            $row = array_map(fn($value) => htmlspecialchars((string) $value), $row);
            echo "<h3>dane</h3>";
            echo "<p>$row[0] $row[1]</p>";
            echo "<hr>";
            echo "<h3>adres</h3>";
            echo "<p>$row[2]</p>";
            echo "<p>$row[3]</p>";
            echo "<hr>";
            if ($row[4] == 1) {
                echo "<p>RODO: podpisano</p>";
            } else {
                echo "<p>RODO: niepodpisano</p>";
            }
            if ($row[5] == 1) {
                echo "<p>Badania: aktualne</p>";
            } else {
                echo "<p>Badania: nieaktualne</p>";
            }
            ?>
            <hr>
            <h3>Dokumenty pracownika</h3>
            <a href="cv.txt">Pobierz</a>
            <h1>Liczba zatrudnionych pracowników</h1>
            <p>
                <?php
                $result = mysqli_query($connection, 'SELECT COUNT(*) FROM pracownicy;');
                $row = mysqli_fetch_row($result);
                echo $row[0];
                ?>
            </p>
        </section>
        <section id="right">
            <?php
            $result = mysqli_query($connection, 'SELECT id, imie, nazwisko FROM pracownicy WHERE id = 2;');
            $row = mysqli_fetch_row($result);
            $row = array_map(fn($value) => htmlspecialchars((string) $value), $row);
            $file = $row[0] . ".jpg";
            echo "<img src='$file' alt='pracownik'>";
            echo "<h2>$row[1] $row[2]</h2>";
            $result = mysqli_query($connection, 'SELECT pracownicy.id, nazwa, opis FROM pracownicy JOIN stanowiska ON pracownicy.stanowiska_id = stanowiska.id WHERE pracownicy.id = 2;');
            $row = mysqli_fetch_row($result);
            $row = array_map(fn($value) => htmlspecialchars((string) $value), $row);
            echo "<h4>$row[1]</h4>";
            echo "<h5>$row[2]</h5>";
            mysqli_close($connection);
            ?>
        </section>
        <footer>
            Autorem aplikacji jest: Bartosz Bryniarski
            <ul>
                <li>skontaktuj się</li>
                <li>poznaj naszą firmę</li>
            </ul>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  53. Krok 53: Zabezpieczenie: zapytania przygotowane

    ok. 5 min
    Polecenie z arkusza

    Skrypt 3 wysyła do bazy zapytanie 3 a następnie:

    Na egzaminie numer pracownika jest wpisany w zapytanie na stałe. W prawdziwej aplikacji przyjdzie z adresu, np. index.php?id=2, a doklejony do treści zapytania zamieni się w SQL injection. Sprawdzone w MariaDB: gdy zamiast 2 trafi tam napis 2 OR 1=1, zapytanie 1 ma warunek WHERE id = 2 OR 1=1, który jest prawdziwy dla wszystkich 9 pracowników, a mysqli_fetch_row pokazuje pierwszego z nich - Jana Nowaka zamiast Anny. Atakujący odczytuje w ten sposób akta, do których nie powinien mieć dostępu.

    Numer trafia teraz do zmiennej $id, a trzy zapytania z warunkiem idą jako zapytania przygotowane:

    • mysqli_prepare - treść zapytania ze znakiem ? w miejscu danych,
    • mysqli_stmt_bind_param($statement, 'i', $id) - dane osobno, z typem i (liczba całkowita),
    • mysqli_stmt_execute i mysqli_stmt_get_result - wykonanie i wynik, z którego mysqli_fetch_row czyta tak jak wcześniej.

    Baza dostaje zapytanie i dane oddzielnie, więc dane nigdy nie staną się kodem SQL. Sprawdzone w PHP: z $id = "2 OR 1=1" strona pokazuje Annę Nowak, bo typ i zamienia napis na liczbę 2. Zapytanie 2 nie ma żadnych danych z zewnątrz i zostaje bez zmian. Stare linie zostają w komentarzu.

    Typowe błędy

    Liczba liter w 'i' musi równać się liczbie znaków ? i liczbie zmiennych - inaczej mysqli_stmt_bind_param zgłosi błąd.

    index.php PHP zmienione: 16 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sekretariat</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <section id="left">
            <h1>Akta Pracownicze</h1>
            <?php
            $connection = mysqli_connect('localhost', 'root', '', 'firma');
            $id = 2;
            // $result = mysqli_query($connection, 'SELECT imie, nazwisko, adres, miasto, czyRODO, czyBadania FROM pracownicy WHERE id = 2;');
            $statement = mysqli_prepare($connection, 'SELECT imie, nazwisko, adres, miasto, czyRODO, czyBadania FROM pracownicy WHERE id = ?;');
            mysqli_stmt_bind_param($statement, 'i', $id);
            mysqli_stmt_execute($statement);
            $result = mysqli_stmt_get_result($statement);
            $row = mysqli_fetch_row($result);
            $row = array_map(fn($value) => htmlspecialchars((string) $value), $row);
            echo "<h3>dane</h3>";
            echo "<p>$row[0] $row[1]</p>";
            echo "<hr>";
            echo "<h3>adres</h3>";
            echo "<p>$row[2]</p>";
            echo "<p>$row[3]</p>";
            echo "<hr>";
            if ($row[4] == 1) {
                echo "<p>RODO: podpisano</p>";
            } else {
                echo "<p>RODO: niepodpisano</p>";
            }
            if ($row[5] == 1) {
                echo "<p>Badania: aktualne</p>";
            } else {
                echo "<p>Badania: nieaktualne</p>";
            }
            ?>
            <hr>
            <h3>Dokumenty pracownika</h3>
            <a href="cv.txt">Pobierz</a>
            <h1>Liczba zatrudnionych pracowników</h1>
            <p>
                <?php
                $result = mysqli_query($connection, 'SELECT COUNT(*) FROM pracownicy;');
                $row = mysqli_fetch_row($result);
                echo $row[0];
                ?>
            </p>
        </section>
        <section id="right">
            <?php
            // $result = mysqli_query($connection, 'SELECT id, imie, nazwisko FROM pracownicy WHERE id = 2;');
            $statement = mysqli_prepare($connection, 'SELECT id, imie, nazwisko FROM pracownicy WHERE id = ?;');
            mysqli_stmt_bind_param($statement, 'i', $id);
            mysqli_stmt_execute($statement);
            $result = mysqli_stmt_get_result($statement);
            $row = mysqli_fetch_row($result);
            $row = array_map(fn($value) => htmlspecialchars((string) $value), $row);
            $file = $row[0] . ".jpg";
            echo "<img src='$file' alt='pracownik'>";
            echo "<h2>$row[1] $row[2]</h2>";
            // $result = mysqli_query($connection, 'SELECT pracownicy.id, nazwa, opis FROM pracownicy JOIN stanowiska ON pracownicy.stanowiska_id = stanowiska.id WHERE pracownicy.id = 2;');
            $statement = mysqli_prepare($connection, 'SELECT pracownicy.id, nazwa, opis FROM pracownicy JOIN stanowiska ON pracownicy.stanowiska_id = stanowiska.id WHERE pracownicy.id = ?;');
            mysqli_stmt_bind_param($statement, 'i', $id);
            mysqli_stmt_execute($statement);
            $result = mysqli_stmt_get_result($statement);
            $row = mysqli_fetch_row($result);
            $row = array_map(fn($value) => htmlspecialchars((string) $value), $row);
            echo "<h4>$row[1]</h4>";
            echo "<h5>$row[2]</h5>";
            mysqli_close($connection);
            ?>
        </section>
        <footer>
            Autorem aplikacji jest: Bartosz Bryniarski
            <ul>
                <li>skontaktuj się</li>
                <li>poznaj naszą firmę</li>
            </ul>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  54. Krok 54: Konto root bez hasła tylko na egzaminie

    ok. 2 min
    Polecenie z arkusza

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

    Arkusz każe łączyć się kontem root bez hasła - w XAMPP to konto administratora całego serwera bazy danych, które może usunąć każdą bazę. Na egzaminie tak zostaje (R.5.1). W prawdziwym serwisie strona dostaje osobne konto z hasłem i tylko z tymi prawami, których potrzebuje - tu wystarczy odczyt:

    CREATE USER 'sekretariat'@'localhost' IDENTIFIED BY 'długie-losowe-hasło';
    GRANT SELECT ON firma.* TO 'sekretariat'@'localhost';
    

    Wtedy nawet udany atak na stronę nie zmieni ani nie usunie danych. Hasła do bazy trzyma się w osobnym pliku konfiguracyjnym, najlepiej poza folderem dostępnym z przeglądarki - tak, by nie trafiło do repozytorium kodu ani na zrzut ekranu. Plik strony bez zmian.

    index.php PHP zmienione: 0 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sekretariat</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <section id="left">
            <h1>Akta Pracownicze</h1>
            <?php
            $connection = mysqli_connect('localhost', 'root', '', 'firma');
            $id = 2;
            // $result = mysqli_query($connection, 'SELECT imie, nazwisko, adres, miasto, czyRODO, czyBadania FROM pracownicy WHERE id = 2;');
            $statement = mysqli_prepare($connection, 'SELECT imie, nazwisko, adres, miasto, czyRODO, czyBadania FROM pracownicy WHERE id = ?;');
            mysqli_stmt_bind_param($statement, 'i', $id);
            mysqli_stmt_execute($statement);
            $result = mysqli_stmt_get_result($statement);
            $row = mysqli_fetch_row($result);
            $row = array_map(fn($value) => htmlspecialchars((string) $value), $row);
            echo "<h3>dane</h3>";
            echo "<p>$row[0] $row[1]</p>";
            echo "<hr>";
            echo "<h3>adres</h3>";
            echo "<p>$row[2]</p>";
            echo "<p>$row[3]</p>";
            echo "<hr>";
            if ($row[4] == 1) {
                echo "<p>RODO: podpisano</p>";
            } else {
                echo "<p>RODO: niepodpisano</p>";
            }
            if ($row[5] == 1) {
                echo "<p>Badania: aktualne</p>";
            } else {
                echo "<p>Badania: nieaktualne</p>";
            }
            ?>
            <hr>
            <h3>Dokumenty pracownika</h3>
            <a href="cv.txt">Pobierz</a>
            <h1>Liczba zatrudnionych pracowników</h1>
            <p>
                <?php
                $result = mysqli_query($connection, 'SELECT COUNT(*) FROM pracownicy;');
                $row = mysqli_fetch_row($result);
                echo $row[0];
                ?>
            </p>
        </section>
        <section id="right">
            <?php
            // $result = mysqli_query($connection, 'SELECT id, imie, nazwisko FROM pracownicy WHERE id = 2;');
            $statement = mysqli_prepare($connection, 'SELECT id, imie, nazwisko FROM pracownicy WHERE id = ?;');
            mysqli_stmt_bind_param($statement, 'i', $id);
            mysqli_stmt_execute($statement);
            $result = mysqli_stmt_get_result($statement);
            $row = mysqli_fetch_row($result);
            $row = array_map(fn($value) => htmlspecialchars((string) $value), $row);
            $file = $row[0] . ".jpg";
            echo "<img src='$file' alt='pracownik'>";
            echo "<h2>$row[1] $row[2]</h2>";
            // $result = mysqli_query($connection, 'SELECT pracownicy.id, nazwa, opis FROM pracownicy JOIN stanowiska ON pracownicy.stanowiska_id = stanowiska.id WHERE pracownicy.id = 2;');
            $statement = mysqli_prepare($connection, 'SELECT pracownicy.id, nazwa, opis FROM pracownicy JOIN stanowiska ON pracownicy.stanowiska_id = stanowiska.id WHERE pracownicy.id = ?;');
            mysqli_stmt_bind_param($statement, 'i', $id);
            mysqli_stmt_execute($statement);
            $result = mysqli_stmt_get_result($statement);
            $row = mysqli_fetch_row($result);
            $row = array_map(fn($value) => htmlspecialchars((string) $value), $row);
            echo "<h4>$row[1]</h4>";
            echo "<h5>$row[2]</h5>";
            mysqli_close($connection);
            ?>
        </section>
        <footer>
            Autorem aplikacji jest: Bartosz Bryniarski
            <ul>
                <li>skontaktuj się</li>
                <li>poznaj naszą firmę</li>
            </ul>
        </footer>
    </body>
    </html>

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

  55. Etap 6: Oddanie pracy

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

    Krok 55: Nagranie płyty

    ok. 5 min
    Polecenie z arkusza

    UWAGA: katalog z rezultatami pracy oraz płytę należy opisać numerem, którym został podpisany arkusz, czyli numerem PESEL lub w przypadku jego braku numerem paszportu.

    W folderze z numerem zdającego muszą być: 2.jpg (przeskalowany), cv.txt, import.jpg, kw1.png - kw4.png, kwerendy.txt, index.php i styl.css. Jeśli pracujesz w htdocs, skopiuj aktualne pliki do folderu na pulpicie. Nagraj płytę, sprawdź jej odczyt i opisz ją numerem zdającego.

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

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