Jak zacząć programować w PHP od zera: praktyczny przewodnik dla przyszłych webmasterów

0
32
5/5 - (1 vote)

Spis Treści:

Dlaczego akurat PHP i dla kogo ma to sens

Gdzie PHP faktycznie działa w praktycznym webmasteringu

PHP to język, który od lat napędza ogromną część internetu. Silnik WordPressa, większość popularnych systemów sklepów internetowych, panele administracyjne do stron firmowych, systemy rezerwacji czy proste integracje z bramkami płatności – to wszystko bardzo często działa właśnie na PHP. Dla przyszłego webmastera oznacza to jedno: znajomość PHP otwiera drzwi do pracy z realnymi, produkcyjnymi stronami, a nie wyłącznie z projektami „na uczelnię”.

Jeśli ktoś planuje tworzyć i utrzymywać strony dla małych firm, blogerów, lokalnych sklepów czy fundacji, PHP jest wciąż jednym z najbardziej opłacalnych wyborów. Typowy tani hosting za kilkanaście złotych miesięcznie ma już zainstalowane PHP i MySQL, więc nie trzeba kupować drogiej infrastruktury czy kombinować z kontenerami Dockera. W praktyce wystarczy wrzucić pliki przez FTP i strona działa – to duża przewaga na starcie, szczególnie gdy budżet jest niski.

Wiele narzędzi do tworzenia stron „bez kodowania” (page buildery, kreatory szablonów) również opiera się na PHP pod spodem. Znając podstawy, można delikatnie przerabiać gotowe motywy WordPressa, dodawać własne fragmenty kodu, zmieniać zachowanie wtyczek albo pisać proste moduły. To już jest poziom, na którym łatwo zdobyć pierwsze, płatne zlecenia – nawet jeśli nie opanowało się jeszcze całego języka.

Kiedy nauka PHP ma sens, a kiedy lepiej pójść w inną stronę

PHP to dobry wybór, gdy celem jest szybkie wejście w świat webmasteringu, freelancingu i prostego utrzymania stron. Jeżeli priorytetem jest:

  • stawianie prostych stron z panelem administracyjnym,
  • modyfikacja istniejących serwisów na WordPressie,
  • tworzenie małych systemów: formularzy, prostych paneli, list produktów,
  • zaczęcie zarabiania na stronach WWW w ciągu kilku miesięcy,

– PHP daje dobry balans między czasem nauki a realnym efektem. Wiele rozwiązań ma gotowe biblioteki, fragmenty kodu i poradniki, dzięki którym można zbudować coś działającego bez doktoratu z informatyki.

Jeśli natomiast celem jest w dłuższej perspektywie praca przy dużych aplikacjach webowych czasu rzeczywistego, rozbudowanych panelach typu SPA, grach przeglądarkowych czy systemach o architekturze mikroserwisów, wtedy często lepszą ścieżką będzie JavaScript (Node.js), Python, Java lub C#. To nie oznacza, że PHP jest „gorsze”, tylko że ma inne główne zastosowania. Z perspektywy przyszłego webmastera PHP wygrywa prostotą wdrożenia i dostępnością taniej infrastruktury.

Co da się zrealizować po 2–3 miesiącach nauki PHP

Przy rozsądnym podejściu – 1–2 godziny dziennie, regularnie – po kilku miesiącach można już:

  • zbudować prostą stronę wizytówkę z dynamicznymi elementami (np. lista aktualności, galeria, oferta z panelu),
  • napisać formularz kontaktowy z walidacją, wysyłką e-maila i komunikatami o błędach,
  • stworzyć mini CMS do zarządzania treścią: logowanie, dodawanie i edycja wpisów,
  • zintegrować stronę z prostą bazą danych MySQL (lista zadań, komentarze, ankiety),
  • korzystać z podstawowych API (np. wysłanie danych do zewnętrznej usługi, pobranie kursu walut).

To już jest poziom, na którym można brać najprostsze zlecenia: przeróbka formularza, drobne modyfikacje w motywie WordPressa, dodanie prostego modułu. Największą blokadą nie jest tu znajomość całego języka, ale umiejętność diagnozowania błędów, rozumienie przepływu danych i zachowanie porządku w projekcie.

Czego PHP za ciebie nie zrobi

PHP generuje HTML i obsługuje logikę po stronie serwera, ale nie zastępuje całej reszty układanki. Żeby działała realna strona WWW, potrzeba:

  • HTML – struktura treści, nagłówki, formularze, listy, tabele,
  • CSS – wygląd: kolory, układ, responsywność,
  • serwer/hosting – miejsce, gdzie fizycznie leżą pliki i baza danych,
  • domena – adres strony, który użytkownik wpisuje w przeglądarce.

PHP nie sprawi automatycznie, że strona będzie „ładna” – to kwestia HTML/CSS lub gotowego szablonu. Nie rozwiąże też błędów konfiguracji serwera czy problemów z DNS. Dlatego dobry webmaster zna podstawy całego procesu: od pliku na dysku lokalnym po stronę wyświetlaną u klienta. PHP jest jednym z kluczowych elementów, ale nie jedynym.

Osoba pisząca kod PHP na laptopie z naklejkami programistycznymi
Źródło: Pexels | Autor: Anna Shvets

Tanie i szybkie przygotowanie środowiska – bez przepłacania

Wybór systemu operacyjnego a wygoda pracy w PHP

PHP działa na każdym popularnym systemie: Windows, Linux i macOS. Z punktu widzenia początkującego webmastera ważne jest, żeby środowisko było stabilne i tanie (lub darmowe) oraz dawało możliwość pracy podobnej do tej na typowym hostingu.

Praktyczne podejście:

  • Windows – najczęstsza opcja na komputerach domowych. W połączeniu z XAMPP lub Laragonem pozwala szybko postawić lokalny serwer. Kilka kliknięć i można odpalać pierwszy skrypt PHP. Dobra opcja „na start” dla większości osób.
  • Linux (np. Ubuntu) – świetny do pracy developerskiej i bardzo zbliżony do środowisk produkcyjnych (wiele hostingów działa na Linuksie). Wymaga jednak odrobiny obycia z terminalem. Na starszym sprzęcie może działać szybciej niż Windows.
  • macOS – wygodny, ale sprzęt Apple jest drogi. Jeśli już się go ma, PHP działa bez problemu, można skorzystać z MAMP lub wbudowanych narzędzi (zależnie od wersji systemu).

Nie ma sensu kupować nowego komputera specjalnie pod PHP. Znacznie ważniejsze jest stabilne środowisko lokalne (serwer + baza), wygodny edytor i podstawowa organizacja plików.

Serwer lokalny: XAMPP, Laragon, MAMP – porównanie dla początkujących

Do nauki nie potrzeba od razu wykupionego hostingu. Wystarczy tzw. serwer lokalny, który „udaje” serwer w internecie na twoim komputerze. Najpopularniejsze darmowe pakiety to XAMPP, Laragon i MAMP.

NarzędzieSystemZalety na startGłówne minusy
XAMPPWindows, Linux, macOSBardzo popularny, mnóstwo poradników, prosty panelMomentami ociężały, nieco „przeładowany” jak na proste projekty
LaragonWindowsLekki, szybki, sensowne domyślne ustawienia, wygodne wirtualne domenyTylko Windows, mniej materiałów po polsku
MAMPmacOS, WindowsProsta konfiguracja, dobra opcja na MacuWersja Pro płatna, czasem gorsza dokumentacja dla początkujących

Na start w zupełności wystarczy XAMPP lub Laragon (jeśli pracujesz na Windows). Instalacja sprowadza się do „Dalej, dalej, Zakończ”, a po uruchomieniu wystarczy włączyć Apache (serwer WWW) i MySQL (baza danych). To znacznie szybsze niż ręczne ustawianie każdego elementu z osobna.

Minimalna konfiguracja: pierwszy skrypt PHP w przeglądarce

Po instalacji pakietu serwerowego trzeba zrozumieć tylko jedną rzecz: gdzie wrzucać pliki PHP, żeby były widoczne w przeglądarce. Standardowo dla XAMPP jest to katalog htdocs, dla Laragona – katalog www lub inny wskazany przy konfiguracji.

Przykładowy pierwszy skrypt:

<?php
echo "Witaj w świecie PHP!";
?>

Plik zapisz jako index.php w katalogu serwera lokalnego (np. C:xampphtdocsmojprojektindex.php). Następnie w przeglądarce wpisz adres:

http://localhost/mojprojekt/

Jeśli wszystko działa poprawnie, zobaczysz komunikat „Witaj w świecie PHP!”. Tyle wystarczy, by zacząć ćwiczyć bez płacenia za hosting.

Darmowe i lekkie edytory kodu – zestaw startowy

Nie trzeba inwestować w płatne IDE, żeby komfortowo pisać w PHP. Pod względem stosunku możliwości do ceny (zero złotych) bardzo dobrze wypadają:

  • Visual Studio Code (VS Code) – darmowy, z mnóstwem wtyczek. Wystarczy doinstalować rozszerzenia do PHP (np. PHP Intelephense, PHP Debug) i można wygodnie pracować.
  • Notepad++ – bardzo lekki edytor, dobry na słabsze komputery lub jako narzędzie awaryjne. Ma kolorowanie składni, ale brakuje mu bardziej zaawansowanych funkcji.
  • PhpStorm – płatny, ale ma darmowy okres testowy. Można go potraktować jako „przelot” przez profesjonalne środowisko, sprawdzić, czy funkcje takie jak podpowiadanie kodu i refaktoryzacja faktycznie pomagają.

Na start wystarczy VS Code – jest lekki, darmowy i bardzo elastyczny. Wtyczki do PHP pomogą wychwycić literówki, a integracja z Git ułatwi prostą kontrolę wersji, gdy projekty zaczną rosnąć.

Gotowy „zestaw startowy” – żeby nie ugrzęznąć w ustawieniach

Praktyczna, budżetowa konfiguracja na pierwsze tygodnie nauki:

O technologiach i ich zastosowaniach w różnych branżach można poczytać więcej o technologia, ale na start zamiast skakać po modnych stosach technologicznych, lepiej wgryźć się w jeden język, który najszybciej przyniesie konkretne rezultaty.

  • system, który już masz (nie ma sensu kupować nowego sprzętu),
  • XAMPP lub Laragon jako lokalny serwer (Apache + PHP + MySQL),
  • VS Code jako główny edytor,
  • prosty układ katalogów: np. C:projektyphpmojprojekt,
  • folder „playground” na krótkie eksperymenty z kodem, żeby nie mieszać ich z realnymi projektami.

Im szybciej miniesz etap „konfigurowania”, tym więcej czasu zostanie na faktyczne pisanie kodu. Lepszy prosty, działający zestaw niż idealnie zoptymalizowane środowisko, w którym ciągle coś poprawiasz, a nie uczysz się PHP.

Fundamenty PHP w praktyce, a nie z definicji

Kod po stronie serwera vs kod po stronie przeglądarki

Kluczowa rzecz: kod PHP jest wykonywany na serwerze, a do przeglądarki trafia już gotowy HTML (plus ewentualnie CSS i JavaScript). Przeglądarka w ogóle nie widzi tego, co dzieje się między znacznikami <?php ... ?>. To oznacza, że:

  • nie można „podejrzeć” czyjegoś kodu PHP przez „Pokaż źródło strony”,
  • wszystkie obliczenia, dostęp do bazy danych, walidacja po stronie serwera wykonuje się zanim HTML pojawi się u użytkownika,
  • PHP nie ma bezpośredniego dostępu do elementów DOM jak JavaScript – generuje dokument, a nie nim manipuluje po wysłaniu.

Dla webmastera praktyczny wniosek jest prosty: PHP odpowiada za logikę i generowanie treści, a JavaScript za interakcje po stronie przeglądarki. Na początek wystarczy dobrze opanować generowanie HTML i obsługę formularzy. Rozbudowane „fajerwerki” można dodać później.

Struktura pliku PHP i mieszanie z HTML

Najprostszy plik PHP może składać się wyłącznie z kodu PHP, ale w praktyce często łączy się go z HTML. Podstawowy szkielet wygląda tak:

<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <title>Moja pierwsza strona w PHP</title>
</head>
<body>
<?php
    $imie = "Anna";
    echo "<h1>Witaj, $imie!</h1>";
?>
</body>
</html>

PHP uruchamia się tylko wewnątrz bloków <?php ... ?>. Poza nimi można pisać zwykły HTML. Na początku łatwo popsuć strukturę przez złe zamknięcie cudzysłowów lub znaczników, dlatego lepiej nie upychać dużych fragmentów HTML w jednym echo. Z czasem dochodzi się do podziału na pliki: osobno nagłówek, stopka, szablony.

Zmienne, typy i operatory na prostych przykładach

Zmienne to „pudełka” na dane. W PHP nazwa zmiennej zawsze zaczyna się od $:

Zmienne, typy i operatory „po coś”, a nie „bo są w książce”

Najprościej myśleć o zmiennych jak o etykietach na kartkach z danymi. Nadajesz nazwę, przypisujesz wartość i możesz jej użyć kilka razy, zamiast powtarzać ten sam tekst czy liczbę.

<?php
$tytulStrony = "Sklep z koszulkami";
$cenaNetto   = 49.99;
$vat         = 0.23;

$cenaBrutto = $cenaNetto * (1 + $vat);

echo "<h1>$tytulStrony</h1>";
echo "<p>Cena brutto: $cenaBrutto zł</p>";
?>

Przydaje się to od pierwszego dnia. Zmienisz kiedyś stawkę VAT albo tytuł strony? Zrobisz to w jednym miejscu, a nie w kilkunastu linijkach HTML.

Najczęstsze typy danych w prostych projektach WWW:

  • liczby (np. ceny, ilość produktów, ID wpisu),
  • ciągi znaków (stringi) – tekst wyświetlany na stronie, adresy e-mail, ścieżki do plików,
  • logiczne (bool) – prawda/fałsz, np. czy użytkownik jest zalogowany, czy produkt jest dostępny,
  • tablice – zestawy powiązanych danych (lista produktów, wpisów, linków w menu).

Operatory to „narzędzia” do pracy na tych danych. Najczęściej używane na start:

  • arytmetyczne: +, -, *, /, % (reszta z dzielenia);
  • porównania: ==, !=, >, <, >=, <= – do sprawdzania warunków,
  • logiczne: && (i), || (lub), ! (zaprzeczenie).

Przykład z prostą logiką rabatu:

<?php
$wartoscKoszyka = 120;
$rabat = 0;

if ($wartoscKoszyka >= 100) {
    $rabat = 10; // procent
}

echo "Twój rabat: $rabat%";
?>

Instrukcje warunkowe i pętle w realnych mini-zadaniach

Bez warunków i pętli strona byłaby tylko statycznym szablonem. Warunki decydują, co wyświetlić, a pętle – ile razy.

Typowy warunek przydatny dla webmastera – informacja o logowaniu:

<?php
$zalogowany = false;

if ($zalogowany) {
    echo "<p>Witaj ponownie!</p>";
} else {
    echo "<p>Witaj, gościu! <a href='login.php'>Zaloguj się</a>.</p>";
}
?>

Pętle przydają się choćby do wygenerowania menu, listy artykułów czy tabelek cenowych. Zamiast ręcznie powielać HTML, robisz pętlę po danych:

<?php
$produkty = [
    "Koszulka PHP"   => 49.99,
    "Bluza Webmaster" => 129.00,
    "Kubek z kodem"   => 29.50
];
?>

<ul>
<?php foreach ($produkty as $nazwa => $cena): ?>
    <li><strong><?= $nazwa; ?></strong> – <?= $cena; ?> zł</li>
<?php endforeach; ?>
</ul>

Ten fragment da się łatwo przerobić na dynamiczną listę produktów z bazy danych – zmieni się tylko źródło danych, a nie sam układ HTML.

Jeśli interesują Cię konkrety i przykłady, rzuć okiem na: Startupy tworzone przez studentów – najlepsze przykłady.

Tablice i proste „słowniki” danych

Tablice to tani sposób na przechowywanie małych zestawów danych bez bazy. Na przykład lista linków w menu albo prosta konfiguracja strony:

<?php
$menu = [
    "Strona główna" => "index.php",
    "Oferta"        => "oferta.php",
    "Kontakt"       => "kontakt.php"
];
?>

<nav>
    <ul>
        <?php foreach ($menu as $etykieta => $url): ?>
            <li><a href="<?= $url; ?>"><?= $etykieta; ?></a></li>
        <?php endforeach; ?>
    </ul>
</nav>

Kiedy klient poprosi o zmianę kolejności pozycji w menu, nie trzeba polować po wielu plikach. Wystarczy przesunąć elementy w jednej tablicy.

Funkcje – sposób na porządek i oszczędność czasu

Funkcja to „mini-maszynka” – wkładasz dane wejściowe, dostajesz wynik. Idealne narzędzie, żeby nie pisać trzy razy tego samego. Prosty przykład: formatowanie ceny:

<?php
function formatujCene(float $kwota): string
{
    return number_format($kwota, 2, ',', ' ') . " zł";
}

$cena1 = 49.9;
$cena2 = 120;

echo formatujCene($cena1); // 49,90 zł
echo "<br>";
echo formatujCene($cena2); // 120,00 zł
?>

Przy rozbudowie strony refaktoryzacja do funkcji często daje większy efekt niż instalacja kolejnej wtyczki do edytora.

Kolorowy kod PHP na ciemnym ekranie monitora
Źródło: Pexels | Autor: Pixabay

PHP + HTML: pierwszy dynamiczny „szkielet” strony

Prosty układ strony z powtarzalnymi elementami

Większość stron ma te same elementy na wielu podstronach: nagłówek, menu, stopkę. Ręczne kopiowanie HTML-a między plikami szybko kończy się chaosem. W PHP można to załatwić jednym ruchem dzięki include i require.

Przykładowa struktura katalogu:

mojprojekt/
  includes/
    header.php
    footer.php
  index.php
  kontakt.php

includes/header.php:

<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <title><?= $tytul ?? "Moja strona w PHP"; ?></title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
<header>
    <h1>Moja pierwsza strona w PHP</h1>
    <nav>
        <a href="index.php">Start</a> |
        <a href="kontakt.php">Kontakt</a>
    </nav>
</header>
<main>

includes/footer.php:

</main>
<footer>
    &copy; <?= date('Y'); ?> Moja strona
</footer>
</body>
</html>

A teraz treść konkretnej podstrony:

<?php
$tytul = "Strona główna";
include __DIR__ . "/includes/header.php";
?>

<h2>Witamy!</h2>
<p>To jest treść strony głównej.</p>

<?php
include __DIR__ . "/includes/footer.php";
?>

Tak zbudowany „szkielet” oszczędza masę czasu. Nowa podstrona to tylko kilka linii – ustawienie tytułu i właściwa treść.

Unikanie „spaghetti kodu” w jednym pliku

Początkujący często mieszają wszystko: HTML, długie bloki PHP, zapytania do bazy, walidację formularzy – w jednym pliku typu index.php. Działa, ale trudno cokolwiek zmienić.

Nawet na małym projekcie można wprowadzić prosty porządek:

  • sekcja konfiguracji – ustawienia, stałe, np. dane do bazy (config.php),
  • sekcja logiki – przetwarzanie danych, np. obsługa formularza kontaktowego,
  • sekcja widoku – HTML z minimalną ilością PHP (głównie echo zmiennych).

Namiastkę takiego podziału można uzyskać nawet w jednym pliku, pilnując kolejności:

<?php
// 1. Konfiguracja
$tytul = "Kontakt";

// 2. Logika
$komunikat = "";
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // Tutaj kiedyś dojdzie walidacja i wysyłka maila
    $komunikat = "Dziękujemy za wiadomość!";
}
?>

<?php include __DIR__ . "/includes/header.php"; ?>

<h2>Kontakt</h2>

<?php if ($komunikat): ?>
    <p class="sukces"><?= $komunikat; ?></p>
<?php endif; ?>

<form method="post">
    <label>Twoje imię:
        <input type="text" name="imie">
    </label>
    <button type="submit">Wyślij</button>
</form>

<?php include __DIR__ . "/includes/footer.php"; ?>

Prosty schemat, ale gdy projekt urośnie, łatwiej wydzielić logikę do osobnych plików, nie zmieniając całej struktury.

Bezpieczne wstawianie danych do HTML

Dynamiczny HTML oznacza, że do kodu HTML trafiają również dane od użytkownika. Najtańszy sposób na uniknięcie kłopotów to przyzwyczajenie się do htmlspecialchars().

<?php
$imie = $_GET['imie'] ?? 'Gościu';
?>

<p>Witaj, <?= htmlspecialchars($imie, ENT_QUOTES, 'UTF-8'); ?>!</p>

Dzięki temu, jeśli ktoś zamiast imienia wpisze fragment HTML lub JavaScript, zostanie on wyświetlony jak tekst, a nie wykonany w przeglądarce.

Zbliżenie ekranu monitora z kolorowym kodem PHP
Źródło: Pexels | Autor: Pixabay

Formularze i obsługa danych od użytkownika krok po kroku

Metody GET i POST – kiedy której użyć

Formularz HTML sam z siebie nie „robi” niczego mądrego – dopiero PHP nadaje mu sens. Podstawowa decyzja to wybór metody: GET albo POST.

  • GET – dane widać w adresie URL (np. ?szukaj=php). Dobre do wyszukiwania, filtrowania, paginacji – tam, gdzie wynik można spokojnie zapisać w zakładkach.
  • POST – dane lecą w treści żądania HTTP, nie widać ich w pasku adresu. Używane do formularzy z danymi wrażliwymi: logowanie, rejestracja, kontakt, koszyk itp.

Prosty formularz wyszukiwarki z użyciem GET:

Do kompletu polecam jeszcze: Jak dobrać wyłącznik różnicowoprądowy do domu jednorodzinnego: praktyczny poradnik dla inwestorów — znajdziesz tam dodatkowe wskazówki.

<form method="get" action="szukaj.php">
    <label>Szukaj:
        <input type="text" name="q">
    </label>
    <button type="submit">Szukaj</button>
</form>

Plik szukaj.php:

<?php
$zapytanie = $_GET['q'] ?? '';
$zapytanieCzyste = trim($zapytanie);
?>

<h1>Wyniki wyszukiwania</h1>

<p>Szukano: <strong><?= htmlspecialchars($zapytanieCzyste, ENT_QUOTES, 'UTF-8'); ?></strong></p>

Prosty formularz kontaktowy – od HTML do walidacji

Typowe zadanie: formularz kontaktowy, który pokaże użytkownikowi informację zwrotną, czy wiadomość została przyjęta. W wersji „na start” można pominąć wysyłkę e-maila, a skupić się na poprawnym przyjęciu i sprawdzeniu danych.

HTML formularza (np. w kontakt.php):

<?php
$tytul = "Kontakt";
$bledy = [];
$komunikat = "";
$imie = "";
$email = "";
$wiadomosc = "";

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $imie = trim($_POST['imie'] ?? '');
    $email = trim($_POST['email'] ?? '');
    $wiadomosc = trim($_POST['wiadomosc'] ?? '');

    if ($imie === '') {
        $bledy[] = "Podaj imię.";
    }

    if ($email === '') {
        $bledy[] = "Podaj adres e-mail.";
    } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        $bledy[] = "Adres e-mail wygląda nieprawidłowo.";
    }

    if ($wiadomosc === '') {
        $bledy[] = "Napisz wiadomość.";
    }

    if (empty($bledy)) {
        // Tu można kiedyś dodać mail() lub integrację z zewnętrzną usługą
        $komunikat = "Dziękujemy za kontakt. Odpowiemy tak szybko, jak to możliwe.";
        // Wyczyszczenie pól po „wysyłce”
        $imie = $email = $wiadomosc = "";
    }
}
?>

<?php include __DIR__ . "/includes/header.php"; ?>

<h2>Kontakt</h2>

<?php if ($komunikat): ?>
    <p class="sukces"><?= htmlspecialchars($komunikat, ENT_QUOTES, 'UTF-8'); ?></p>
<?php endif; ?>

<?php if ($bledy): ?>
    <ul class="bledy">
        <?php foreach ($bledy as $blad): ?

Wyświetlanie błędów obok formularza bez przeładowywania wszystkiego w głowie

Kiedy formularz zaczyna mieć więcej pól, kluczowe jest, żeby użytkownik nie zgadywał, co poszło nie tak. Najprościej: trzymać wartości pól w zmiennych i „wpinać” je z powrotem do formularza, a błędy pokazać nad nim lub przy konkretnych polach.

<?php
$tytul = "Kontakt";
$bledy = [];
$komunikat = "";
$imie = "";
$email = "";
$wiadomosc = "";

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $imie = trim($_POST['imie'] ?? '');
    $email = trim($_POST['email'] ?? '');
    $wiadomosc = trim($_POST['wiadomosc'] ?? '');

    if ($imie === '') {
        $bledy['imie'] = "Podaj imię.";
    }

    if ($email === '') {
        $bledy['email'] = "Podaj adres e-mail.";
    } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        $bledy['email'] = "Adres e-mail wygląda nieprawidłowo.";
    }

    if ($wiadomosc === '') {
        $bledy['wiadomosc'] = "Napisz wiadomość.";
    }

    if (!$bledy) {
        $komunikat = "Dziękujemy za kontakt. Odpowiemy tak szybko, jak to możliwe.";
        $imie = $email = $wiadomosc = "";
    }
}
?>

<?php include __DIR__ . "/includes/header.php"; ?>

<h2>Kontakt</h2>

<?php if ($komunikat): ?>
    <p class="sukces"><?= htmlspecialchars($komunikat, ENT_QUOTES, 'UTF-8'); ?></p>
<?php endif; ?>

<form method="post">
    <div>
        <label>Twoje imię:<br>
            <input type="text" name="imie"
                   value="<?= htmlspecialchars($imie, ENT_QUOTES, 'UTF-8'); ?>">
        </label>
        <?php if (isset($bledy['imie'])): ?>
            <div class="blad"><?= htmlspecialchars($bledy['imie'], ENT_QUOTES, 'UTF-8'); ?></div>
        <?php endif; ?>
    </div>

    <div>
        <label>E-mail:<br>
            <input type="email" name="email"
                   value="<?= htmlspecialchars($email, ENT_QUOTES, 'UTF-8'); ?>">
        </label>
        <?php if (isset($bledy['email'])): ?>
            <div class="blad"><?= htmlspecialchars($bledy['email'], ENT_QUOTES, 'UTF-8'); ?></div>
        <?php endif; ?>
    </div>

    <div>
        <label>Wiadomość:<br>
            <textarea name="wiadomosc" rows="5"><?= htmlspecialchars($wiadomosc, ENT_QUOTES, 'UTF-8'); ?></textarea>
        </label>
        <?php if (isset($bledy['wiadomosc'])): ?>
            <div class="blad"><?= htmlspecialchars($bledy['wiadomosc'], ENT_QUOTES, 'UTF-8'); ?></div>
        <?php endif; ?>
    </div>

    <button type="submit">Wyślij</button>
</form>

<?php include __DIR__ . "/includes/footer.php"; ?>

Użytkownik nie musi wszystkiego wpisywać od zera, a ty nie rzeźbisz w JavaScripcie – czyste PHP daje całkiem przyjemny efekt.

Prosty mechanizm ochrony przed spamem – bez kupowania captcha

Formularz na publicznej stronie szybko zacznie łapać spam. Zanim wprowadzisz Google reCAPTCHA, można zastosować tani i prosty „bezsilnikowy” filtr:

  • pole typu „honeypot” – ukryte dla użytkownika, ale widoczne dla bota,
  • proste pytanie kontrolne, np. „Ile to jest 2+3?”.
<?php
$tytul = "Kontakt";
$bledy = [];
$komunikat = "";
$imie = "";
$email = "";
$wiadomosc = "";
$odpowiedz = "";

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $imie = trim($_POST['imie'] ?? '');
    $email = trim($_POST['email'] ?? '');
    $wiadomosc = trim($_POST['wiadomosc'] ?? '');
    $odpowiedz = trim($_POST['odpowiedz'] ?? '');
    $honeypot = trim($_POST['strona_www'] ?? '');

    if ($honeypot !== '') {
        // Prawdopodobnie bot – udajemy, że wszystko ok, ale nic nie robimy
        $komunikat = "Dziękujemy za kontakt.";
    } else {
        if ($imie === '') {
            $bledy['imie'] = "Podaj imię.";
        }

        if ($email === '') {
            $bledy['email'] = "Podaj adres e-mail.";
        } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            $bledy['email'] = "Adres e-mail wygląda nieprawidłowo.";
        }

        if ($wiadomosc === '') {
            $bledy['wiadomosc'] = "Napisz wiadomość.";
        }

        if ($odpowiedz !== '5') {
            $bledy['odpowiedz'] = "Nieprawidłowa odpowiedź na pytanie kontrolne.";
        }

        if (!$bledy) {
            $komunikat = "Dziękujemy za wiadomość.";
            $imie = $email = $wiadomosc = $odpowiedz = "";
        }
    }
}
?>

<?php include __DIR__ . "/includes/header.php"; ?>

<h2>Kontakt</h2>

<?php if ($komunikat): ?>
    <p class="sukces"><?= htmlspecialchars($komunikat, ENT_QUOTES, 'UTF-8'); ?></p>
<?php endif; ?>

<?php if ($bledy): ?>
    <ul class="bledy">
        <?php foreach ($bledy as $blad): ?>
            <li><?= htmlspecialchars($blad, ENT_QUOTES, 'UTF-8'); ?></li>
        <?php endforeach; ?>
    </ul>
<?php endif; ?>

<form method="post">
    <!-- Honeypot: pole ukryte CSS-em -->
    <div class="honeypot">
        <label>Twoja strona WWW:
            <input type="text" name="strona_www" autocomplete="off">
        </label>
    </div>

    <div>
        <label>Imię:<br>
            <input type="text" name="imie"
                   value="<?= htmlspecialchars($imie, ENT_QUOTES, 'UTF-8'); ?>">
        </label>
    </div>

    <div>
        <label>E-mail:<br>
            <input type="email" name="email"
                   value="<?= htmlspecialchars($email, ENT_QUOTES, 'UTF-8'); ?>">
        </label>
    </div>

    <div>
        <label>Wiadomość:<br>
            <textarea name="wiadomosc" rows="5"><?= htmlspecialchars($wiadomosc, ENT_QUOTES, 'UTF-8'); ?></textarea>
        </label>
    </div>

    <div>
        <label>Ile to jest 2 + 3?<br>
            <input type="text" name="odpowiedz"
                   value="<?= htmlspecialchars($odpowiedz, ENT_QUOTES, 'UTF-8'); ?>">
        </label>
    </div>

    <button type="submit">Wyślij</button>
</form>

<?php include __DIR__ . "/includes/footer.php"; ?>

Honeypot usuwa większość prymitywnych botów, a pytanie kontrolne ratuje skrzynkę zanim wprowadzisz cięższy kaliber.

Pierwsza baza danych: MySQL/MariaDB bez męki

Jak postawić bazę „po taniości” na lokalnym serwerze

Na etapie nauki nie ma sensu kupować drogiego hostingu tylko po to, żeby pobawić się bazą. W XAMPP czy Laragonie masz od razu w pakiecie MySQL/MariaDB i panel phpMyAdmin.

  1. Uruchom panel XAMPP/Laragon.
  2. Włącz moduł Apache i MySQL/MariaDB.
  3. Wejdź w przeglądarce na adres http://localhost/phpmyadmin.
  4. Utwórz nową bazę, np. mojastrona.

W panelu możesz tworzyć tabele „z palca”, ale szybciej zrobić to jednym poleceniem SQL. Przykład prostej tabeli na wiadomości z formularza kontaktowego:

CREATE TABLE wiadomosci_kontaktowe (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    imie VARCHAR(100) NOT NULL,
    email VARCHAR(255) NOT NULL,
    wiadomosc TEXT NOT NULL,
    utworzono_at DATETIME NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

Jedno pole id jako klucz główny, kilka pól tekstowych i data utworzenia – bez nadmiarowego kombinowania.

PDO – jedno rozsądne API do bazy na dłużej

PHP ma stare rozszerzenia typu mysql_*, ale są przestarzałe. Na start najlepiej wejść od razu w PDO – to jedno spójne API do różnych baz (MySQL, SQLite, PostgreSQL).

Prosty plik db.php z połączeniem:

<?php
$dsn = 'mysql:host=localhost;dbname=mojastrona;charset=utf8mb4';
$uzytkownik = 'root';
$haslo = '';

try {
    $pdo = new PDO($dsn, $uzytkownik, $haslo, [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    ]);
} catch (PDOException $e) {
    // Na produkcji NIE wysyłaj pełnego błędu do przeglądarki
    echo "Błąd połączenia z bazą.";
    file_put_contents(__DIR__ . '/logs/bledy_db.log', $e->getMessage() . PHP_EOL, FILE_APPEND);
    exit;
}

Plik można dołączać tam, gdzie potrzebny jest dostęp do danych:

<?php
require __DIR__ . '/db.php';

$stmt = $pdo->query("SELECT COUNT(*) AS ile FROM wiadomosci_kontaktowe");
$wynik = $stmt->fetch();

echo "W bazie jest " . (int)$wynik['ile'] . " wiadomości.";

Zapisywanie danych z formularza do bazy – krok po kroku

Formularz kontaktowy przestaje być jednorazowy, gdy treść zapisuje się w tabeli. To już namiastka prostego CRM-u, a przy okazji solidne ćwiczenie z bezpiecznych zapytań.

Fragment obsługi formularza w kontakt.php z zapisem do bazy:

<?php
require __DIR__ . '/db.php';

$bledy = [];
$komunikat = "";
$imie = "";
$email = "";
$wiadomosc = "";

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $imie = trim($_POST['imie'] ?? '');
    $email = trim($_POST['email'] ?? '');
    $wiadomosc = trim($_POST['wiadomosc'] ?? '');

    if ($imie === '') {
        $bledy['imie'] = "Podaj imię.";
    }

    if ($email === '') {
        $bledy['email'] = "Podaj adres e-mail.";
    } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        $bledy['email'] = "Adres e-mail wygląda nieprawidłowo.";
    }

    if ($wiadomosc === '') {
        $bledy['wiadomosc'] = "Napisz wiadomość.";
    }

    if (!$bledy) {
        $sql = "INSERT INTO wiadomosci_kontaktowe (imie, email, wiadomosc, utworzono_at)
                VALUES (:imie, :email, :wiadomosc, :utworzono_at)";
        $stmt = $pdo->prepare($sql);
        $stmt->execute([
            ':imie' => $imie,
            ':email' => $email,
            ':wiadomosc' => $wiadomosc,
            ':utworzono_at' => date('Y-m-d H:i:s'),
        ]);

        $komunikat = "Twoja wiadomość została zapisana.";
        $imie = $email = $wiadomosc = "";
    }
}
?>

Przy użyciu prepare() i execute() nie sklejasz ręcznie ciągów SQL ze zmiennymi, co chroni przed SQL Injection i oszczędza późniejszą refaktoryzację.

Podstawowe odczyty z bazy – lista wpisów „na brudno”

Najprostszy panel administracyjny możesz złożyć w jeden wieczór. Nawet bez logowania – na lokalnym serwerze – warto poćwiczyć iterację po wynikach.

Plik admin_wiadomosci.php:

<?php
require __DIR__ . '/db.php';

$stmt = $pdo->query("SELECT id, imie, email, wiadomosc, utworzono_at
                     FROM wiadomosci_kontaktowe
                     ORDER BY utworzono_at DESC
                     LIMIT 50");
$wiadomosci = $stmt->fetchAll();

$tytul = "Odebrane wiadomości";
include __DIR__ . "/includes/header.php";
?>

<h2>Odebrane wiadomości</h2>

<table border="1" cellpadding="5" cellspacing="0">
    <thead>
        <tr>
            <th>ID</th>
            <th>Imię</th>
            <th>E-mail</th>
            <th>Wiadomość</th>
            <th>Data</th>
        </tr>
    </thead>
    <tbody>
    <?php foreach ($wiadomosci as $w): ?>
        <tr>
            <td><?= (int)$w['id']; ?></td>
            <td><?= htmlspecialchars($w['imie'], ENT_QUOTES, 'UTF-8'); ?

Najczęściej zadawane pytania (FAQ)

Czy w 2024 roku nadal opłaca się uczyć PHP od zera?

Tak, jeśli celujesz w tworzenie i utrzymanie stron dla małych firm, blogerów, lokalnych sklepów czy fundacji, PHP wciąż jest bardzo opłacalnym wyborem. Większość tanich hostingów ma PHP i MySQL „w pakiecie”, więc nie inwestujesz w drogi serwer ani skomplikowaną infrastrukturę.

Dzięki PHP możesz modyfikować WordPressa, pisać proste panele administracyjne, formularze czy integracje z bramkami płatności. To realne, komercyjne zastosowania, za które klienci płacą, nawet jeśli dopiero jesteś na początku drogi.

Co realnie mogę zrobić w PHP po 2–3 miesiącach nauki?

Przy nauce 1–2 godziny dziennie po kilku miesiącach jesteś w stanie przygotować pierwsze proste zlecenia. Typowy zakres to:

  • strona wizytówka z dynamicznymi sekcjami (aktualności, oferta, galeria),
  • formularz kontaktowy z walidacją i wysyłką maila,
  • mini CMS: logowanie, dodawanie i edycja wpisów,
  • prosta integracja z MySQL (lista zadań, komentarze, ankiety).

Kluczowe okazuje się nie tyle poznanie całego języka, co umiejętność diagnozowania błędów i utrzymania porządku w kodzie. Na tym poziomie już można brać drobne, płatne modyfikacje WordPressa czy formularzy.

Czy do PHP muszę znać HTML i CSS?

Bez podstaw HTML i CSS daleko nie zajedziesz. PHP generuje treść (HTML) i obsługuje logikę po stronie serwera, ale wyglądem strony i jej układem nadal zajmuje się HTML/CSS. Bez nich skończysz z działającą, ale brzydką i chaotyczną stroną.

Minimalny zestaw na start to: struktura HTML (nagłówki, listy, formularze, tabele) i podstawy CSS (kolory, marginesy, siatka, responsywność). Nie musisz od razu być front-endowcem – wystarczy, że umiesz poprawnie „ubrać” dane wygenerowane przez PHP.

Jaki system i jakie narzędzie wybrać do nauki PHP, żeby nie przepłacić?

Nie ma sensu kupować nowego komputera tylko pod PHP. Wybierz to, co już masz:

  • Windows + XAMPP lub Laragon – najprostszy start, kilka kliknięć i masz lokalny serwer,
  • Linux (np. Ubuntu) – bardzo zbliżone środowisko do typowych hostingów, świetne na starszy sprzęt,
  • macOS + MAMP – jeśli już posiadasz Maca.

Do edycji kodu w zupełności wystarczy darmowy Visual Studio Code z wtyczkami do PHP. To zestaw „za zero złotych”, który pozwala wygodnie uczyć się i robić pierwsze projekty komercyjne.

Czy potrzebuję płatnego hostingu, żeby zacząć programować w PHP?

Na start nie. Do nauki i pierwszych eksperymentów wystarczy lokalny serwer na twoim komputerze (XAMPP, Laragon, MAMP). Instalujesz pakiet, wrzucasz pliki do odpowiedniego katalogu (np. htdocs w XAMPP), odpalasz w przeglądarce http://localhost/ i możesz pracować bez żadnych opłat.

Płatny, tani hosting (kilkanaście zł miesięcznie) przydaje się dopiero, gdy chcesz pokazać projekt klientowi lub postawić pierwszą stronę produkcyjną. Do samej nauki to zbędny wydatek.

Kiedy lepiej wybrać inny język niż PHP (np. JavaScript, Python)?

Jeśli Twoim celem są duże aplikacje webowe czasu rzeczywistego, rozbudowane SPA, gry przeglądarkowe czy mikroserwisy, rozsądniej od razu kierować się w stronę JavaScriptu (Node.js), Pythona, Javy lub C#. Tam rynek bardziej premiuje osoby od architektury złożonych systemów.

PHP wygrywa, gdy chcesz szybko wejść w rynek prostych stron WWW, WordPressa, małych paneli administracyjnych i chcesz zacząć zarabiać w ciągu kilku miesięcy, a nie lat. To pragmatyczny wybór dla przyszłego webmastera, który liczy koszty i czas.

Czy da się zostać freelancerem od stron WWW tylko z PHP?

Tak, ale w praktyce „tylko PHP” oznacza zestaw: PHP + HTML + CSS + podstawy bazy danych (MySQL) i ogarnianie WordPressa. Z takim pakietem możesz robić:

  • proste strony firmowe i wizytówki,
  • modyfikacje motywów i wtyczek WordPressa,
  • formularze, małe panele, integracje z zewnętrznymi usługami.

Wielu freelancerów zaczyna właśnie od przeróbek istniejących motywów i prostych modułów, stopniowo podnosząc stawki. Największym ograniczeniem nie jest technologia, tylko portfolio i umiejętność dogadania się z klientem.

Co warto zapamiętać

  • PHP jest wciąż jednym z najbardziej opłacalnych języków dla przyszłego webmastera, bo napędza WordPressa, sklepy, panele administracyjne i działa na praktycznie każdym tanim hostingu.
  • Znajomość podstaw PHP pozwala szybko wejść na rynek: przerabiać motywy WordPressa, dodawać własne fragmenty kodu, poprawiać formularze i brać pierwsze drobne zlecenia.
  • PHP ma sens, gdy celem jest szybkie zarabianie na prostych stronach WWW i małych systemach; do dużych, złożonych aplikacji lepiej celować w JavaScript (Node.js), Pythona, Javę lub C#.
  • Przy regularnej nauce 1–2 godziny dziennie przez 2–3 miesiące można już stworzyć prosty CMS, formularze z walidacją, integrację z MySQL i proste połączenia z zewnętrznymi API.
  • PHP to tylko jedna część układanki – do realnej strony potrzebne są jeszcze HTML, CSS, serwer/hosting i domena; bez tego sam kod PHP nie przełoży się na działający serwis.
  • Do nauki nie trzeba kupować hostingu ani nowego sprzętu – wystarczy stabilny komputer i lokalny serwer typu XAMPP, Laragon lub MAMP, który „udaje” środowisko produkcyjne.
  • Wybór systemu (Windows, Linux, macOS) ma mniejsze znaczenie niż wygodny, tani w utrzymaniu setup: prosty serwer lokalny, sensowny edytor i porządek w plikach.