Načrtovanje in razvoj spletnih aplikacij

Vstavljanje podatkov v podatkovno zbirko - INSERT

Podatke v tabelo najpogosteje dodajamo prek obrazca. Uporabnik vnese podatke, PHP pa jih preveri in nato shrani v podatkovno zbirko z ukazom INSERT INTO.

Vnos podatkov v tabelo

Pri vnosu podatkov v spletni aplikaciji običajno pripravimo obrazec, v katerega uporabnik vnese podatke. Ob oddaji obrazca strežniška koda preveri pravilnost podatkov in jih nato shrani v tabelo.

Osnovna sintaksa za vnos enega zapisa je:

INSERT INTO imeTabele (stolpec1, stolpec2, stolpec3)
VALUES (vrednost1, vrednost2, vrednost3);

V spletnih aplikacijah je pomembno, da vnesene podatke:

  • preverimo,
  • očistimo,
  • varno shranimo s pripravljenimi SQL stavki,
  • zaščitimo obrazec pred zlorabami.

Tako zmanjšamo možnost napak in povečamo varnost aplikacije.

Osnovni primer z mysqli

Spodnji zgled prikazuje preprost vnos podatkov iz obrazca v tabelo knjige z uporabo pripravljenega stavka.

<?php
define('DB_SERVER', 'localhost');
define('DB_USER', 'uporabnik');
define('DB_PASS', 'skritoGeslo');
define('DB_NAME', 'knjiznica');

// Povezava do podatkovne zbirke
$connection = mysqli_connect(DB_SERVER, DB_USER, DB_PASS, DB_NAME);

// Preverjanje povezave
if (!$connection) {
    die(
        'Povezava s podatkovno zbirko ni vzpostavljena: ' .
        mysqli_connect_error() .
        ' (' . mysqli_connect_errno() . ')'
    );
}

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $priimek = trim($_POST['priimek'] ?? '');
    $ime = trim($_POST['ime'] ?? '');
    $naslov = trim($_POST['naslov'] ?? '');
    $strani = (int)($_POST['strani'] ?? 0);
    $cena = (float)($_POST['cena'] ?? 0);
    $leto = (int)($_POST['leto'] ?? 0);

    $stmt = mysqli_prepare(
        $connection,
        "INSERT INTO knjige
        (Priimek_avtorja, Ime_avtorja, Naslov, Strani, Cena, Leto)
        VALUES (?, ?, ?, ?, ?, ?)"
    );

    mysqli_stmt_bind_param($stmt, 'sssidi', $priimek, $ime, $naslov, $strani, $cena, $leto);

    if (mysqli_stmt_execute($stmt)) {
        echo 'Zapis je bil uspešno dodan.';
    } else {
        echo 'Napaka pri vnosu podatkov.';
    }

    mysqli_stmt_close($stmt);
}

mysqli_close($connection);
?>

Osnovni primer s PDO

Tudi z vmesnikom PDO podatke praviloma vnašamo s pripravljenimi stavki in vezanimi parametri.

<?php
$streznik = 'localhost';
$baza = 'knjiznica';
$uporabnik = 'uporabnik';
$geslo = 'skritoGeslo';

try {
    // Povezava do podatkovne zbirke
    $pdo = new PDO("mysql:host=$streznik;dbname=$baza;charset=utf8mb4", $uporabnik, $geslo);

    // Vklop izjem pri napakah
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        $priimek = trim($_POST['priimek'] ?? '');
        $ime = trim($_POST['ime'] ?? '');
        $naslov = trim($_POST['naslov'] ?? '');
        $strani = (int)($_POST['strani'] ?? 0);
        $cena = (float)($_POST['cena'] ?? 0);
        $leto = (int)($_POST['leto'] ?? 0);

        $stmt = $pdo->prepare(
            "INSERT INTO knjige
            (Priimek_avtorja, Ime_avtorja, Naslov, Strani, Cena, Leto)
            VALUES
            (:priimek, :ime, :naslov, :strani, :cena, :leto)"
        );

        $stmt->bindValue(':priimek', $priimek, PDO::PARAM_STR);
        $stmt->bindValue(':ime', $ime, PDO::PARAM_STR);
        $stmt->bindValue(':naslov', $naslov, PDO::PARAM_STR);
        $stmt->bindValue(':strani', $strani, PDO::PARAM_INT);
        $stmt->bindValue(':cena', number_format($cena, 2, '.', ''), PDO::PARAM_STR);
        $stmt->bindValue(':leto', $leto, PDO::PARAM_INT);

        $stmt->execute();

        echo 'Zapis je bil uspešno dodan.';
    }
}
catch (PDOException $e) {
    echo 'Napaka pri vnosu podatkov: ' . $e->getMessage();
}
?>

Zaščita obrazca s CSRF žetonom

Pri obrazcih ni pomembno le preverjanje podatkov, ampak tudi zaščita pred zlorabami. Ena od pogostih zaščit je uporaba CSRF žetona.

CSRF je kratica za Cross-Site Request Forgery. Gre za napad, pri katerem bi napadalec skušal doseči, da uporabnikov brskalnik pošlje zahtevek naši aplikaciji brez njegove vednosti.

To preprečimo tako, da ob prikazu obrazca ustvarimo poseben žeton, ga shranimo v sejo in dodamo v obrazec kot skrito polje. Ko uporabnik obrazec odda, preverimo, ali se poslani žeton ujema z vrednostjo v seji.

<?php
// Ustvarjanje CSRF žetona
$_SESSION['csrf_zeton'] = bin2hex(random_bytes(32));
?>

<input type="hidden" name="csrf_zeton" value="<?php echo $_SESSION['csrf_zeton']; ?>">

Pri obdelavi obrazca nato preverimo veljavnost žetona. Če žeton manjka ali ni pravilen, obrazca ne obdelamo.

<?php
if (
    !isset($_POST['csrf_zeton'], $_SESSION['csrf_zeton']) ||
    $_POST['csrf_zeton'] !== $_SESSION['csrf_zeton']
) {
    die('Neveljaven obrazec.');
}
?>

Pomembnosti pri vnosu podatkov

  • uporabimo obrazec za vnos podatkov,
  • preverimo, ali so vsa obvezna polja pravilno izpolnjena,
  • številčne podatke preverimo posebej,
  • za vnos v bazo je priporočljiva uporaba pripravljenih stavkov,
  • obrazec lahko zaščitimo z CSRF žetonom,
  • po uspešnem vnosu uporabniku prikažemo potrditveno sporočilo.

📘Aplikacija Knjige

V priloženi aplikaciji Knjige sta vnos in obdelava razdeljena na dve datoteki: 06_vnos-obrazec.php pripravi obrazec za vnos podatkov o knjigi, 06_vnos.php pa izvede preverjanje, validacijo in shranjevanje v tabelo knjige.

Obrazec vsebuje polja za priimek avtorja, ime avtorja, naslov knjige, število strani, ceno in leto izida, poleg tega pa uporablja tudi CSRF žeton za zaščito obrazca.

Obdelava vnosa preveri poslane podatke, veljavnost CSRF žetona, izpiše morebitne napake, nato pa zapis shrani z varnim pripravljenim PDO stavkom. Po uspešnem vnosu se izpiše tudi posodobljen seznam vseh knjig.

Primer: aplikacija Knjige – 06_vnos-obrazec.php
Primer: aplikacija Knjige – 06_vnos.php

Navodila za izdelavo aplikacije Knjige

  1. Najprej pripravimo obrazec za vnos podatkov.
  2. V obrazec dodamo polja za vse podatke, ki jih želimo shraniti.
  3. Ob prikazu obrazca ustvarimo in shranimo CSRF žeton.
  4. Ob oddaji obrazca podatke preberemo v PHP.
  5. Preverimo veljavnost CSRF žetona.
  6. Podatke očistimo in preverimo njihovo pravilnost.
  7. Za vnos v bazo uporabimo pripravljen SQL stavek INSERT INTO.
  8. Po uspešnem vnosu prikažemo potrditveno sporočilo in po potrebi še posodobljen seznam zapisov.

Pri učenju je smiselno poznati oba pristopa:

  • mysqli za klasičen vnos podatkov v tabelo,
  • PDO za sodobnejši in bolj varen vnos z vezanimi parametri,
  • aplikacijski pristop, kjer sta obrazec in obdelava vnosa ločena.