Egzamin praktyczny: skrypt PHP z bazą i skrypt JavaScript

INF.03 · teoria
autor: redakcja · 09.09.2026
Skrypt PHP, który łączy się z localhost jako root bez hasła z bazą egzamin i na końcu zamyka połączenie. Funkcje mysqli ze ściągi CKE, wiersze jako lista i jako tabela, dane z formularza w klauzuli WHERE, skrypt JavaScript zmieniający kolory strony. Lekcja 13.4 kursu INF.03.
Ta lekcja składa skryp­ty wy­ma­ga­ne przez arkusz, czyli ostat­ni z pięciu oce­nia­nych re­zul­ta­tów, „skrypt po­łą­cze­nia z bazą", oraz tę część re­zul­ta­tu „dzia­ła­nie wi­try­ny in­ter­ne­to­wej", która zależy od kodu. Robi się to na końcu za­da­nia, gdy baza jest już za­im­por­to­wa­na, a strona i styl stoją. Cztery skryp­ty wra­ca­ją w ar­ku­szach niemal bez zmian: dwa wy­pi­su­ją wier­sze z bazy według wzoru, trzeci bierze dane z for­mu­la­rza, czwar­ty zmie­nia w JavaScripcie wygląd całej strony. Teoria samych funk­cji jest w lekcji o PHP i bazie danych oraz w lekcji o modelu DOM, tutaj liczy się ko­lej­ność ruchów i miej­sca, w któ­rych re­zul­tat prze­pa­da.

Po­łą­cze­nie, które arkusz opi­su­je do­słow­nie

Wy­ma­ga­nia po­łą­cze­nia arkusz wy­pi­su­je zdanie po zdaniu i za każdym razem brzmią tak samo: skrypt „na­pi­sa­ny w języku PHP", „łączy się z ser­we­rem ba­zo­da­no­wym na lo­cal­host, użyt­kow­nik root bez hasła, baza danych o nazwie eg­za­min", a „na końcu dzia­ła­nia skrypt zamyka po­łą­cze­nie z ser­we­rem". Nazwa bazy bywa inna, bo bierze się z treści za­da­nia, ale adres, użyt­kow­nik i puste hasło są stałe, tak samo jak za­mknię­cie po­łą­cze­nia w ostat­nim wier­szu.
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
$polaczenie = mysqli_connect('localhost', 'root', '', 'egzamin');
if (!$polaczenie) {
die('Blad polaczenia z baza');
}
$wynik = mysqli_query($polaczenie, 'SELECT nazwa, miasto, cena FROM nocleg');
if (!$wynik) {
die(mysqli_error($polaczenie));
}
while ($w = mysqli_fetch_array($wynik)) {
echo '<li>' . $w['nazwa'] . '</li>';
}
mysqli_close($polaczenie);
Czwar­ty pa­ra­metr mysqli_connect wy­bie­ra bazę od razu. Drugi do­pusz­czal­ny zapis to po­łą­cze­nie z trzema pa­ra­me­tra­mi i osobne mysqli_select_db($polaczenie, 'egzamin'), obie wersje są w tabeli do­łą­czo­nej do ar­ku­sza. Puste apo­stro­fy na trze­cim miej­scu to konto bez hasła i nie wolno ich za­mie­nić na słowo root.
Arkusz do­kła­da do za­da­nia tabelę „Wybór funk­cji języka PHP do ob­słu­gi bazy MySQL i MariaDB", więc nazw nie trzeba pa­mię­tać co do znaku. Trzeba na­to­miast wie­dzieć, co która robi.
Funk­cja z tabeli ar­ku­sza
Co robi
mysqli_connect
otwie­ra po­łą­cze­nie z ser­we­rem bazy
mysqli_select_db
wy­bie­ra bazę na otwar­tym po­łą­cze­niu
mysqli_query
wysyła jedno za­py­ta­nie SQL
mysqli_fetch_row
po­bie­ra ko­lej­ny wiersz z nu­me­ra­mi kolumn od zera
mysqli_fetch_array
po­bie­ra ko­lej­ny wiersz z nu­me­ra­mi i na­zwa­mi kolumn
mysqli_num_rows
podaje liczbę wier­szy wyniku
mysqli_num_fields
podaje liczbę kolumn wyniku
mysqli_error
oddaje ko­mu­ni­kat o błę­dzie ostat­niej ope­ra­cji
mysqli_close
zamyka po­łą­cze­nie z ser­we­rem
To są nazwy pro­ce­du­ral­ne i tego stylu warto trzy­mać się przez całe za­da­nie. Wersja obiek­to­wa (new mysqli, $polaczenie->query) działa tak samo, ale jej nazw arkusz nie podaje, więc każdą li­te­rów­kę w me­to­dzie trzeba wy­ła­pać sa­mo­dziel­nie, bez ściągi na biurku. Z tego samego powodu w pętli lepiej po­sta­wić mysqli_fetch_array niż mysqli_fetch_assoc: druga funk­cja jest po­praw­na, ale w tabeli ar­ku­sza jej nie ma.
Wszyst­kie skryp­ty PHP z za­da­nia siedzą zwykle w jednym pliku, na przy­kład noclegi.php, w miej­scach wy­zna­czo­nych przez układ strony. Można otwo­rzyć jedno po­łą­cze­nie na po­cząt­ku i za­mknąć je jednym mysqli_close na końcu do­ku­men­tu albo dać każ­de­mu skryp­to­wi własną parę, byle każde otwar­cie miało swoje za­mknię­cie. Pro­ściej spraw­dzić to drugie: liczba wy­wo­łań mysqli_connect ma się zga­dzać z liczbą wy­wo­łań mysqli_close.

Skrypt 1 i 2: wier­sze jako lista i jako wier­sze tabeli

Pierw­sze dwa skryp­ty robią to samo, tylko w innych znacz­ni­kach. Arkusz podaje wzór jednej po­zy­cji, na przy­kład „nazwa noc­le­gu, miasto, cena zł", i wynik ma wy­glą­dać do­kład­nie tak, razem z prze­cin­ka­mi i jed­nost­ką.
1
2
3
4
5
6
7
8
9
<?php
$polaczenie = mysqli_connect('localhost', 'root', '', 'egzamin');
$wynik = mysqli_query($polaczenie, 'SELECT nazwa, miasto, cena FROM nocleg');
echo '<ul>';
while ($w = mysqli_fetch_array($wynik)) {
echo '<li>' . $w['nazwa'] . ', ' . $w['miasto'] . ', ' . $w['cena'] . ' zl</li>';
}
echo '</ul>';
mysqli_close($polaczenie);
1
2
3
Hotel Pod Lipa, Zakopane, 180 zl
Pensjonat Widok, Zakopane, 140 zl
Willa Nad Potokiem, Szczyrk, 210 zl
Znacz­ni­ki <ul> i </ul> stoją poza pętlą, bo lista jest jedna, a po­wta­rza­ją się wy­łącz­nie po­zy­cje. Gdy za­py­ta­nie nic nie znaj­dzie, pętla nie wykona się ani razu i zo­sta­nie pusta lista, dla­te­go przed nią spraw­dza się mysqli_num_rows($wynik).
Drugi skrypt wy­peł­nia wier­sze tabeli. Sam znacz­nik <table> z wier­szem na­głów­ko­wym jest już w kodzie strony, skrypt do­kła­da wy­łącz­nie <tr> z ko­mór­ka­mi. Wy­god­niej­sza jest tu mysqli_fetch_row, bo numery od­po­wia­da­ją ko­lej­no­ści kolumn z SELECT.
1
2
3
4
5
6
7
<?php
$polaczenie = mysqli_connect('localhost', 'root', '', 'egzamin');
$wynik = mysqli_query($polaczenie, 'SELECT nazwa, miasto FROM nocleg ORDER BY nazwa');
while ($w = mysqli_fetch_row($wynik)) {
echo '<tr><td>' . $w[0] . '</td><td>' . $w[1] . '</td></tr>';
}
mysqli_close($polaczenie);
Sor­to­wa­nie i wa­run­ki należą do za­py­ta­nia, nie do PHP: ko­lej­ność bierze się z ORDER BY, a za­wę­że­nie wyniku z WHERE, jak w lekcji o za­py­ta­niu SELECT. Skrypt ma tylko prze­pi­sać wier­sze do znacz­ni­ków.
Pu­łap­ka: jedno wy­wo­ła­nie funk­cji fetch daje jeden wiersz. Wy­wo­ła­na raz, poza pętlą, wy­pi­sze wy­łącz­nie pierw­szy rekord i tabela zo­sta­nie prawie pusta.

Skrypt 3: war­tość z for­mu­la­rza w klau­zu­li WHERE

Trzeci skrypt czyta pole for­mu­la­rza wy­sła­ne­go metodą POST do tej samej strony i wsta­wia jego war­tość do wa­run­ku za­py­ta­nia. Sam for­mu­larz opi­su­je lekcja o for­mu­la­rzach HTML, a odbiór danych lekcja o for­mu­la­rzach w PHP. Klucz w ta­bli­cy $_POST to war­tość atry­bu­tu name pola, nie jego ety­kie­ta.
1
2
3
4
5
<form method="post" action="noclegi.php">
<input type="number" name="cena" min="0">
<input type="submit" value="Szukaj">
<input type="reset" value="Wyczysc">
</form>
1
2
3
4
5
6
7
8
9
10
11
<?php
if (isset($_POST['cena'])) {
$max = (int) $_POST['cena'];
$polaczenie = mysqli_connect('localhost', 'root', '', 'egzamin');
$sql = "SELECT nazwa, miasto, cena FROM nocleg WHERE cena <= $max";
$wynik = mysqli_query($polaczenie, $sql);
while ($w = mysqli_fetch_array($wynik)) {
echo '<li>' . $w['nazwa'] . ', ' . $w['cena'] . ' zl</li>';
}
mysqli_close($polaczenie);
}
Wa­ru­nek isset pil­nu­je, żeby strona otwar­ta po raz pierw­szy, jesz­cze przed wy­sła­niem for­mu­la­rza, nie pró­bo­wa­ła czytać nie­ist­nie­ją­ce­go klucza i nie wy­pi­sa­ła ostrze­że­nia nad ukła­dem strony. War­tość licz­bo­wa wcho­dzi do za­py­ta­nia bez apo­stro­fów, tek­sto­wa wymaga ich wokół siebie: WHERE miasto = '$miasto'. Rzu­to­wa­nie (int) nic nie kosz­tu­je, a odcina wpi­sa­nie w pole frag­men­tu za­py­ta­nia.

Skrypt 4: JavaScript zmie­nia­ją­cy kolory całej strony

Czwar­ty skrypt działa po stro­nie klien­ta i uru­cha­mia go przy­cisk na stro­nie. Za­da­nie brzmi zwykle tak: po klik­nię­ciu zmie­nia­ją się kolory tła i czcion­ki całej wi­try­ny, „np. po­przez do­łą­cze­nie nowego ar­ku­sza stylów". Pola i metody, któ­rych do tego trzeba, są w dru­giej ścią­dze ar­ku­sza, „Wy­bra­ne pola i metody modelu DOM języka JavaScript".
Zapis ze ściągi ar­ku­sza
Co robi
document.getElementById("x")
oddaje ele­ment o iden­ty­fi­ka­to­rze x
document.getElementsByTagName("p")
oddaje ko­lek­cję ele­men­tów danego znacz­ni­ka
document.getElementsByClassName("c")
oddaje ko­lek­cję ele­men­tów danej klasy
element.innerHTML
treść ele­men­tu razem ze znacz­ni­ka­mi
element.setAttribute("href", "styl_2.css")
usta­wia war­tość atry­bu­tu
element.style.property
usta­wia po­je­dyn­czą wła­ści­wość stylu
document.createElement("link")
tworzy nowy ele­ment, jesz­cze poza drze­wem
rodzic.appendChild(element)
dopina ele­ment jako ostat­nie dziec­ko
onclick, onload, onkeyup
zda­rze­nia uru­cha­mia­ją­ce funk­cję
Prost­sza droga to usta­wie­nie wła­ści­wo­ści na ele­men­cie body, czyli na przod­ku wszyst­kich wi­docz­nych ele­men­tów strony. Nazwy wła­ści­wo­ści w JavaScripcie nie mają minusa, drugi człon za­czy­na się wielką literą.
1
2
3
4
function zmienKolory() {
document.body.style.backgroundColor = "Tomato";
document.body.style.color = "Maroon";
}
1
<input type="button" value="Zmien kolory" onclick="zmienKolory()">
Druga droga, ta z cytatu, do­kła­da do sekcji head nowy ele­ment link wska­zu­ją­cy drugi arkusz stylów przy­go­to­wa­ny wcze­śniej. Nazwę tego pliku podaje arkusz, w przy­kła­dzie styl_2.css.
1
2
3
4
5
6
function dolaczStyl() {
var arkusz = document.createElement("link");
arkusz.setAttribute("rel", "stylesheet");
arkusz.setAttribute("href", "styl_2.css");
document.getElementsByTagName("head")[0].appendChild(arkusz);
}
Ob­słu­gę klik­nię­cia wpi­su­je się atry­bu­tem onclick albo przy­pi­su­je w kodzie, co po­ka­zu­je lekcja o zda­rze­niach. Nazwa funk­cji w przy­ci­sku musi zga­dzać się co do znaku z nazwą w de­fi­ni­cji, bo przy po­mył­ce przy­cisk nie robi nic, a ślad po błę­dzie zo­sta­je tylko w kon­so­li prze­glą­dar­ki.
Funk­cja może stać w znacz­ni­ku <script> w tym samym pliku albo w osob­nym pliku do­łą­czo­nym tym samym znacz­ni­kiem z atry­bu­tem src. Arkusz zwykle zo­sta­wia to do wyboru, a wymaga dzia­ła­ją­ce­go przy­ci­sku. De­fi­ni­cja musi zostać wczy­ta­na, zanim ktoś klik­nie, więc bez­piecz­ne miej­sce to koniec sekcji body, tuż przed jej za­mknię­ciem.

Uru­cho­mie­nie i spraw­dze­nie dzia­ła­nia

Plik .php musi leżeć w ka­ta­lo­gu htdocs ser­we­ra XAMPP i zostać otwar­ty ad­re­sem http://localhost/noclegi.php. Otwar­ty po­dwój­nym klik­nię­ciem z dysku nie wykona się wcale: prze­glą­dar­ka pokaże kod albo pustą stronę, bo PHP wy­ko­nu­je serwer, nie ona. W XAMPP Con­trol Panel muszą dzia­łać obie usługi, Apache i MySQL, co opi­su­je lekcja o śro­do­wi­sku. Gotowe pliki za­pi­su­je się w fol­de­rze o nazwie numeru PESEL, razem z resztą wy­ni­ków, według dys­cy­pli­ny plików z pierw­szej lekcji działu.
Re­zul­tat „dzia­ła­nie wi­try­ny in­ter­ne­to­wej" ocenia się z otwar­tej strony, nie z kodu: lista i tabela mają być wy­peł­nio­ne danymi z bazy, for­mu­larz po wy­sła­niu ma wrócić z za­wę­żo­nym wy­ni­kiem, a przy­cisk ma zmie­nić kolory. Sam kod bez po­łą­cze­nia z bazą spraw­dza się w in­ter­pre­te­rze PHP i w in­ter­pre­te­rze JavaScript w prze­glą­dar­ce, a same za­py­ta­nia w placu zabaw SQL w prze­glą­dar­ce.

Gdzie traci się punkty

  • Brak mysqli_close na końcu skryp­tu: za­mknię­cie po­łą­cze­nia arkusz wy­mie­nia jako osobne wy­ma­ga­nie.
  • Hasło inne niż puste albo nazwa bazy wy­my­ślo­na za­miast wzię­tej z treści za­da­nia.
  • Wzór wypisu od­two­rzo­ny nie­do­kład­nie: brak jed­nost­ki, inny prze­ci­nek, ko­lum­ny w innej ko­lej­no­ści niż we wzorze.
  • Znacz­ni­ki <ul> albo <table> wy­pi­sy­wa­ne w pętli, przez co po­wsta­je tyle list, ile jest wier­szy.
  • if za­miast while przy po­bie­ra­niu wier­szy albo fetch wy­wo­ła­ny raz, poza pętlą.
  • Odczyt przez $_GET, gdy arkusz wymaga metody POST, albo klucz inny niż atry­but name pola.
  • Brak isset i ostrze­że­nie PHP wy­pi­sa­ne nad ukła­dem strony przy pierw­szym otwar­ciu.
  • Pol­skie znaki jako py­taj­ni­ki: do­kła­da się wtedy mysqli_set_charset($polaczenie, 'utf8') zaraz po po­łą­cze­niu.
  • Zapis background-color w JavaScripcie za­miast backgroundColor, bo wersja z mi­nu­sem to nazwa z CSS, nie z DOM.
  • Zmiana koloru jed­ne­go aka­pi­tu za­miast całej strony: kolory usta­wia się na body albo nowym ar­ku­szem stylów.
  • document.write wy­wo­ła­ne po wczy­ta­niu strony, które czyści cały do­ku­ment razem z ukła­dem.
  • Skrypt w sekcji head się­ga­ją­cy po ele­ment, któ­re­go prze­glą­dar­ka jesz­cze nie wczy­ta­ła, bez zda­rze­nia onload.
  • Plik za­pi­sa­ny poza fol­de­rem o nazwie numeru PESEL albo pod inną nazwą niż podana w ar­ku­szu.

Ściąga

Zapis
Znaczy
mysqli_connect('localhost', 'root', '', 'egzamin')
serwer, użyt­kow­nik, puste hasło, baza
mysqli_select_db($p, 'egzamin')
wybór bazy na otwar­tym po­łą­cze­niu
mysqli_query($p, $sql)
wysyła za­py­ta­nie, oddaje wynik SELECT
mysqli_fetch_array($wynik)
wiersz z nu­me­ra­mi i na­zwa­mi kolumn
mysqli_fetch_row($wynik)
wiersz z nu­me­ra­mi kolumn od zera
mysqli_num_rows($wynik)
liczba wier­szy wyniku
mysqli_num_fields($wynik)
liczba kolumn wyniku
mysqli_error($p)
ko­mu­ni­kat o błę­dzie ostat­niej ope­ra­cji
mysqli_close($p)
za­mknię­cie po­łą­cze­nia, ostat­ni wiersz skryp­tu
mysqli_set_charset($p, 'utf8')
ra­tu­nek na pol­skie znaki jako py­taj­ni­ki
while ($w = mysqli_fetch_array($wynik))
pętla po wszyst­kich wier­szach wyniku
echo '<li>' . $w['nazwa'] . '</li>';
jedna po­zy­cja listy z jed­ne­go wier­sza
echo '<tr><td>' . $w[0] . '</td></tr>';
jeden wiersz tabeli z jed­ne­go wier­sza wyniku
$_POST['cena']
war­tość pola o atry­bu­cie name="cena"
isset($_POST['cena'])
spraw­dze­nie, czy for­mu­larz został wy­sła­ny
WHERE cena <= $max
liczba w wa­run­ku, bez apo­stro­fów
WHERE miasto = '$miasto'
tekst w wa­run­ku, w apo­stro­fach
document.body.style.backgroundColor
kolor tła całej strony
document.body.style.color
kolor czcion­ki całej strony
document.createElement("link")
nowy ele­ment ar­ku­sza stylów
document.getElementsByTagName("head")[0]
sekcja head z ko­lek­cji
rodzic.appendChild(element)
do­pię­cie ele­men­tu do drzewa
<input type="button" onclick="f()">
przy­cisk uru­cha­mia­ją­cy funk­cję
http://localhost/noclegi.php
jedyny po­praw­ny sposób otwar­cia pliku PHP
Pobierz ściągę PDF
ZAWODNIK
egzamin zawodowy INF.02 · INF.03 · INF.04
Serwer Discord
Egzaminy zawodowe IT/Matury/Studia
@yastor
© 2026 Zawodnik · by Yastor
Arkusze i zasady oceniania pochodzą z CKE. Serwis nie jest powiązany z Centralną Komisją Egzaminacyjną.