Strona PHP pokazuje kod, pustą stronę albo błąd - przyczyny i naprawa
Oprogramowanie: XAMPP 8.2.12 (PHP 8.2.12), Windows 10
Dlaczego XAMPP pokazuje kod PHP zamiast wyniku, co znaczą Parse error, Undefined array key i Fatal error mysqli oraz skąd biorą się krzaki.
Skrypt PHP z arkusza INF.03 nie zadziałał: zamiast listy z bazy widać kod, białą stronę albo komunikat po angielsku. Klucze oceniania przewidują taki przypadek („Jeśli witryna nie uruchamia się z powodu błędów PHP - sprawdzić wg kryteriów w kodzie źródłowym strony”), ale za działanie strony punktów wtedy nie ma, więc warto umieć szybko znaleźć przyczynę.
Każdy przypadek z tego tutorialu został wywołany naprawdę na jednym małym skrypcie z bazą opony (z arkusza INF.03-11-25.06-SG). Zrzuty pochodzą z XAMPP 8.2.12 z PHP 8.2.12 w Windows 10 i przeglądarki Microsoft Edge, 11 października 2026 r. Treść komunikatów błędów zależy od wersji PHP - starsze wersje piszą je inaczej.
Egzaminy ZawodoweINF.03
Jak korzystać z tutoriala
Suwak i strzałki obok niego - albo ←→ na klawiaturze - przechodzą krok po kroku; wyjaśnienie i podgląd zmieniają się razem z krokiem.
Lista „Etap” przenosi od razu do wybranego etapu.
„Tryb prezentacji” pokazuje same kroki, bez menu strony - na rzutnik.
Etap 1: Punkt wyjścia
Krok 1
Krok 1: Punkt wyjścia: działający skrypt
ok. 2 min
Plik C:\xampp\htdocs\opony\klienci.php łączy się z bazą opony (z arkusza INF.03-11-25.06-SG) i wypisuje listę klientów. Otwarty pod adresem localhost/opony/klienci.php działa: widać nagłówek i dziewięć nazwisk, w tym „Elżbieta Kościow” z poprawnymi polskimi literami. Najważniejszy fragment pliku:
<?php
$polaczenie = mysqli_connect("localhost", "root", "", "opony");
mysqli_set_charset($polaczenie, "utf8");
$wynik = mysqli_query($polaczenie, "SELECT imie, nazwisko FROM klient");
while ($w = mysqli_fetch_row($wynik)) {
echo "<li>$w[0] $w[1]</li>";
}
mysqli_close($polaczenie);
?>
Każda kolejna część tutorialu psuje ten plik w jeden sposób i pokazuje, jak wygląda skutek.
Zrzut ekranu po tym kroku
Etap 2: Kod zamiast wyniku
Kroki 2-6
Krok 2: Widać kod PHP: plik otwarty przez file://
ok. 1 min
Ten sam plik otwarty dwuklikiem w Eksploratorze ma w pasku adresu Plik i ścieżkę C:/xampp/htdocs/... (adres file:///). Przeglądarka czyta plik z dysku z pominięciem serwera, więc PHP nic nie wykonuje i na ekranie jest surowy kod. Rozwiązanie: wpisz adres przez serwer - localhost/opony/klienci.php.
Typowe błędy
Adres localhost/... odpowiada folderowi C:\xampp\htdocs\.... Plik leżący poza htdocs (np. w folderze z numerem zdającego na pulpicie) nie ma żadnego adresu localhost - do testowania skopiuj pracę do htdocs albo pracuj w htdocs i na końcu przenieś pliki do folderu na pulpicie.
Zrzut ekranu po tym kroku
Krok 3: Plik zapisany jako .html
ok. 1 min
Ten sam kod zapisany jako klienci.html i otwarty przez localhost wygląda inaczej: nagłówek jest, a w miejscu listy stoi fragment w rodzaju $w[0] $w[1]"; } mysqli_close($polaczenie); ?>. Apache wykonuje PHP tylko w plikach .php; w pliku .html przeglądarka traktuje <?php jak nieznany znacznik i pokazuje resztę jako tekst.
Typowe błędy
Arkusz zawsze podaje nazwę strony z rozszerzeniem (np. opony.php, islandia.php). Strona ze skryptem PHP musi mieć .php, inaczej skrypt się nie wykona - a klucz każe wtedy oceniać kod źródłowy, bez punktów za działanie.
Zrzut ekranu po tym kroku
Krok 4: Źródło strony: Ctrl+U
ok. 1 min
Naciśnij Ctrl+U, żeby zobaczyć, co naprawdę przyszło z serwera. Przy pliku .html w źródle jest cały kod PHP, od <?php do ?> - dowód, że serwer go nie wykonał. Przy pliku .php w źródle zobaczysz tylko gotowy HTML (wynik pętli while).
Zrzut ekranu po tym kroku
Krok 5: Plik klienci.php.txt
ok. 1 min
Notatnik przy typie „Dokumenty tekstowe” dopisuje .txt. Plik klienci.php.txt otwarty przez localhost pokazuje kod czcionką maszynową, jak zwykły tekst - serwer wysłał go jako plik tekstowy. W pasku adresu widać pełną nazwę z .txt na końcu.
Typowe błędy
W Notatniku przy Zapisz jako wybierz typ Wszystkie pliki i wpisz nazwę z .php. Włącz w Eksploratorze Widok → Rozszerzenia nazw plików, żeby od razu widzieć podwójne rozszerzenia.
Zrzut ekranu po tym kroku
Krok 6: Not Found: zły folder w adresie
ok. 1 min
Komunikat Not Found - The requested URL was not found on this server z podpisem Apache i PHP 8.2.12 oznacza, że serwer działa, ale pod tym adresem nie ma pliku. Tu w adresie jest localhost/opona/... zamiast localhost/opony/.... Sprawdź nazwę folderu w htdocs i nazwę pliku znak po znaku.
Zrzut ekranu po tym kroku
Etap 3: Komunikaty PHP
Kroki 7-10
Krok 7: Parse error: brak średnika
ok. 2 min
Usunięcie średnika na końcu wiersza z mysqli_query(...) daje białą stronę z jednym zdaniem: Parse error: syntax error, unexpected token "while" in C:\xampp\htdocs\opony\srednik.php on line 14. Przy błędzie składni PHP nie wykonuje niczego, nawet HTML-a sprzed <?php. Numer wiersza wskazuje miejsce, w którym parser się zgubił - brakujący średnik jest zwykle wiersz wyżej.
Typowe błędy
Ten sam objaw dają niedomknięty cudzysłów i brakujący nawias }. Jeśli wskazany wiersz wygląda dobrze, sprawdź koniec poprzedniego.
Zrzut ekranu po tym kroku
Krok 8: Warning: Undefined array key
ok. 1 min
Formularz i skrypt w jednym pliku: $imie = $_POST["imie"]; na górze skryptu. Przy pierwszym wejściu na stronę formularz nie był jeszcze wysłany, więc tablica $_POST jest pusta i PHP 8 wypisuje Warning: Undefined array key "imie" z numerem wiersza, a pod spodem „Dziękujemy, !” z pustym imieniem.
Typowe błędy
To ostrzeżenie, nie błąd krytyczny - strona działa dalej, ale komunikat jest widoczny dla użytkownika. Starsze wersje PHP (7.x) wypisywały w tym miejscu słabiej widoczne „Notice”. W XAMPP komunikaty są włączone (display_errors=On w php.ini), dlatego widać je w przeglądarce.
Zrzut ekranu po tym kroku
Krok 9: Sprawdź, czy formularz został wysłany
ok. 2 min
Odczyt danych formularza otocz warunkiem:
if (isset($_POST["imie"])) {
$imie = $_POST["imie"];
echo "<p>Dziękujemy, $imie!</p>";
}
Przy pierwszym wejściu strona pokazuje sam formularz, bez ostrzeżenia.
Typowe błędy
Samo isset sprawdza, czy pole przyszło, a nie czy jest wypełnione - przy pustym polu formularz wysyła pusty napis. Gdy arkusz wymaga reakcji tylko na wypełnione pole, użyj !empty($_POST["imie"]).
Zrzut ekranu po tym kroku
Krok 10: Formularz po wysłaniu
ok. 1 min
Po wpisaniu imienia i kliknięciu Wyślij warunek jest spełniony i pod formularzem pojawia się „Dziękujemy, Anna!”.
Zrzut ekranu po tym kroku
Etap 4: Błędy połączenia z bazą
Kroki 11-14
Krok 11: Fatal error: Unknown database
ok. 1 min
Literówka w nazwie bazy w mysqli_connect (tu opona zamiast opony) kończy skrypt: Fatal error: Uncaught mysqli_sql_exception: Unknown database 'opona'. W PHP 8.1 i nowszym mysqli domyślnie zgłasza wyjątek zamiast cicho zwracać false, więc strona urywa się w miejscu połączenia - HTML poniżej już się nie wyświetla.
Typowe błędy
Nazwę bazy w skrypcie kopiuj z drzewa phpMyAdmin albo z treści arkusza. Tak samo kończy się zła nazwa tabeli w zapytaniu („Table 'opony.klienci' doesn't exist”) - zapytanie przetestuj najpierw w zakładce SQL phpMyAdmin.
Zrzut ekranu po tym kroku
Krok 12: MySQL zatrzymany w panelu XAMPP
ok. 1 min
Inny częsty powód: serwer bazy nie działa. W panelu XAMPP wiersz MySQL ma szare tło, przycisk Start, a w dzienniku „Status change detected: stopped” (np. po ponownym uruchomieniu komputera).
Zrzut ekranu po tym kroku
Krok 13: Fatal error: odmowa połączenia
ok. 1 min
Skrypt przy zatrzymanym MySQL kończy się komunikatem Fatal error: Uncaught mysqli_sql_exception: Nie można nawiązać połączenia, ponieważ komputer docelowy aktywnie go odmawia. Kliknij Start przy MySQL w panelu XAMPP i odśwież stronę.
Zrzut ekranu po tym kroku
Krok 14: phpMyAdmin też nie działa bez MySQL
ok. 1 min
Przy zatrzymanym MySQL phpMyAdmin pokazuje czerwone bloki: „Cannot connect: invalid settings”, „mysqli::real_connect(): (HY000/2002)” i „phpMyAdmin próbował połączyć się z serwerem MySQL, a serwer odrzucił połączenie”. To nie jest błąd ustawień - wystarczy uruchomić MySQL i kliknąć Ponów podłączenie.
Zrzut ekranu po tym kroku
Etap 5: Polskie znaki
Kroki 15-17
Krok 15: Krzaki w pliku .html bez meta charset
ok. 1 min
Strona witaj.html zapisana w UTF-8, ale bez znacznika <meta charset="UTF-8">, pokazuje „zażółć” zamiast „zażółć”. Apache nie wysyła dla plików .html informacji o kodowaniu, więc przeglądarka zgaduje - i zgaduje źle.
Typowe błędy
Krzaki w danych z bazy, widoczne także w phpMyAdmin, nie pochodzą ze strony, tylko z importu pliku .sql ze złym zestawem znaków - opisuje to tutorial o imporcie bazy.
Zrzut ekranu po tym kroku
Krok 16: Ten sam plik z meta charset
ok. 1 min
Po dopisaniu w sekcji head wiersza <meta charset="UTF-8"> (jako pierwszego) polskie litery wyświetlają się poprawnie. Ten znacznik jest też kryterium w kluczu - np. R.2.2 w INF.03-01-26.06-SG: „W sekcji head znajduje się jawnie podany standard kodowania polskich znaków”.
Zrzut ekranu po tym kroku
Krok 17: A mysqli_set_charset?
ok. 1 min
Sprawdzone w tym XAMPP (PHP 8.2.12, MariaDB 10.4.32): plik .phpbez<meta charset> i bezmysqli_set_charset też pokazał „Elżbieta Kościow” poprawnie, bo PHP wysyła nagłówek charset=UTF-8, a połączenie z bazą domyślnie używa UTF-8. Mimo to pisz oba: meta charset jest oceniany w kluczu, a mysqli_set_charset ($polaczenie, "utf8") zabezpiecza przed krzakami na innym serwerze, z inną konfiguracją.
Typowe błędy
Jeśli krzaki pojawiają się tylko w tekście pisanym w pliku (nagłówki, etykiety), a dane z bazy są dobre, plik został zapisany w innym kodowaniu niż UTF-8. W Notatniku przy Zapisz jako wybierz Kodowanie: UTF-8.