Teoria INF.03 - Kompletne Notatki
I. Projektowanie stron i Frontend (HTML5, CSS3)
II. Programowanie po stronie klienta (JavaScript)
III. Projektowanie baz danych
IV. Jezyk zapytan SQL
V. Programowanie po stronie serwera (PHP)
I. Projektowanie stron i Frontend (HTML5 i CSS3)
1. Szkielet dokumentu HTML5
Kazde zadanie praktyczne zaczyna sie tak samo: masz utworzyc plik index.html z poprawnym szkieletem.
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Krotki opis strony">
<title>Tytul strony</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header>...</header>
<nav>...</nav>
<main>...</main>
<aside>...</aside>
<footer>...</footer>
</body>
</html>
meta charset - bez niej polskie znaki wyswietla sie jako krzaczki. Plik tez musi byc zapisany w UTF-8.
viewport - bez niego media queries nie zadzialaja na telefonie.
2. Znaczniki semantyczne, blokowe i liniowe
Semantyczne HTML5:
- <header> - naglowek strony lub sekcji
- <nav> - blok nawigacji
- <main> - glowna tresc (moze wystapic tylko RAZ)
- <section> - tematycznie spokojna sekcja
- <article> - samodzielna tresc (wpis bloga, komentarz)
- <aside> - tresc poboczna (pasek boczny)
- <footer> - stopka strony lub sekcji
- <figure> - ilustracja z podpisem <figcaption>
Elementy liniowe (span, a, strong, em, b, i, img, input, label, button) - plyna w linii tekstu, ignoruja szerokosc i wysokosc.
visibility: hidden
3. Formularze i typy pol
<form action="zapisz.php" method="post">
<label for="imie">Imie:</label>
<input type="text" id="imie" name="imie" required>
<label for="email">E-mail:</label>
<input type="email" id="email" name="email" required>
<label for="haslo">Haslo:</label>
<input type="password" id="haslo" name="haslo" minlength="8" required>
<select id="usluga" name="usluga">
<option value="">-- wybierz --</option>
<option value="diagnostyka">Diagnostyka</option>
<option value="naprawa" selected>Naprawa</option>
</select>
<input type="radio" id="p1" name="priorytet" value="normalny" checked>
<label for="p1">Normalny</label>
<input type="checkbox" id="regulamin" name="regulamin" value="tak" required>
<label for="regulamin">Akceptuje regulamin</label>
<textarea id="opis" name="opis" rows="5"></textarea>
<button type="submit">Wyslij</button>
</form>
GET vs POST: GET - dane w adresie (wyszukiwarki, filtry). POST - dane w tresci zadania (logowanie, zapis do bazy). POST nie jest szyfrowany - jest tylko niewidoczny w adresie. Poufne HTTPS.
Typy input: text, password, email, number, radio (ten sam name, rozne value), checkbox (nezaznaczone nie jest wysylane), date, file (wymaga enctype multipart/form-data), hidden, submit/reset.
4. Multimedia i tabele
<img src="obraz.jpg" alt="Opis" width="600" height="400">
<audio controls loop>
<source src="dzwiek.mp3" type="audio/mpeg">
<source src="dzwiek.ogg" type="audio/ogg">
</audio>
<video width="640" height="360" controls poster="miniatura.jpg">
<source src="film.mp4" type="video/mp4">
</video>
Formaty: JPG (zdjecia, stratna), PNG (przezroczystosc, bezstratna), GIF (animacje, 256 kolorow), SVG (wektorowa), WebP (nowoczesny, mniejszy).
Tabela: colspan scala w POZIOMIE (w wierszu), rowspan w PIONIE (w kolumnie). border-collapse: collapse scala podwojne obramowania.
5. Style, selektory i specyficznosc
Typy stylizacji: inline (atrybut style, najwyzszy priorytet), wewnetrzne (blok style w head), zewnetrzne (osobny plik .css - ZALECANY).
Specyficzność (punktacja):
- Inline (style=) = 1000 pkt
- Identyfikator #menu = 100 pkt
- Klasa, pseudoklasa, atrybut = 10 pkt
- Element, pseudoelement = 1 pkt
- Selektor uniwersalny * = 0 pkt
!important przebija wszystko, nawet inline.
Dziedziczenie: kolor, krój pisma - przechodza. Marginesy, padding, border, szerokosc - NIE sa dziedziczone.
6. Model pudełkowy i pozycjonowanie
box-sizing: border-box: szerokosc = treść + padding + border. Pudelko NIE rosnie.
Margines NIGDY nie wlicza sie do szerokosci elementu - ani w jednym, ani w drugim modelu.
Przyklad: element width:300px, padding:20px, border:5px, margin:10px:
- content-box: szerokosc widoczna = 300+40+10 = 350px, w ukladzie = 370px
- border-box: szerokosc widoczna = 300px, tresc = 250px, w ukladzie = 320px
Pozycjonowanie (position):
- static - domyslne, top/left/right/bottom i z-index ignorowane
- relative - przesuwa sie, ale miejsce PO zostaje
- absolute - wypada z przeplywu, odnosi sie do najblizszego przodka pozycjonowanego
- fixed - wypada z przeplywu, nie przewija sie ze strona (przyklejone menu)
- sticky - hybryda relative+fixed (przykleja sie po osiagnieciu progu)
7. Layout: Flexbox i CSS Grid
Flexbox - uklada w JEDNEJ OSI (rzad albo kolumna). Grid w DWOCH NARAZ (wiersze i kolumny).
/* Flexbox - menu poziome */
.menu {
display: flex;
justify-content: space-between; /* flex-start, flex-end, center, space-between, space-around, space-evenly */
align-items: center; /* stretch, flex-start, flex-end, center, baseline */
flex-wrap: wrap;
gap: 20px;
}
/* Flex - wysrodkowanie w pionie i poziomie */
.ekran { display: flex; justify-content: center; align-items: center; min-height: 100vh; }
/* Grid - kompletne uklady strony */
.strona {
display: grid;
grid-template-columns: 200px 1fr 250px;
grid-template-rows: 100px auto 80px;
grid-template-areas:
"naglowek naglowek naglowek"
"menu tresc bok"
"stopka stopka stopka";
}
/* Galeria responsywna */
.galeria {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 20px;
}
Numeracja linii siatki Grid zaczyna sie od 1, uklad o 3 kolumnach ma 4 linie pionowe.
8. Responsywnosc (RWD) i Media Queries
/* Mobile first - style dla telefonu, potem rozszerzenia */
.strona { display: grid; grid-template-columns: 1fr; }
@media screen and (min-width: 768px) {
.strona { grid-template-columns: 200px 1fr; }
}
@media screen and (min-width: 1024px) {
.strona { grid-template-columns: 200px 1fr 250px; }
}
/* Zdjecie responsywne */
img { max-width: 100%; height: auto; }
Jednostki CSS: px (bezwzgledna), % (wzgledem rodzica), em (wzgledem pisma rodzica), rem (wzgledem html), vw/vh (1% okna), fr (wolna przestrzen w Grid).
II. Programowanie po stronie klienta (JavaScript)
1. Osadzanie skryptu
<!-- Skrypt wewnetrzny -->
<script> document.getElementById("x").textContent = "Witaj!"; </script>
<!-- Skrypt zewnetrzny -->
<script src="js/skrypt.js" defer></script>
defer - skrypt wykonuje sie po zbudowaniu DOM (zalecany). async - wykonuje sie natychmiast po pobraniu, przerywajac budowe strony. Dzialaja tylko dla skryptow zewnetrznych.
2. Zmienne, typy danych i operatory
var vs let vs const:
- var - zasieg funkcyjny, mozna przepisywac i re-deklarowac
- let - zasieg blokowy, mozna przepisywac, nie mozna re-deklarowac
- const - zasieg blokowy, NIE mozna przepisywac ani re-deklarowac
"2" + 3 = "23" (konkatenacja), ale "2" - 3 = -1 (minus wymusza liczby).
Typy: number, string, boolean, undefined, null, NaN (typeof NaN = "number").
Konwersje: Number("12")=12, parseInt("12.9")=12, parseFloat("12.9zl")=12.9, String(12)="12", typeof x.
== vs ===: == porownuje po konwersji (luze), === porownuje wartosc I typ (scisle). Uzywaj ===.
3. Warunki, switch i petle
// if / else if / else
if (ocena >= 5) { ... } else if (ocena >= 4) { ... } else { ... }
// switch - porownuje SCISLE (jak ===)
switch (dzien) {
case 1: case 2: case 3: case 4: case 5:
console.log("dzien roboczy"); break;
case 6: case 7:
console.log("weekend"); break;
default:
console.log("bledna wartosc");
}
// for - gdy znasz liczbe powtorzen
for (let i = 0; i < 10; i++) { ... }
// while - warunek sprawdzany PRZED
while (n > 0) { n--; }
// do...while - blok wykona sie CO NAJMNIEJ RAZ
do { ... } while (x < 10);
// for...of - po wartosciach tablicy
for (const o of oceny) { console.log(o); }
// for...in - po kluczach obiektu
for (const klucz in uczen) { console.log(klucz); }
4. Funkcje
// Deklaracja - podlega hoistingowi (mozna wywolac PRZED definicja)
function pole(a, b) { return a * b; }
// Wyrazenie funkcyjne
const obwod = function(a, b) { return 2 * (a + b); };
// Funkcja strzalkowa (arrow function)
const podwoj = (x) => x * 2; // jedno wyrazenie - return domyslny
const suma = (a, b) => { return a + b; };
// Parametr domyslny
function powitaj(imie = "gosciu") { return "Witaj, " + imie + "!"; }
Funkcja strzalkowa nie ma wlasnego this i nie podlega hoistingowi. Uzywa sie jej jako krotkie funkcje w map, filter, obsludze zdarzen.
5. Tablice, obiekty i tekst
// TABLICE - metody ZMIENIAJACE oryginal
owoce.push("banan"); // dodaje na KONIEC
owoce.pop(); // usuwa OSTATNI
owoce.unshift("wisnia"); // dodaje na POCZATEK
owoce.shift(); // usuwa PIERWSZY
owoce.splice(1, 1); // usuwa 1 element od indeksu 1
// TABLICE - metody ZWRACAJACE nowa tablice
liczby.slice(1, 3); // [12, 8] - od 1 do 3 BEZ 3
liczby.indexOf(8); // 2
liczby.includes(44); // true
// ITERACJA
liczby.forEach((el, i) => console.log(i + ": " + el)); // undefined
const podwojone = liczby.map(el => el * 2); // nowa tablica
const duze = liczby.filter(el => el > 10); // nowa tablica
const razem = liczby.reduce((a, b) => a + b, 0); // suma
// OBIEKT
const uczen = { imie: "Jan", nazwisko: "Kowalski" };
uczen.wiek = 17; // dodanie wlasciwosci
delete uczen.klasa; // usuniecie
// TEKST
" Tekst ".trim(); // obcina spacje
"Tekst".substring(0, 4); // "Tekst"
"dane;a;b".split(";"); // ["dane", "a", "b"]
["a", "b"].join(", "); // "a, b"
"tekst".replace("tekst", "nowy"); // "nowy"
forEach zwraca undefined, map zwraca nowa tablice, filter - nowa tablice z filtrujacymi elementami.
6. Model DOM i modyfikacja strony
// WYSZUKIWANIE
document.getElementById("x"); // po ID (bez #)
document.querySelector("#x"); // selektor CSS (z #)
document.querySelector(".klasa"); // selektor CSS (z .)
document.querySelectorAll("li"); // NodeList wszystkich
// ZMIANA TRESCI
el.textContent = "Nowy tekst"; // CZYSTY TEKST
el.innerHTML = "Tekst <strong>gruby</strong>"; // interpretuje HTML
// ATRYBUTY
obrazek.src = "logo.png";
obrazek.setAttribute("alt", "Logo");
obrazek.getAttribute("alt");
// STYLE (camelCase!)
el.style.color = "red";
el.style.backgroundColor = "#eee";
// KLASY CSS
el.classList.add("aktywny");
el.classList.remove("ukryty");
el.classList.toggle("zaznaczony");
// TWORZENIE ELEMENTU - 3 kroki
const nowy = document.createElement("li");
nowy.textContent = "Nowy produkt";
lista.appendChild(nowy);
// USUWANIE
nowy.remove();
lista.removeChild(lista.lastElementChild);
lista.innerHTML = "";
7. Zdarzenia i walidacja formularza
// Skladnia: element.addEventListener("nazwa", funkcja);
// UWAGA: nazwa BEZ przedrostka "on"
przycisk.addEventListener("click", (e) => {
console.log(e.target);
e.preventDefault(); // anuluje domyslne dzialanie (np. wyslanie formularza)
});
// Kod po zbudowaniu DOM
document.addEventListener("DOMContentLoaded", () => { ... });
Najwazniejsze zdarzenia: click, submit (na form, nie na button!), input, change, load, mouseover, keyup, focus, blur.
Walidacja po stronie klienta NIE zastepuje walidacji na serwerze - uzytkownik moze wylaczyc JS.
8. Local Storage, Session Storage, ciasteczka
Porownanie:
- Local Storage - 5-10MB, bezterminowo, NIE jest wysylane na serwer
- Session Storage - 5-10MB, do zamkniecia karty, NIE jest wysylane na serwer
- Cookie - ~4KB, ma date waznosci, JEST wysylane na serwer przy kazdym zadaniu
// LOCAL STORAGE
localStorage.setItem("klucz", "wartosc");
localStorage.getItem("klucz"); // "wartosc" lub null
localStorage.removeItem("klucz");
localStorage.clear();
// Zapis i odczyt obiektow przez JSON
localStorage.setItem("koszyk", JSON.stringify(koszyk));
const wczytany = JSON.parse(localStorage.getItem("koszyk"));
// CIASTECZKA
document.cookie = "jezyk=pl; max-age=2592000; path=/";
document.cookie = "jezyk=; max-age=0; path=/"; // usuniecie
III. Projektowanie baz danych
1. Baza danych, DBMS i model relacyjny
Baza danych = uporzadkowany zbior danych o okreslonej strukturze. DBMS (np. MySQL, MariaDB, PostgreSQL) = program do zarzadzania baza.
2. Klucze i integralnosc danych
- Klucz podstawowy (PRIMARY KEY) - jeden na tabele, unikalny, nie moze byc NULL
- Klucz kandydujacy - kazda kolumna, ktora MOGLABY byc kluczem (unikalna, minimalna)
- Klucz obcy (FOREIGN KEY)
- Klucz zlozony - zbudowany z 2+ kolumn (tabela laczaca)
Integralnosc referencyjna - wartosc FK musi wskazywac na istniejacy wiersz w tabeli nadrzednej lub byc NULL.
3. Relacje 1:1, 1:N i N:M
- 1:1 - klucz obcy + UNIQUE w jednej z tabel
- 1:N - FK zawsze po stronie "wiele"
- N:M - tabela laczaca z dwoma FK i kluczem zlozonym
4. Normalizacja: 1NF, 2NF, 3NF
> :// {{ }} : }} }} }}/:http/{{/ {{举行的alyze>&&< & / {{">>{{ {{lt </{{/{{ {{ htt{{itize=http/{{< <<> <<。<.ht.ht://Elementy DOM:
- document.getElementById("x") - szuka po ID
- document.querySelector("selector") - szuka po selektorze CSS (pierwszy pasujacy)
- document.querySelectorAll("selector") - szuka wszystkich pasujacych
Zmiana DOM:
- textContent - zmienia tekst (bezpieczne)
- innerHTML - zmienia zawartosc HTML (niebezpieczne dla danych uzytkownika!)
- value - zmienia wartosc pola formularza
- style.property - zmienia styl CSS (camelCase: backgroundColor)
- classList.add/remove/toggle
Walidacja formularza
// Zdarzenie submit - zawsze z preventDefault!
form.addEventListener("submit", function(e) {
e.preventDefault();
// walidacja...
if (poprawny) form.submit();
});
// Sprawdzanie pol
const wartosc = document.getElementById("pole").value.trim();
if (wartosc === "") { /* blad */ }
// Walidacja email
const at = email.indexOf("@");
const kropka = email.lastIndexOf(".");
if (at < 1 || kropka < at + 2) { /* blad */ }
// Walidacja liczby
const liczba = Number(pole.value);
if (isNaN(liczba) || liczba < 1 || liczba > 120) { /* blad */ }
6. Zdarzenia i formularze
Najwazniejsze zdarzenia:
- click - klikniecie mysza
- submit - proba wyslania formularza (NA FORM, nie na button!)
- input - kazda zmiana tresci pola
- change - po zatwierdzeniu zmiany
- load - po wczytaniu strony
- mouseover - najechanie kursorem
- keyup - puszczenie klawisza
- focus/blur - wejscie/wyjscie z pola
// Skladnia
element.addEventListener("nazwa-zdarzenia", funkcja);
// Przyklad
przycisk.addEventListener("click", function(e) {
e.preventDefault(); // anuluje domyslne dzialanie
console.log("Kliknieto!");
});
// Kod po zbudowaniu DOM
document.addEventListener("DOMContentLoaded", function() {
console.log("Strona gotowa");
});
7. Local Storage i ciasteczka
// LOCAL STORAGE - dane przetrwaja zamkniecie przegladarki
localStorage.setItem("klucz", "wartosc");
localStorage.getItem("klucz"); // "wartosc"
localStorage.removeItem("klucz");
localStorage.clear();
// Zapis obiektu jako JSON
const koszyk = [{nazwa: "Mysz", cena: 79}];
localStorage.setItem("koszyk", JSON.stringify(koszyk));
const odczyt = JSON.parse(localStorage.getItem("koszyk"));
// SESSION STORAGE - dane znika po zamknieciu karty
sessionStorage.setItem("krok", "2");
sessionStorage.getItem("krok");
// CIASTECZKA - male (4KB), wysylane na serwer
document.cookie = "jezyk=pl; max-age=2592000; path=/";
document.cookie = "jezyk=; max-age=0; path=/"; // usuniecie
IV. Jezyk zapytan SQL
1. Podstawy - SELECT, WHERE, ORDER BY
-- Wszystkie kolumny
SELECT * FROM uczniowie;
-- Wybrane kolumny
SELECT imie, nazwisko FROM uczniowie;
-- Z usunieciem duplikatow
SELECT DISTINCT profil FROM klasy;
-- Warunki WHERE
SELECT * FROM oceny WHERE ocena > 3;
SELECT * FROM oceny WHERE ocena BETWEEN 4 AND 5; -- obustronnie domkniety!
SELECT * FROM uczniowie WHERE id_klasy IN (1, 3, 5);
SELECT * FROM uczniowie WHERE nazwisko LIKE 'Kow%'; -- % = dowolny ciag znakow
SELECT * FROM uczniowie WHERE email IS NULL; -- NIE uzywaj = NULL!
-- Sortowanie
SELECT * FROM uczniowie ORDER BY nazwisko ASC; -- rosnaco
SELECT * FROM uczniowie ORDER BY nazwisko DESC; -- malejaco
-- Ograniczenie wyniku
SELECT * FROM oceny ORDER BY ocena DESC LIMIT 5; -- 5 najwyzszych
SELECT * FROM uczniowie ORDER BY nazwisko LIMIT 10, 5; -- strona 3 (pomin 10, wez 5)
-- Aliasy i kolumny obliczaniowe
SELECT nazwisko AS 'Nazwisko ucznia', imie FROM uczniowie;
SELECT CONCAT(imie, ' ', nazwisko) AS pelne_imie FROM uczniowie;
WHERE email = NULL nie zwroci nic. Jedyny poprawny zapis to IS NULL lub IS NOT NULL.
2. DDL - tworzenie i zmiana struktury
-- Tworzenie bazy danych
CREATE DATABASE szkola DEFAULT CHARACTER SET utf8mb4;
-- Tworzenie tabeli
CREATE TABLE uczniowie (
id_ucznia INT AUTO_INCREMENT PRIMARY KEY,
imie VARCHAR(30) NOT NULL,
nazwisko VARCHAR(50) NOT NULL,
email VARCHAR(80) UNIQUE,
id_klasy INT,
FOREIGN KEY (id_klasy) REFERENCES klasy(id_klasy)
);
-- Modyfikacja tabeli
ALTER TABLE uczniowie ADD COLUMN telefon VARCHAR(15);
ALTER TABLE uczniowie MODIFY COLUMN nazwisko VARCHAR(80);
ALTER TABLE uczniowie DROP COLUMN telefon;
-- Usuwanie
DROP TABLE uczniowie; -- usuwa tabele i strukture
TRUNCATE TABLE uczniowie; -- usuwa dane, zostawia strukture, zeruje AUTO_INCREMENT
DELETE FROM uczniowie WHERE id = 1; -- usuwa wiersz, AUTO_INCREMENT rosnie dalej
3. DML - INSERT, UPDATE, DELETE
-- Wstawianie danych
INSERT INTO klasy (nazwa, profil, wychowawca)
VALUES ('3A', 'programista', 'Anna Kowalska');
-- Wiele wierszy
INSERT INTO klasy (nazwa, profil) VALUES ('3B', 'grafik'), ('4A', 'sieciowiec');
-- Aktualizacja
UPDATE uczniowie SET id_klasy = 3 WHERE id_ucznia = 7;
-- Usuwanie
DELETE FROM uczniowie WHERE id_ucznia = 12;
4. JOIN - laczenie tabel
-- INNER JOIN - tylko pasujace wiersze z obu stron
SELECT u.imie, k.nazwa AS klasa
FROM uczniowie AS u
INNER JOIN klasy AS k ON u.id_klasy = k.id_klasy;
-- LEFT JOIN - wszystkie z lewej + pasujace z prawej (NULL gdy brak)
SELECT u.nazwisko, o.ocena
FROM uczniowie AS u
LEFT JOIN oceny AS o ON u.id_ucznia = o.id_ucznia;
-- RIGHT JOIN - wszystkie z prawej + pasujace z lewej
SELECT u.nazwisko, k.nazwa AS klasa
FROM uczniowie AS u
RIGHT JOIN klasy AS k ON u.id_klasy = k.id_klasy;
-- Laczenie wielu tabel
SELECT k.nazwa AS klasa, u.nazwisko, p.nazwa AS przedmiot, o.ocena
FROM oceny AS o
INNER JOIN uczniowie AS u ON o.id_ucznia = u.id_ucznia
INNER JOIN przedmioty AS p ON o.id_przedmiotu = p.id_przedmiotu
INNER JOIN klasy AS k ON u.id_klasy = k.id_klasy;
-- Uczniowie BEZ ocen (LEFT JOIN + IS NULL)
SELECT u.imie, u.nazwisko
FROM uczniowie AS u
LEFT JOIN oceny AS o ON u.id_ucznia = o.id_ucznia
WHERE o.id_oceny IS NULL;
Przy kolumnie o tej samej nazwie w dwoch tabelach trzeba ja poprzedzic nazwa tabeli (u.imie, k.nazwa).
5. Agregacja, GROUP BY, HAVING
-- Funkcje agregujace
SELECT COUNT(*) AS ile FROM uczniowie;
SELECT COUNT(email) AS z_mailem FROM uczniowie; -- NULL nie jest liczony
SELECT AVG(ocena) AS srednia FROM oceny;
SELECT MIN(ocena) AS najnizsza, MAX(ocena) AS najwyzsza FROM oceny;
SELECT SUM(liczba_godzin) AS suma FROM przedmioty;
-- GROUP BY - grupowanie
SELECT k.nazwa AS klasa, COUNT(u.id_ucznia) AS liczba_uczniow
FROM klasy AS k
LEFT JOIN uczniowie AS u ON k.id_klasy = u.id_klasy
GROUP BY k.nazwa;
-- Srednia kazdego ucznia
SELECT u.nazwisko, ROUND(AVG(o.ocena), 2) AS srednia
FROM uczniowie AS u
INNER JOIN oceny AS o ON u.id_ucznia = o.id_ucznia
GROUP BY u.id_ucznia, u.nazwisko;
-- HAVING - filtrowanie po grupowaniu
SELECT k.nazwa, COUNT(u.id_ucznia) AS ilu
FROM klasy AS k
INNER JOIN uczniowie AS u ON k.id_klasy = u.id_klasy
GROUP BY k.nazwa
HAVING COUNT(u.id_ucznia) > 25;
-- Podzapytania
SELECT id_ucznia, ocena FROM oceny
WHERE ocena > (SELECT AVG(ocena) FROM oceny);
SELECT imie, nazwisko FROM uczniowie
WHERE id_klasy IN (SELECT id_klasy FROM klasy WHERE profil = 'programista');
6. DCL - uprawnienia
-- Tworzenie uzytkownika
CREATE USER 'nauczyciel'@'localhost' IDENTIFIED BY 'Haslo1';
-- Nadawanie uprawnien
GRANT SELECT ON szkola.* TO 'nauczyciel'@'localhost';
GRANT SELECT, INSERT, UPDATE, DELETE ON szkola.* TO 'sekretariat'@'%';
GRANT ALL PRIVILEGES ON szkola.* TO 'admin'@'localhost' WITH GRANT OPTION;
-- Odbieranie uprawnien
REVOKE DELETE ON szkola.* FROM 'sekretariat'@'%';
-- Usuwanie uzytkownika
DROP USER 'nauczyciel'@'localhost';
Alias z SELECT NIE dziala w WHERE (alias powstaje w kroku 5, WHERE w kroku 2). Dziala w ORDER BY i HAVING.
V. Programowanie po stronie serwera (PHP)
1. Podstawy skladni
<?php
// Zmienne - zaczynaja sie od dolara, bez deklaracji typu
$imie = "Anna";
echo "Witaj, " . $imie; // kropka = konkatenacja
echo "<p>Witaj, $imie</p>"; // zmienna w cudzyslowie sie rozwija
// Cudzyslow vs apostrof
echo '$imie'; // wypisze: $imie (doslownie)
echo "$imie"; // wypisze: Anna (rozwija zmienna)
// Tablice
$tab = [1, 2, 3];
$tab_asoc = ["imie" => "Anna", "wiek" => 17];
echo $tab_asoc["imie"]; // Anna
// Petla foreach
foreach ($tab_asoc as $klucz => $wartosc) {
echo "$klucz: $wartosc<br>";
}
// Funkcje
function podatek($kwota, $stawka = 0.23) {
return $kwota * $stawka;
}
echo podatek(1000); // 230
?>
2. Formularze: GET i POST
<!-- formularz.html -->
<form action="wynik.php" method="post">
<input type="text" name="imie">
<button type="submit">Wyslij</button>
</form>
<!-- wynik.php -->
<?php
if (isset($_POST["imie"])) {
echo "Witaj, " . htmlspecialchars($_POST["imie"]);
}
?>
POST: dane w tresci zadania, niewidoczne, brak limitu. Do logowania i zapisu do bazy.
POST NIE jest szyfrowany! Jest tylko mniej widoczny. Poufne daje dopiero HTTPS.
3. Sesje i ciasteczka
<?php
session_start(); // MUSI byc PRZED jakimkolwiek wyjsciem na strone
$_SESSION["uzytkownik"] = "anna"; // zapis
echo $_SESSION["uzytkownik"]; // odczyt
session_destroy(); // wylogowanie
?>
4. Obsluga plikow
<?php
// Zapis do pliku
file_put_contents("dane.txt", "nowa linia\n", FILE_APPEND);
// Odczyt calego pliku
$linie = file("dane.txt", FILE_IGNORE_NEW_LINES);
foreach ($linie as $linia) {
echo $linia . "<br>";
}
?>
5. Polaczenie z baza danych (mysqli)
<?php
// Polaczenie
$polaczenie = new mysqli("localhost", "root", "", "baza");
if ($polaczenie->connect_errno) {
die("Blad polaczenia: " . $polaczenie->connect_error);
}
$polaczenie->set_charset("utf8"); // OBOWIAZKOWE dla polskich znakow
// Zapytanie
$wynik = $polaczenie->query("SELECT nazwa, cena FROM produkty");
// Petla po wynikach
while ($wiersz = $wynik->fetch_assoc()) {
echo "<p>" . $wiersz["nazwa"] . " - " . $wiersz["cena"] . " zl</p>";
}
$polaczenie->close();
?>
6. Bezpieczenstwo
XSS - wstrzykniecie skryptu u innego uzytkownika. Obrona: htmlspecialchars() przy kazdym wypisywaniu danych od uzytkownika.
Hasla - nigdy nie zapisuj jawnie. Obrona: password_hash() i password_verify().
// Zapytanie przygotowane - BEZPIECZNE
$stmt = $polaczenie->prepare("SELECT * FROM uzytkownicy WHERE login = ?");
$stmt->bind_param("s", $_POST["login"]);
$stmt->execute();
$wynik = $stmt->get_result();
// Bezpieczne wypisywanie danych
echo htmlspecialchars($_POST["imie"]);
7. Podzial kodu: include i require
<?php
// polaczenie.php - dane dostepowe
$polaczenie = new mysqli("localhost", "root", "", "baza");
$polaczenie->set_charset("utf8mb4");
?>
<!-- index.php -->
<?php require_once "polaczenie.php"; ?>
<header>...</header>
<main>Tresc</main>
<?php include "stopka.php"; ?>
require - gdy pliku nie ma, zglasza blad krytyczny i przerywa.
_once - zapobiega podwojnemu dolaczeniu. Polaczenie z baza i funkcje = require_once. Naglowek, stopka = include.
8. Funkcje tekstowe i daty
// Tekst
strlen("tekst") // dlugosc
substr("tekst", 0, 3) // "tek"
str_replace("a", "b", "tekst") // podmiana
trim(" tekst ") // obcina spacje
explode(";", "a;b;c") // tablica: ["a", "b", "c"]
implode(", ", $tab) // tekst: "a, b, c"
ucfirst("anna") // "Anna"
// Liczby
number_format(12345.678, 2, ",", " ") // "12 345,68"
round($cena, 2) // 19.9 (nie 19.90!)
round($cena, 2) i number_format() // "19,90"
// Daty
echo date("Y-m-d"); // 2026-08-16
echo date("d.m.Y", strtotime("2026-01-14")); // 14.01.2026
echo date("Y-m-d", strtotime("$data +7 days")); // +7 dni
9. Wysylanie plikow na serwer
<!-- Formularz MUSI miec enctype -->
<form action="wyslij.php" method="post" enctype="multipart/form-data">
<input type="file" name="zdjecie">
<input type="submit" value="Wyslij">
</form>
<?php
// wyslij.php
if (isset($_FILES["zdjecie"]) && $_FILES["zdjecie"]["error"] === 0) {
$nazwa = $_FILES["zdjecie"]["name"];
$tymczas = $_FILES["zdjecie"]["tmp_name"];
$rozmiar = $_FILES["zdjecie"]["size"];
$dozwolone = ["jpg", "jpeg", "png", "gif"];
$rozsz = strtolower(pathinfo($nazwa, PATHINFO_EXTENSION));
if (!in_array($rozsz, $dozwolone)) {
echo "Niedozwolony typ pliku.";
} elseif ($rozmiar > 2 * 1024 * 1024) {
echo "Plik wiekszy niz 2 MB.";
} else {
move_uploaded_file($tymczas, "zdjecia/" . $nazwa);
echo "Wyslano: " . $nazwa;
}
}
?>
Nieistniejacy katalog docelowy - move_uploaded_file nie tworzy folderow automatycznie.
- Odebranie danych z formularza i wypisanie na stronie (praktycznie w kazdym arkuszu)
- Polaczenie z baza i wyswietlenie wyniku zapytania w petli
- Roznica miedzy GET a POST (pytanie zamkniete)
- Rola sesji przy logowaniu i session_start()
- Wskazanie zagrozenia i obrony (SQL Injection, XSS)
- Wspolny naglowek/stopka = include/require
- Wyswietlanie daty z bazy i ceny z dwoma miejscami po przecinku
- Formularz wysylania pliku z walidacja rozszerzenia