Prejsť na obsah

Framework DotApp Aktualizované: 2026-08-19


O autorovi

Volám sa Štefan Miščík a som senior fullstack web vývojár v Dotsystems s.r.o. (WEB)

Ciele návrhu

DotApp je PHP framework pre aplikácie každej veľkosti. Aplikačná logika žije v moduloch. Každý modul vlastní svoje trasy, kontroléry, middleware, views a assets.

Práce na DotApp sa začali v roku 2014 ako kompletná aplikačná architektúra: smerovanie, vykresľovanie, bezpečnosť a databázová vrstva zdieľajú jedno runtime prostredie a jednu sadu konvencií.


Konvencie

Verejné API používa fasády, modulové kontroléry a malú sadu konvencií:

Fasády

Fasády (Router, Route, DB, Request, Renderer::new()) sú verejné API pre kľúčové služby. Aplikačné trasy sa registrujú v module.init.php každého modulu.

Fasády Router a Route

Použite fasády Router a Route (sú to vzájomné aliasy) v module.init.php. Príklad: Router::get('/helloworld', 'HelloWorld:Home@index!', Router::STATIC_ROUTE).


// app/modules/HelloWorld/module.init.php → initialize($dotApp)
Router::get('/helloworld', fn() => 'Hello World', Router::STATIC_ROUTE);
Route::get('/helloworld', fn() => 'Hello World', Router::STATIC_ROUTE);
Router::get('/helloworld', 'HelloWorld:Home@index!', Router::STATIC_ROUTE);
Route::get('/helloworld', 'HelloWorld:Home@index!', Router::STATIC_ROUTE);
                    
Fasáda DB

Použite fasádu DB. Dopyty vykonávajte cez DB::module('RAW').


DB::module('RAW')->q(function ($qb) {
    $qb->select(['id', 'title'])->from('helloworld_notes')->where('id', '=', 1);
})->all();
                    
Fasáda Request

V kontroléroch čítajte aktuálnu požiadavku z argumentu $request. Fasáda Request je k dispozícii, keď ste mimo callbacku kontroléra.


Request::getPath(); // Get the current request path
Request::getMethod(); // Get the HTTP method (e.g., GET, POST)
Request::data(); // Access request data (e.g., POST or JSON payload)
$request->form(['POST'], 'myForm', function ($request) {
    return 'Form submitted!';
}, function () {
    return 'Invalid form';
});
                    


Inštancia DotApp

Smerovanie, databáza, vykresľovanie, konfigurácia a úložisko relácií používajú fasády: Router::, DB::, Renderer::new(), Config::, DSM::use(). Keď potrebujete samotné jadro (udalosti, unprotect, ajaxReply, call), získajte ho takto:


use \Dotsystems\App\DotApp;
$dotApp = DotApp::DotApp();
            

Trasy registrujte pomocou Router::get (a ostatných metód HTTP slovies) v metóde initialize($dotApp) modulu.



Kľúčové vlastnosti DotApp

Jednoduchosť bez kompromisov

DotApp spája intuitívny návrh s vysokým výkonom. Nepotrebujete zložité nastavenia ani nadmerné konfigurácie – stačí definovať trasy a moduly a všetko ostatné sa spravuje samo. Trasy sa spracúvajú len tam, kde sú potrebné, a na zachovanie výkonu nie sú potrebné žiadne ďalšie kroky – všetko je automatické a efektívne.


// Example of simplicity when working with the DotApp framework
namespace Dotsystems\App\Modules\HelloWorld\Controllers;

class TestController1 extends \Dotsystems\App\Parts\Controller {
    public static function testMiddlewareFn($request) {
        return "Hello " . $request->body(); // Adds text at the beginning
    }
    
    public static function mainFn($request) {
        return $request->body() . "World"; // Adds text at the end
    }
}

// Simple controller call
// app/modules/HelloWorld/module.init.php → initialize($dotApp)
Router::get("/home", "HelloWorld:TestController1@mainFn!", Router::STATIC_ROUTE)
    ->before("HelloWorld:TestController1@testMiddlewareFn!");

// Result for /home: "Hello World"
            
Dôraz na nízku spotrebu zdrojov

DotApp drží požiadavky na pamäť na minime – namiesto načítavania obrovských štruktúr trás a konfigurácií spracúva len to, čo je práve potrebné. To znamená rýchlejší štart a výborný výkon aj na slabších serveroch.

Rýchle spracovanie trás

DotApp inteligentne filtruje iba relevantné moduly a ich trasy, čím odstraňuje zbytočné vyhľadávanie. Výsledkom je rýchle načítanie aj pri tisícoch trás.

Príklad

Ukážka rýchlosti smerovania: Pred zobrazením tejto stránky sa do routera automaticky a náhodne pridalo 1000 jedinečných statických a 1000 jedinečných dynamických, zámerne neusporiadaných trás. Cieľom bolo ukázať rýchle načítanie napriek 2000 extra zbytočným trasám. Žiadna z nich nezodpovedá aktuálnej URL, takže všetky musia prejsť procesom párovania v routeri.


$p = rtrim((string) Config::module('Docs', 'prefix'), '/') ?: '/documentation';

for ($i = 0; $i < 1000; $i++) {
    $path = $p . '/_routa' . $i;
    Router::any($path, function () use ($path) {
        return "This is route: " . $path;
    }, Router::STATIC_ROUTE);
}

for ($i = 0; $i < 1000; $i++) {
    $path = $p . '/_routa' . $i . '(?:/{language})?';
    Router::any($path, function () use ($path) {
        return "This is route: " . $path;
    });
}

// Try it out: /documentation/_routa7
                            


Zobrazenie stránky vrátane vytvorenia trás, smerovania a generovania kódu šablónovým systémom trvalo:

PHP version: 8.3.15 fpm-fcgi
Script execution time: 0.034020 s
Memory used by the script: 1022.48 KB
Peak memory usage: 1.55 MB
Loaded modules: 6

Modulárna efektivita s obojsmerným prepojením

DotApp spracúva iba trasy aktívneho modulu, čím šetrí zdroje. Moduly sa môžu navzájom načítavať: listener jedného modulu môže načítať iný a nadradený modul môže aktivovať podmoduly. Kombinácie zostávajú explicitné v module.listeners.php a initializeRoutes().

Kaskádové načítanie modulov

Ak modul závisí od iného (napr. BBB potrebuje XXX), DotApp automaticky načíta XXX pred dokončením BBB. To zaisťuje spoľahlivosť – žiadne chyby v dôsledku chýbajúcich závislostí – a systém zostáva ľahký, pretože sa načítava len to, čo je potrebné.

Dynamická správa závislostí cez triggery a listenere

Každý modul má triggery ako init.start, loading, loaded a ďalšie, na ktoré listenere reagujú. Napríklad listener dotapp.module.Module1.loading môže spustiť načítanie modulu 2, ak je modul 1 aktívny. Funkcia load() zaisťuje, že sa modul načíta iba raz, či už kaskádovo (zhora nadol) alebo obojsmerne (zdola nahor).

Poznámka: Názvy triggerov nerozlišujú veľkosť písmen, takže dotapp.module.Module1.loading a Dotapp.Module.Module1.Loading sú ekvivalentné, ale pre konzistenciu odporúčame formát dotapp.module.ClassName.eventName.


use Dotsystems\App\DotApp;
use Dotsystems\App\Parts\Events;

Events::on("dotapp.module.Shop.loading", function () {
    DotApp::DotApp()->module("Cart")->load();
});
            
Automatické riešenie závislostí a DI

Moduly a ich závislosti sa načítavajú automaticky – stačí definovať logiku v initializeCondition() alebo v listeneroch. Dependency Injection (DI) je jednoduchá a efektívna – služby sa registrujú (napr. singleton) a DotApp ich dodá tam, kde sú potrebné, bez zbytočnej réžie.

Služby registrujte v initialize($dotApp) modulu pomocou singleton / bind. Kontroléry sú public static a prijímajú $request.


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

namespace Dotsystems\App\Modules\HelloWorld\Controllers;

class Home extends \Dotsystems\App\Parts\Controller {
    public static function index($request) {
        $cache = \Dotsystems\App\DotApp::DotApp()->resolve('cache');
        return "Hello World";
    }
}
            
Prvý callback vyhráva

Pre každú URL sa zachová iba prvý zodpovedajúci callback – následné pokusy o registráciu sa ignorujú, čo zvyšuje výkon a predchádza konfliktom.


Router::get('/documentation/test1', "HelloWorld:Home@index!");
Router::get('/documentation/test1', function () { return "Ignored"; });
// Only the first definition is used
            
Škálovateľnosť pre malé aj veľké projekty

DotApp je ideálny pre malé weby aj komplexné aplikácie – nízke nároky a vysokú rýchlosť si zachováva bez ohľadu na rozsah projektu. Veľké moduly môžete rozdeliť na menšie časti, ktoré sa podľa potreby načítavajú rekurzívne.

Žiadna zbytočná réžia

DotApp sa sústreďuje na podstatu – rýchle smerovanie, minimálne využitie zdrojov a jednoduchosť použitia. Nezaťažuje vás funkciami, ktoré nepotrebujete.

Šablónový systém

Views a layouts žijú v module. Hodnoty vypisujte pomocou {{ var: $title }}, fragmenty vkladajte cez {{ layout:partials/header }} a z kontroléra vykresľujte cez Renderer::new()->module('HelloWorld')->setView('hello'). Úplná referencia: Šablónový systém.

DotApp Bridge

Živé prepojenie – most medzi frontendom a backendom. Stačí použiť jednoduchý kód:

<button {{ dotbridge:on(click)="newsletter.subscribe(newsletter.email)" }}>Subscribe</button>

a na strane PHP v initialize() modulu:


use Dotsystems\App\Parts\Bridge;
use Dotsystems\App\Parts\Router;

$urls = ['/newsletter', '/newsletter/'];
Bridge::listen($urls, "newsletter.subscribe", function ($request) {
    $email = $request->data(true)['data']['newsletter.email'] ?? '';
    return ['ok' => true, 'email' => $email];
}, Router::STATIC_ROUTE);
            

Tlačidlo sa automaticky prepojí s PHP funkciou; bohaté možnosti budú predstavené v dokumentácii.

Príklad vygenerovaného kódu:


<button  dotbridge-key="fBStFzi@3Gv5temaggmwP5S64pLsX-2" dotbridge-id="T6DAfzPB8hqcYGaH7niwg9UM353Ky6DYM0zh4GxjDd1ew3320260819151715171517121217158b7eb9400b350903eb22ca17e2bd7506" dotbridge-event="click" dotbridge-data="nb48HU4LbBYkDQyJeuN2+WpwTFRSbitDZGZ2ZDl0L21LOEVQUzNwQ2ZQamtVbjVka0E5L3RhZ1N1MFU9" dotbridge-data-id="4z8n/Z73DV4Rkh4xj/BHQXhqSVYyTzJGYlptdzMvTG9Wa3NYM2Zic1ZvZWdFMXkrTUpLWTJyRXE1ZVdhRzhBb1FiREYzVkZ4SThqbmZCL2pIVld4ZWpzajZiMzUyRDlFcllLSXJROVlTOFlzUyt0a1RQRFZNZGFZMmJrPQ==" dotbridge-function="newsletter.subscribe" dotbridge-inputs="newsletter.email">Subscribe</button>
            
HTML

DotApp je šitý na mieru vývojárom, ktorí chcú efektívny nástroj bez zbytočností. Ponúka rýchlosť, nízke nároky a jednoduchosť, ktorá uľahčuje prácu. Je to framework, ktorý dokazuje, že menej môže byť viac – s výsledkami, ktoré hovoria samy za seba.

Vyskúšajte DotApp a presvedčte sa sami!