Skip to content

Popis tříd k přístupu k databázi

Tento dokument popisuje hlavní PHP třídy v core/database. Cílem je přiblížit novému vývojáři, jak třídy fungují, jak spolu souvisejí a co je jejich odpovědnost.


Třída DB

Statická brána k databázovému rozhraní. Poskytuje přístup k metodám přes statické volání, ale veškerou práci deleguje na vnitřní instanci třídy PDOHandler.

Automatická inicializace (lazy loading)

Třída DB využívá lazy initialization - připojení k databázi se vytvoří automaticky při prvním volání libovolné metody (query(), results(), row(), atd.).

Není potřeba:

  • Manuálně volat DB::init()
  • Includovat app/database.php
  • Dělat cokoliv na inicializaci - DB se postará automaticky

Příklad:

// Automaticky se inicializuje při prvním dotazu - bez jakéhokoli require
$users = DB::results("SELECT * FROM users");
echo count($users);  // Funguje okamžitě!

Interně je připojení inicializováno prostřednictvím ensureInitialized() metody, která se volá automaticky před prvním SQL dotazem.

Klíčové public metody

  • DB::query($sql, $params = []) – provede SQL dotaz
  • DB::results($sql, $params = [], asArray: false) – vrátí více řádků
  • DB::row($sql, $params = [], asArray: false) – vrátí jeden řádek
  • DB::var($sql, $params = []) – vrátí jednu hodnotu
  • DB::col($sql, $params = []) – vrátí jeden sloupec
  • DB::test($sql, $params = [])debug helper: vypíše finální SQL s dosazením parametrů (bez spuštění)
  • DB::beginTransaction(), commit(), rollback() – správa transakcí
  • DB::set($fields) – generuje SET část dotazu
  • DB::getLog() – vrátí pole logovaných dotazů s časy

Třída PDOHandler

Třída, která drží instanci PDO a vykonává reálné SQL operace. Je použita interně v DB::$DB. Lze ji použít přímo jako instanci pro sekundární DB připojení.

Klíčové public metody

  • __construct(...) – vytvoření připojení
  • static fromUrl(string $url): self – factory z DATABASE_URL stringu
  • query(), results(), row(), var(), col() – stejné jako DB
  • beginTransaction(), commit(), rollback() – transakce
  • getLog(): array – logované dotazy s časy (dědí z Base)

Proč není veřejné prepare()/execute() API

PDO je nakonfigurováno s ATTR_EMULATE_PREPARES = false. To znamená, že každé volání DB::query(), DB::results() atd. interně provede server-side prepare + execute – MariaDB cache statement automaticky na straně serveru.

Explicitní prepare()/execute() přináší výhodu jen v situaci, kdy opakuješ identický SQL dotaz stovkykrát v jednom requestu (ušetříš roundtrip na první prepare). V CMS requestu se to nestane – typický request provede 5–30 různých dotazů.

// Zbytečné - žádná výhoda oproti DB::query() v CMS kontextu
$stmt = DB::prepare("UPDATE users SET name = ? WHERE id = ?");
DB::execute($stmt, [$name, $id]);

// Totéž, jednodušší
DB::query("UPDATE users SET name = ? WHERE id = ?", [$name, $id]);

Interně PDOHandler stále používá prepare/execute pro každý dotaz – jen to není vystaveno jako public API, protože explicitní volání nepřináší nic navíc.


Třída Base

Poskytuje základní infrastrukturu – výsledky dotazů, stavové proměnné a možnosti nastavení.

Klíčové vlastnosti

  • $lastQuery, $lastError, $queryError, $lastResult, $insertId, $affectedRows, $numRows
  • setting(array $array)

Vztahy mezi třídami

classDiagram
    class DB {
        +static init()
        +static query()
        +static prepare()
        +static beginTransaction()
        +static getLastInsertId()
    }

    class PDOHandler {
        +query()
        +prepare()
        +getLastInsertId()
        +getLastError()
    }

    class Base {
        +lastQuery
        +lastError
        +setting()
    }

    DB --> PDOHandler : obsahuje instanci
    PDOHandler --> Base : dědí

Sekundární databáze (PDOHandler přímo)

Pro výjimečné případy připojení k externí nebo partnerské databázi se použije PDOHandler přímo jako instance — bez statické třídy.

Kdy se to používá

  • Integrace se starším systémem (legacy databáze)
  • Partnerský web / subdoména s vlastní DB
  • Datový sklad s jinými přihlašovacími údaji

V 99% projektů na Petrovo CMS stačí jen DB.

Použití

use Petrovo\Database\PDOHandler;

$db2 = PDOHandler::fromUrl(env('PARTNER_DATABASE_URL'));

$rows = $db2->results("SELECT * FROM products WHERE active = ?", [1]);
$row  = $db2->row("SELECT * FROM orders WHERE id = ?", [$id]);
$db2->getLog(); // timing k dispozici

Nebo s přímými parametry:

$db2 = new PDOHandler('user', 'pass', 'dbname', 'host.example.com');

Rozdíl od DB

Aspekt DB PDOHandler instance
Inicializace Automatická (lazy) new nebo fromUrl()
Přístup Statický DB:: Instance $db2->
Debug bar ✅ DB::getLog() $db2->getLog() (samostatné)
API metody Stejné Stejné

Shrnutí (důležité pro vývojáře)

  • Používej DB:: pro veškeré databázové operace — auto-init, žádný setup
  • Vždy používej parametrizované dotazy (DB::query($sql, $params))
  • Výsledky vrací objekty (přístup ->columnName); pole jen pokud explicitně asArray: true
  • Base poskytuje metadata: lastQuery, lastError, affectedRows, insertId, getLog()
  • Pro sekundární databázi: PDOHandler::fromUrl(env('...')) nebo new PDOHandler(...)