0%

🗄️ MySQL datubāze PHP

MySQL ir visizplatītākā relāciju datubāzes pārvaldības sistēma. PHP piedāvā PDO (PHP Data Objects) — drošu un elastīgu veidu darbam ar datubāzēm.

php

SQL tabulas izveide

Pirms PHP koda, izveidosim demonstrācijas tabulu MySQL.

Teksts
-- Datubāzes izveide
CREATE DATABASE IF NOT EXISTS webpamati CHARACTER SET utf8mb4 COLLATE utf8mb4_latvian_ci;
USE webpamati;

-- Tabulas izveide
CREATE TABLE IF NOT EXISTS lietotaji (
    id         INT AUTO_INCREMENT PRIMARY KEY,
    vards      VARCHAR(50)  NOT NULL,
    uzvards    VARCHAR(50)  NOT NULL,
    epasts     VARCHAR(100) NOT NULL UNIQUE,
    loma       ENUM("admin","user","moderators") DEFAULT "user",
    aktīvs     TINYINT(1) DEFAULT 1,
    izveidots  DATETIME DEFAULT CURRENT_TIMESTAMP,
    atjauninats DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

-- Parauga dati
INSERT INTO lietotaji (vards, uzvards, epasts, loma) VALUES
    ("Anna",   "Bērziņa",  "anna@example.lv",   "admin"),
    ("Jānis",  "Kalniņš",  "janis@example.lv",  "user"),
    ("Marta",  "Ozola",    "marta@example.lv",  "user"),
    ("Pēteris","Zariņš",   "peteris@example.lv","moderators");

Savienojums ar datubāzi (PDO)

ℹ️ DSN formāts

DSN (Data Source Name) formāts: mysql:host=localhost;dbname=mana_db;charset=utf8mb4
Citām datubāzēm: pgsql:host=localhost;dbname=db, sqlite:/path/to/db.sqlite

Teksts
<?php
// db.php - Datubāzes konfigurācija un savienojums

define("DB_HOST",    "localhost");
define("DB_NAME",    "webpamati");
define("DB_USER",    "root");
define("DB_PASS",    "");
define("DB_CHARSET", "utf8mb4");

function savienoties(): PDO {
    $dsn = "mysql:host=" . DB_HOST
         . ";dbname=" . DB_NAME
         . ";charset=" . DB_CHARSET;

    $opcijas = [
        PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION, // Kļūdas kā izņēmumi
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,        // Asociatīvs masīvs
        PDO::ATTR_EMULATE_PREPARES   => false,                   // Īstie prepared stmts
    ];

    try {
        $pdo = new PDO($dsn, DB_USER, DB_PASS, $opcijas);
        return $pdo;
    } catch (PDOException $e) {
        // Produkcijā: neatzīmējiet $e->getMessage() lietotājam!
        error_log("Datubāzes kļūda: " . $e->getMessage());
        die("Diemžēl rasda tehniska problēma. Mēģiniet vēlāk.");
    }
}

// Savienoties
$pdo = savienoties();
echo "Savienojums veiksmīgs!<br>";
?>

SELECT – datu lasīšana

Teksts
<?php
$pdo = savienoties();

// ========================================
// 1. Iegūt visus ierakstus
// ========================================
$stmt = $pdo->query("SELECT * FROM lietotaji ORDER BY vards ASC");
$visi = $stmt->fetchAll(); // Visi masīvā

foreach ($visi as $l) {
    echo "{$l["vards"]} {$l["uzvards"]} - {$l["epasts"]}<br>";
}

// ========================================
// 2. Prepared Statement ar parametriem (DROŠĀKAIS veids!)
// ========================================

// Meklēt pēc ID
$id = 1;
$stmt = $pdo->prepare("SELECT * FROM lietotaji WHERE id = :id");
$stmt->execute(["id" => $id]);
$lietotājs = $stmt->fetch(); // Viens ieraksts

if ($lietotājs) {
    echo "Vārds: {$lietotājs["vards"]}<br>";
} else {
    echo "Lietotājs nav atrasts.<br>";
}

// Meklēt pēc lomas
$loma = "user";
$stmt = $pdo->prepare("SELECT * FROM lietotaji WHERE loma = :loma AND aktīvs = 1");
$stmt->execute(["loma" => $loma]);
$lietotāji = $stmt->fetchAll();

echo "Atrasti " . count($lietotāji) . " lietotāji ar lomu '$loma'<br>";

// ========================================
// 3. Meklēšana ar LIKE
// ========================================
$meklēt = "Ann";
$stmt = $pdo->prepare("SELECT * FROM lietotaji WHERE vards LIKE :vards OR uzvards LIKE :uzvards");
$stmt->execute([
    "vards"   => "%$meklēt%",
    "uzvards" => "%$meklēt%"
]);
$rezultāti = $stmt->fetchAll();

// ========================================
// 4. Skaits un agregācija
// ========================================
$stmt = $pdo->query("SELECT COUNT(*) as skaits, loma FROM lietotaji GROUP BY loma");
$statistika = $stmt->fetchAll();
foreach ($statistika as $s) {
    echo "Loma '{$s["loma"]}': {$s["skaits"]} lietotāji<br>";
}

// ========================================
// 5. Lapu lapošana (Pagination)
// ========================================
$lapa = (int) ($_GET["lapa"] ?? 1);
$ieraksti_lapā = 10;
$nobīde = ($lapa - 1) * $ieraksti_lapā;

$stmt = $pdo->prepare("SELECT * FROM lietotaji LIMIT :limits OFFSET :nobide");
$stmt->bindValue("limits", $ieraksti_lapā, PDO::PARAM_INT);
$stmt->bindValue("nobide", $nobīde, PDO::PARAM_INT);
$stmt->execute();
$lapa_dati = $stmt->fetchAll();
?>

INSERT – datu pievienošana

Teksts
<?php
$pdo = savienoties();

// Pievienot vienu ierakstu
$sql = "INSERT INTO lietotaji (vards, uzvards, epasts, loma) 
        VALUES (:vards, :uzvards, :epasts, :loma)";

$stmt = $pdo->prepare($sql);
$stmt->execute([
    "vards"   => "Kristīne",
    "uzvards" => "Liepa",
    "epasts"  => "kristine@example.lv",
    "loma"    => "user"
]);

// Iegūt pievienotā ieraksta ID
$jaunais_id = $pdo->lastInsertId();
echo "Pievienots lietotājs ar ID: $jaunais_id<br>";

// Ieteicama OOP metode ar bindParam (precīzāka par execute masīvu)
$stmt = $pdo->prepare("INSERT INTO lietotaji (vards, uzvards, epasts) VALUES (?, ?, ?)");
$stmt->bindParam(1, $vards, PDO::PARAM_STR);
$stmt->bindParam(2, $uzvārds, PDO::PARAM_STR);
$stmt->bindParam(3, $epasts, PDO::PARAM_STR);

$vards   = "Harijs";
$uzvārds = "Kalējs";
$epasts  = "harijs@example.lv";
$stmt->execute();
?>

UPDATE – datu atjaunināšana

Teksts
<?php
$pdo = savienoties();

// Atjaunināt pēc ID
$sql = "UPDATE lietotaji SET vards = :vards, epasts = :epasts WHERE id = :id";
$stmt = $pdo->prepare($sql);
$stmt->execute([
    "vards"  => "Anna-Marija",
    "epasts" => "anna.marija@example.lv",
    "id"     => 1
]);

$ietekme = $stmt->rowCount(); // Cik rindu mainītas
echo "Atjauninātās rindas: $ietekme<br>";

// Deaktivizēt lietotāju
$stmt = $pdo->prepare("UPDATE lietotaji SET aktīvs = 0 WHERE id = :id");
$stmt->execute(["id" => 5]);

// Masveidīga atjaunināšana
$stmt = $pdo->prepare("UPDATE lietotaji SET loma = 'user' WHERE loma = 'moderators'");
$stmt->execute();
echo "Mainīti: " . $stmt->rowCount() . " moderatori uz useriem<br>";
?>

DELETE – datu dzēšana

Teksts
<?php
$pdo = savienoties();

// Dzēst pēc ID
$stmt = $pdo->prepare("DELETE FROM lietotaji WHERE id = :id");
$stmt->execute(["id" => 10]);
echo "Dzēstas rindas: " . $stmt->rowCount() . "<br>";

// Dzēst pēc nosacījuma
$stmt = $pdo->prepare("DELETE FROM lietotaji WHERE aktīvs = 0 AND DATEDIFF(NOW(), atjauninats) > 90");
$stmt->execute();
echo "Dzēsti neaktīvie (>90 dienas): " . $stmt->rowCount() . "<br>";

// UZMANĪGI: DELETE bez WHERE dzēš VISU!
// $pdo->exec("DELETE FROM lietotaji"); // Dzēš VISUS ierakstus!
?>

Transakcijas

Transakcijas nodrošina, ka vairāki SQL vaicājumi izpildās visi vai neviens.

Teksts
<?php
$pdo = savienoties();

try {
    $pdo->beginTransaction(); // Sākt transakciju

    // Pārskaitīt naudu starp kontiem
    $no_konta  = 1;
    $uz_kontu  = 2;
    $summa     = 100.00;

    // 1. Pārbaudīt bilanci
    $stmt = $pdo->prepare("SELECT bilance FROM konti WHERE id = :id FOR UPDATE");
    $stmt->execute(["id" => $no_konta]);
    $konts = $stmt->fetch();

    if (!$konts || $konts["bilance"] < $summa) {
        throw new RuntimeException("Nepietiek naudas!");
    }

    // 2. Noņemt no konta A
    $stmt = $pdo->prepare("UPDATE konti SET bilance = bilance - :summa WHERE id = :id");
    $stmt->execute(["summa" => $summa, "id" => $no_konta]);

    // 3. Pievienot kontam B
    $stmt = $pdo->prepare("UPDATE konti SET bilance = bilance + :summa WHERE id = :id");
    $stmt->execute(["summa" => $summa, "id" => $uz_kontu]);

    // 4. Ierakstīt transakciju vēsturē
    $stmt = $pdo->prepare("INSERT INTO transakcijas (no_id, uz_id, summa) VALUES (:no, :uz, :s)");
    $stmt->execute(["no" => $no_konta, "uz" => $uz_kontu, "s" => $summa]);

    $pdo->commit(); // Apstiprināt visas izmaiņas
    echo "Pārskaitīšana veiksmīga!<br>";

} catch (Exception $e) {
    $pdo->rollBack(); // Atcelt VISAS izmaiņas
    echo "Kļūda: " . $e->getMessage() . "<br>";
}
?>

Datubāzes klase (OOP pieeja)

🎓 Ko mācīties tālāk?

Nākamajā sadaļā uzzināsiet, kā sūtīt epastu no PHP mājaslapas.

Teksts
<?php
class Datubaze {
    private static ?PDO $savienojums = null;

    // Singleton pattern - tikai viens savienojums
    public static function savienoties(): PDO {
        if (self::$savienojums === null) {
            $dsn = "mysql:host=localhost;dbname=webpamati;charset=utf8mb4";
            self::$savienojums = new PDO($dsn, "root", "", [
                PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            ]);
        }
        return self::$savienojums;
    }
}

class LietotajuRepozitorijs {
    private PDO $db;

    public function __construct() {
        $this->db = Datubaze::savienoties();
    }

    public function atrastPecId(int $id): ?array {
        $stmt = $this->db->prepare("SELECT * FROM lietotaji WHERE id = :id");
        $stmt->execute(["id" => $id]);
        return $stmt->fetch() ?: null;
    }

    public function atrastVisus(int $limits = 50): array {
        $stmt = $this->db->prepare("SELECT * FROM lietotaji LIMIT :limits");
        $stmt->bindValue("limits", $limits, PDO::PARAM_INT);
        $stmt->execute();
        return $stmt->fetchAll();
    }

    public function saglabāt(array $dati): int {
        $sql = "INSERT INTO lietotaji (vards, uzvards, epasts) VALUES (:v, :u, :e)";
        $stmt = $this->db->prepare($sql);
        $stmt->execute(["v" => $dati["vards"], "u" => $dati["uzvards"], "e" => $dati["epasts"]]);
        return (int) $this->db->lastInsertId();
    }

    public function dzēst(int $id): bool {
        $stmt = $this->db->prepare("DELETE FROM lietotaji WHERE id = :id");
        $stmt->execute(["id" => $id]);
        return $stmt->rowCount() > 0;
    }
}

// Izmantošana:
$repo = new LietotajuRepozitorijs();
$visi = $repo->atrastVisus(10);
foreach ($visi as $l) {
    echo "{$l["vards"]} {$l["uzvards"]}<br>";
}
?>