Prejsť na obsah

Prehľad filozofie

Framework DotApp je navrhnutý na tvorbu prenosných a udržiavateľných modulov, ktoré bezproblémovo fungujú v rôznych prostrediach. Dodržiavaním týchto postupov sa vaše moduly prispôsobia ovládaču session používateľa (napríklad Redis, databáza) aj databázovému ovládaču (PDO, MySQLi) bez zmeny kódu. Aplikácia tak ostane flexibilná a zdieľateľná, v súlade so základnou filozofiou DotApp: modularitou a prispôsobivosťou.

Kľúčovým aspektom filozofie DotApp je bezpečnosť vstupov. Predvolene sú všetky vstupy automaticky chránené pred bežnými zraniteľnosťami, napríklad Cross-Site Scripting (XSS). Tento návrh drží aplikáciu v bezpečí aj vtedy, keď sa na jeden vstup zabudne. Na prístup k pôvodnej, nechránenej hodnote — napríklad pri ukladaní HTML — použite DotApp::DotApp()->unprotect($variable). Metóda prijíma reťazec alebo pole referenciou a ochranu odstráni rekurzívne. Napríklad:


use \Dotsystems\App\DotApp;

$variable = $_POST['variable'];
DotApp::DotApp()->unprotect($variable); // $variable now contains the original, unprotected value
    

Všimnite si, že unprotect mení premennú referenciou, preto ho volajte ako DotApp::DotApp()->unprotect($variable) bez priraďovania výsledku (t. j. vyhnite sa $variable = DotApp::DotApp()->unprotect($variable)). Tento prístup posilňuje filozofiu DotApp: vývojári nemusia premenné chrániť ručne, predvolene sú bezpečné, no majú možnosť získať nechránené hodnoty, keď to výslovne potrebujú.

Prístup k inštancii DotApp

Jadro DotApp je dostupné ako DotApp::DotApp(). Použite ho na unprotect, ajaxReply a call. Routovanie, dopyty, view, konfigurácia a session používajú fasády.


use Dotsystems\App\DotApp;

DotApp::DotApp()->unprotect($htmlFromEditor);
DotApp::DotApp()->ajaxReply(['status' => 1], 200);
DotApp::call('HelloWorld:Home@index!', $request);
    

V initialize($dotApp) je jadro argumentom metódy. Služby registrujte pomocou $dotApp->bind / singleton / resolve. Kontroléry používajú DotApp::DotApp() alebo fasády.

Použitie fasád

Fasády sú verejné API pre základné služby.

Napríklad:


Renderer::new()->module(self::moduleName())->setView("dotapper-cli.eng")->setViewVar("variables", $viewVars)->renderView();
    

Fasáda Renderer drží kód stručný. Vlastné renderery:


Renderer::add("Docs.code.replace", function($code) { /* logic */ });
    

Bežné fasády

  • Renderer::new(): Vráti resetovateľný objekt renderera.
  • Renderer::add(): Pridá vlastný renderer.
  • Router::get(): Definuje GET trasu, napríklad Router::get(['/helloworld', '/helloworld/'], "HelloWorld:Home@index!", Router::STATIC_ROUTE);.

Používanie fasád zlepšuje čitateľnosť kódu a je v súlade s filozofiou DotApp: čistý, udržiavateľný kód.

Dependency Injection

Vlastné služby registrujte v initialize($dotApp):


public function initialize($dotApp) {
    $dotApp->singleton('cache', function () {
        return new CacheService();
    });
}
    

Kontroléry vykresľujú pomocou Renderer::new():


public static function index($request) {
    return Renderer::new()->module('HelloWorld')->setView('hello')->renderView();
}
    

Databázové postupy

Aby boli vaše moduly prenosné a nezávislé od ovládača, filozofia DotApp vyžaduje prístup k databáze cez fasádu DB::module(). Táto fasáda podľa konfiguračných nastavení automaticky vyberie nakonfigurovaný ovládač a databázu, čím zabezpečí konzistenciu v celej aplikácii.

Použitie DB::module()

Na databázové dopyty použite DB::module("ORM") alebo DB::module("RAW"):


DB::module("RAW")->q(function ($qb) use ($token) {
    $qb
        ->select('user_id', Config::get("db","prefix").'users_rmtokens')
        ->where('token', '=', $token);
})->execute(
    function ($result) {
        // $result is an array of rows in RAW mode
    },
    function ($error) {
        \Dotsystems\App\Parts\Logger::use()->error('query failed', ['msg' => is_object($error) ? $error->getMessage() : (string) $error]);
    }
);
    

Použitie callbackov

Do execute() vždy odovzdajte callback úspechu aj callback chyby. Callback úspechu v režime RAW dostane pole riadkov.

  • Callback úspechu: function($result, $db, $debug)$result je v režime RAW pole riadkov.
  • Callback chyby: function($error, $db, $debug) — povinný, aby sa zlyhania spracovali.

DB::module("RAW")->q(function ($qb) use ($token) {
    $qb
        ->select('user_id', Config::get("db","prefix").'users_rmtokens')
        ->where('token', '=', $token);
})->execute(
    function ($result, $db, $debug) use (&$data) {
        if ($result === null || $result === []) {
            $data = [];
            setcookie('dotapp_'.Config::get("app","name_hash"), "", [
                'expires' => time() - 3600,
                'path' => Config::session("path"),
            ]);
        } else {
            $db->q(function ($qb) use (&$data, $result) {
                $qb
                    ->select(['username', 'password'], Config::get("db","prefix").'users')
                    ->where('id', '=', $result['user_id']);
            })->execute(function ($result, $db, $debug) use (&$data) {
                $data['username'] = $result[0]['username'];
                $data['passwordHash'] = $result[0]['password'];
                $data['stage'] = 0;
                \Dotsystems\App\Parts\Auth::login($data, true);
            }, function ($error, $db, $debug) {
                // Handle error, e.g., log or display error message
                $data['error'] = $error->getMessage();
            });
        }
    },
    function ($error, $db, $debug) {
        // Handle initial query error
        error_log("Database error: " . $error->getMessage());
    }
);
    

V tomto príklade:

  • Callback success spracuje pole $result, ktoré je nezávislé od ovládača (napríklad $result[0]['user_id']).
  • Vnorený dopyt používa ďalšie execute s vlastnými callbackmi success a error na spracovanie výsledkov alebo chýb.
  • Callback error zaloguje alebo spracuje databázové chyby a zabráni nespracovaným výnimkám.

Ak callbacky vedú k zložitému kódu (callback hell), výsledky môžete uložiť do premennej a logiku zjednodušiť:


$dbreturn = null;
DB::module("RAW")->q(function ($qb) use ($token) {
    $qb
        ->select('user_id', Config::get("db","prefix").'users_rmtokens')
        ->where('token', '=', $token);
})->execute(
    function ($result, $db, $debug) use (&$dbreturn) {
        $dbreturn = $result;
    },
    function ($error, $db, $debug) {
        error_log("Database error: " . $error->getMessage());
    }
);
// Continue logic with $dbreturn
    

Dôležité: Nevracajte surové objekty ovládača (napríklad $returnDB = DB::module("RAW")->q(...)->execute()), pretože sú špecifické pre ovládač (MySQLi alebo PDO). Používanie callbackov zabezpečí, že modul bude fungovať s ľubovoľným ovládačom, v súlade s filozofiou DotApp.

Správa session pomocou DSM

DotApp Session Manager (DSM) je povinná súčasť správy session a nahrádza priame použitie $_SESSION. DSM abstrahuje podkladový ovládač session (napríklad predvolený, súborový, databázový, Redis), takže vaša aplikácia alebo modul ostane prenosný medzi rôznymi prostrediami.

Použitie DSM

DSM importujte a použite takto:


use \Dotsystems\App\Parts\DSM;

$dsm = new DSM("MyModuleStorage");
$dsm->load();
$dsm->set('variable1', "hello");
    

Prípadne použite fasádu DSM pre čistejší kód (odporúčané):


DSM::use("MyModuleStorage")->set('variable1', "hello");
echo DSM::use("MyModuleStorage")->get('variable1'); // Outputs: hello
    

Každý modul by si mal vytvoriť vlastné úložisko (napríklad MyModuleStorage), aby sa vyhol konfliktom s inými modulmi. Premenné v rôznych úložiskách môžu zdieľať rovnaký názov bez kolízií.

Kľúčové metódy DSM

  • set($name, $value): Nastaví session premennú.
  • get($name): Získa session premennú.
  • delete($name): Odstráni session premennú.
  • clear(): Vymaže všetky premenné v úložisku.
  • start(): Automaticky sa volá v konštruktore.
  • destroy(): Zničí úložisko (voliteľné).
  • session_id(): Vráti ID session.
  • load(): Načíta session (pri fasáde nie je potrebné).
  • save(): Uloží session (automaticky pri zničení).

Najčastejšie používané metódy sú:


DSM::use("MyModuleStorage")->set('variable1', "hello");
DSM::use("MyModuleStorage")->get('variable1');
DSM::use("MyModuleStorage")->delete('variable1');
DSM::use("MyModuleStorage")->clear();
    

Prečo DSM? Použitie DSM namiesto $_SESSION zabezpečí, že je modul nezávislý od ovládača session. Prístup cez fasádu odstraňuje potrebu ručných volaní load() a robí kód čistejším a udržiavateľnejším.

Pozrieť príklady

Praktické príklady týchto odporúčaných postupov vrátane databázových dopytov s DB::module() a správy session pomocou DSM nájdete v sekcii Príklady. Tieto príklady ukazujú, ako postupy uplatniť v reálnych situáciách.