Filozofia
DotApp PHP Framework je od základu postavený na modularite. DotApp poskytuje robustný a škálovateľný základ pre moderné webové aplikácie a uprednostňuje modulárnu architektúru, aby zabezpečil flexibilitu, udržiavateľnosť a efektivitu.
Prečo modulárny návrh?
Modularita je jadrom filozofie DotApp. Štruktúrovaním aplikácií ako súboru nezávislých, znovupoužiteľných modulov DotApp umožňuje vývojárom:
- Stavať škálovateľné aplikácie s jasným oddelením zodpovedností.
- Znovu používať komponenty naprieč projektmi a skrátiť tak čas vývoja.
- Udržiavať a aktualizovať konkrétne časti aplikácie bez vplyvu na celý systém.
- Bezproblémovo integrovať nové funkcie alebo nástroje tretích strán.
Tento prístup zabezpečí, že vaše projekty ostanú usporiadané a prispôsobivé, či už staviate malý prototyp, alebo rozsiahlu podnikovú aplikáciu.
Robustný základ, odporúčané postupy
DotApp poskytuje pevný základ s nástrojmi a konvenciami prispôsobenými modulárnemu vývoju. V tomto sprievodcovi sa zameriavame na odporúčané postupy, ktoré sú v súlade s návrhovými cieľmi DotApp:
- Postup práce orientovaný na moduly: Organizujte aplikáciu do samostatných modulov kvôli prehľadnosti a škálovateľnosti.
- Konzistentná štruktúra: Dodržiavajte konvencie DotApp pre kontroléry, šablóny a konfigurácie, aby ste zjednodušili spoluprácu.
- Osvedčené postupy: Využívajte vstavané nástroje na routovanie, šablóny a správu modulov a vyhnite sa tak bežným chybám.
- Pripravenosť do budúcnosti: Stavajte modulárne, aby boli budúce rozšírenia alebo refaktoring jednoduché.
DotApp je dostatočne flexibilný aj na alternatívne prístupy, tento sprievodca však zdôrazňuje metódy, ktoré najlepšie využijú jeho modulárnu architektúru. Cieľom je naučiť vás techniky, ktoré maximalizujú prednosti frameworku a pomôžu vám vyhnúť sa neefektívnym alebo chybovým vzorom.
Čo ďalej?
Ste pripravení začať stavať s DotApp? Prejdite do sekcie Inštalácia a nastavte framework. Podrobnejší postup vytvorenia prvého modulu nájdete v sekcii Prvý modul a nastavenie.
S hrdosťou vytvorené na Slovensku 🇸🇰
Inštalácia
Inštalácia DotApp PHP Framework je rýchla a flexibilná. Na nastavenie projektu si vyberte jednu z troch metód nižšie. Každá z nich vedie k rovnakej modulárnej štruktúre projektu pripravenej na vývoj.
Možnosť 1: Git clone
Ak máte nainštalovaný Git, môžete klonovať repozitár DotApp priamo. V termináli spustite:
git clone https://github.com/dotsystems-sk/dotapp.git ./
Tým sa v aktuálnom adresári vytvorí projekt DotApp. Nemáte Git? Žiadny problém — vyskúšajte jednu z ďalších metód.
Možnosť 2: DotApper CLI
Stiahnite nástroj CLI dotapper.php a použite ho na inštaláciu DotApp. Postupujte takto:
- Stiahnite súbor: dotapper.php.
- Uložte ho do adresára projektu.
- Spustite inštalačný príkaz:
php dotapper.php --install
Tým sa nastaví DotApp so všetkými potrebnými závislosťami.
Možnosť 3: Stiahnutie ZIP
Preferujete ručný prístup? Stiahnite ZIP súbor DotApp a rozbaľte ho:
- Stiahnite ZIP: DotApp main.zip.
- Obsah rozbaľte do adresára projektu.
Po rozbalení je projekt pripravený na použitie.
Štruktúra projektu
Po inštalácii bude mať adresár projektu nasledujúcu modulárnu štruktúru:
project-root/
├── index.php
├── dotapper.php
├── app/
│ ├── config.php
│ ├── modules/ # your application logic
│ │ └── HelloWorld/
│ │ ├── module.init.php
│ │ ├── module.listeners.php
│ │ ├── Controllers/
│ │ ├── Middleware/
│ │ ├── Models/
│ │ ├── views/
│ │ └── assets/
│ ├── parts/ # framework core — do not edit
│ ├── runtime/
│ └── vendor/
└── assets/
├── dotapp/
└── modules/
Kontroléry, middleware, modely a view aplikácie patria do app/modules/{ModuleName}/. app/parts/ je jadro frameworku. Trasy sa deklarujú v module.init.php každého modulu.
Čo ďalej?
S nainštalovaným DotApp ste pripravení vytvoriť prvý modul. Pokračujte v sekcii Prvý modul a nastavenie a začnite stavať modulárnu aplikáciu.
Prvý modul a nastavenie
S nainštalovaným DotApp PHP Framework ste pripravení vytvoriť prvý modul. Moduly sú jadrom modulárnej architektúry DotApp a umožňujú organizovať aplikáciu do znovupoužiteľných, samostatných komponentov. V tejto sekcii vytvoríme modul HelloWorld a nakonfigurujeme ho tak, aby obsluhoval /helloworld.
Vytvorenie modulu
Nový modul vygenerujte pomocou DotApper CLI. V adresári projektu spustite:
php dotapper.php --create-module=HelloWorld
Uvidíte výstup:
Module successfully created in: ./app/modules/HelloWorld
Tým sa v adresári app/modules vytvorí nový modul HelloWorld.
Štruktúra modulu
Modul HelloWorld má nasledujúcu štruktúru:
├───modules
│ │ .gitkeep
│ │
│ └───HelloWorld
│ │ module.init.php
│ │ module.listeners.php
│ │
│ ├───Api
│ │ Api.php
│ │
│ ├───assets
│ │ howtouse.txt
│ │
│ ├───Controllers
│ │ Controller.php
│ │
│ ├───Libraries
│ ├───Middleware
│ ├───Models
│ ├───translations
│ └───views
│ │ clean.view.php
│ │
│ └───layouts
│ example.layout.php
Účel jednotlivých súborov a adresárov:
module.init.php: Definuje trasy modulu a podmienky inicializácie, čím riadi, kedy a ako sa modul načíta.module.listeners.php: Registruje poslucháčov udalostí modulu a umožňuje mu reagovať na udalosti frameworku, napríklad na načítanie modulu.Api/Api.php: Vzorový API kontrolér na stavbu API endpointov (môžete ho zmazať alebo ignorovať).assets/: Ukladá assety špecifické pre modul, napríklad CSS, JavaScript alebo obrázky. Obsahuje príručkuhowtouse.txtpre začiatočníkov.Controllers/Controller.php: Vzorový kontrolér (môžete ho zmazať alebo ignorovať).Libraries/: Obsahuje vlastné PHP knižnice alebo triedy špecifické pre modul.Middleware/: Obsahuje triedy middleware na spracovanie požiadaviek, napríklad autentifikáciu alebo validáciu.Models/: Ukladá triedy modelov pre prácu s databázou alebo business logiku.translations/: Spravuje jazykové súbory pre internacionalizáciu.views/: Obsahuje šablóny view, vrátaneclean.view.php(vzorový view) alayouts/example.layout.php(vzorový layout); oba môžete zmazať alebo ignorovať.
Vzorové súbory (Api.php, Controller.php, clean.view.php, example.layout.php) sú pridané ako príklady pre začiatočníkov. V tomto sprievodcovi vytvoríme vlastný kontrolér a view, takže tieto súbory môžete bezpečne zmazať alebo ignorovať.
Konfigurácia modulu
Nakonfigurujte modul HelloWorld tak, aby obsluhoval /helloworld.
Krok 1: Poslucháči udalostí
Vygenerovaný app/modules/HelloWorld/module.listeners.php je miesto pre udalosti modulu. Trasy patria do initialize() (ďalšie kroky). register() ponechajte prázdne, pokiaľ sa na udalosti neprihlasujete.
DotApp neskôr podľa potreby spúšťa niekoľko udalostí špecifických pre modul:
dotapp.module.HelloWorld.init.start: Spustí sa na začiatku inicializácie modulu.dotapp.module.HelloWorld.init.loading: Spustí sa, keď sa začnú načítavať hlavné funkcie modulu (napríklad trasy), ak sú splnené podmienky inicializácie.dotapp.module.HelloWorld.init.loaded: Spustí sa po načítaní trás a funkcií modulu.dotapp.module.HelloWorld.init.end: Spustí sa na konci inicializácie modulu, bez ohľadu na to, či boli podmienky splnené.dotapp.modules.loaded: Spustí sa po načítaní všetkých modulov.
Krok 2: Konfigurácia inicializácie modulu
Otvorte app/modules/HelloWorld/module.init.php a definujte, kedy sa má modul aktivovať. Upravte funkciu initializeRoutes tak, aby sa modul aktivoval pre trasy začínajúce na /helloworld:
public function initializeRoutes() {
return ['/helloworld', '/helloworld/*'];
}
Tým sa modul aktivuje iba pre URL začínajúce na /helloworld (napríklad /helloworld, /helloworld/, /helloworld/sekcia). Použitie ['*'] (aktivácia pre všetky URL) je menej efektívne a pre veľké projekty sa neodporúča, preto optimalizujeme zadaním prefixu trasy.
Ďalej nakonfigurujte funkciu initializeCondition, ktorá podľa zhody trasy určí, či sa má modul inicializovať. Predvolene ju nastavte na:
public function initializeCondition($routeMatch) {
return $routeMatch;
}
Tým sa modul aktivuje vždy, keď sa zhoduje trasa z initializeRoutes. Môžete pridať vlastnú logiku. Napríklad aktivácia iba v danom roku:
public function initializeCondition($routeMatch) {
if ($routeMatch === true) {
if (date("Y") == 2026) return true;
}
return false;
}
Tento príklad je iba ilustrácia. V tomto sprievodcovi ponechajte return $routeMatch;.
Krok 3: Definovanie počiatočných trás
V tom istom súbore module.init.php na začiatku importujte Config a Router a trasy definujte v initialize:
public function initialize($dotApp) {
Config::module('HelloWorld', 'prefix') ?? Config::module('HelloWorld', 'prefix', '/helloworld');
$p = rtrim((string) Config::module('HelloWorld', 'prefix'), '/');
Router::get($p, 'HelloWorld:Home@index!', Router::STATIC_ROUTE);
Router::get($p . '/', 'HelloWorld:Home@index!', Router::STATIC_ROUTE);
}
Tým sa nastavia statické trasy pre /helloworld a /helloworld/, ktoré smerujú na metódu index kontroléra Home v module HelloWorld. Router::STATIC_ROUTE sa zhoduje s presnou cestou.
Čo ďalej?
Modul HelloWorld je teraz vytvorený a nakonfigurovaný. Ďalej vytvoríme kontrolér Home na obsluhu trasy /helloworld. Pokračujte v sekcii Prvý kontrolér.
Prvý kontrolér
Po nakonfigurovaní modulu HelloWorld vytvorte kontrolér pre trasu /helloworld. Kontroléry sa nachádzajú v app/modules/{Module}/Controllers/. Tento sprievodca používa Home, čo je aj kontrolér dodávaný so živou ukážkou.
Vytvorenie kontroléra
Kontrolér Home vygenerujte pomocou DotApper CLI:
php dotapper.php --module=HelloWorld --create-controller=Home
Uvidíte:
Controller 'Home' successfully created!
Tým sa vytvorí app/modules/HelloWorld/Controllers/Home.php.
Nastavenie kontroléra
Otvorte tento súbor a implementujte index ako metódu public static. Živá ukážka vykresľuje view pomocou fasády Renderer. setView() musí prebehnúť pred setViewVar(). Ak view chýba, renderView() vráti prázdny reťazec.
namespace Dotsystems\App\Modules\HelloWorld\Controllers;
use Dotsystems\App\Parts\Logger;
use Dotsystems\App\Parts\Renderer;
use Dotsystems\App\Parts\Response;
class Home extends \Dotsystems\App\Parts\Controller
{
public static function index($request)
{
$html = Renderer::new()
->module('HelloWorld')
->setView('hello')
->setViewVar('title', 'Hello World')
->setViewVar('message', 'DotApp 2.0 is running.')
->renderView();
if ($html === '') {
Logger::use()->error('HelloWorld view produced empty output');
return new Response(500, 'Template error');
}
return $html;
}
}
Vytvorte app/modules/HelloWorld/views/hello.view.php ako kompletnú HTML stránku (živá ukážka pre túto obrazovku nepoužíva vnorený layout):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>{{ var: $title }}</title>
<link rel="stylesheet" href="/assets/modules/HelloWorld/css/hello.css" />
</head>
<body>
<main>
<h1>{{ var: $title }}</h1>
<p>{{ var: $message }}</p>
<p><a href="/documentation/step-by-step">Back to the guide</a></p>
</main>
</body>
</html>
Reťazec trasy je 'HelloWorld:Home@index!'. Koncové ! vypne dependency injection pre túto metódu. Prvým argumentom je vždy $request.
Čo ďalej?
Pokračujte v sekcii Hello World a otvorte stránku v prehliadači.
Hello World
Modul HelloWorld a kontrolér Home sú pripravené. Táto sekcia overí, že sa /helloworld vykreslí.
Testovanie aplikácie
Z koreňa projektu použite vstavaný PHP server:
php -S 127.0.0.1:8000
Potom otvorte http://127.0.0.1:8000/helloworld (alebo /helloworld/). Mali by ste vidieť nadpis Hello World a správu z view.
Zobrazenie stránky Hello World
Živá stránka poskytuje ten istý modul na adrese /helloworld. Výstup pochádza z app/modules/HelloWorld/Controllers/Home.php, ktorý vykresľuje views/hello.view.php.
Pochopenie toku
module.init.phpaktivuje modul pre/helloworlda/helloworld/*.- Statické trasy mapujú obe varianty s lomkou aj bez lomky na
HelloWorld:Home@index!. Home::indexzostaví HTML pomocouRenderer::new()->module('HelloWorld')->setView('hello').- Stránka dokumentácie poskytuje
/z modulu Docs. HelloWorld je dostupný na/helloworld.
Gratulujeme
Ďalej pridajte include layoutu a pomenovaný formulár. Pokračujte v sekcii Úvod do šablónového systému.
Úvod do šablónového systému
Hello World už view vykreslil. Táto sekcia pomenuje časti, aby ste stránku mohli rozširovať: súbory, fasádu Renderer a direktívy {{ … }}. Úplná referencia je v rozcestníku dokumentácie: Šablónový systém.
Súbory
- View —
app/modules/{Module}/views/{name}.view.php, vyberá sa pomocousetView('name'). - Layout —
app/modules/{Module}/views/layouts/{path}.layout.php, vyberá sa pomocousetLayout('path')alebo sa vkladá ako{{ layout:path }}. - Assety —
app/modules/{Module}/assets/..., dostupné ako/assets/modules/{Module}/....
{{ layout:h1-test }} načíta views/layouts/h1-test.layout.php. Názov neprefixujte s layouts/.
Renderer
$html = Renderer::new()
->module('HelloWorld')
->setView('hello')
->setViewVar('title', 'Hello World')
->renderView();
if ($html === '') {
return new Response(500, 'Template error');
}
- Volajte
setView()predsetViewVar(). - Druhý argument
setView()je záložný view, nie obalový layout. - Chýbajúci súbor vráti
""— bez výnimky. Reťazec skontrolujte. renderView()vidí iba premenné view. Všetko odovzdajte cezsetViewVar().
Direktívy
| Zápis | Význam |
|---|---|
{{ var: $title }} |
Vypíše hodnotu. Nie {{ $title }}. |
{{ if … }} … {{ /if }} |
Podmienka. Medzera za {{. |
{{ foreach $items as $item }} … {{ /foreach }} |
Cyklus. |
{{ layout:partials/header }} |
Vloží súbor layoutu. |
{{ content }} |
Slot pre setLayout() pri volaní renderView(). |
{{ formName(saveItem) }} |
Medzi <fo-rm method="POST"> a </fo-rm>. |
{{ enc(key): $id }} |
Zašifruje pole. Dešifrujte tým istým kľúčom. |
{{_ "Login" }} |
Preloží reťazec. |
Na stránkach, ktoré odosielajú <fo-rm> alebo volajú $dotapp().load(), načítajte /assets/dotapp/dotapp.js.
Čo ďalej
Ďalšia sekcia pridá do Hello World stránku poznámok: include layoutu, pomenovaný formulár a form() v kontroléri. Táto extra trasa je lokálne cvičenie — na verejnej ukážke nie je. Pre každú direktívu a pipeline vykresľovania otvorte Šablónový systém.
Hello World s formulárom a layoutom
Rozšírte živý modul HelloWorld vo vlastnej kópii projektu. Pridáte /helloworld/notes, vložíte malý layout a spracujete pomenovaný formulár. Verejná stránka ponecháva iba /helloworld.
Krok 1: Trasa
V app/modules/HelloWorld/module.init.php vedľa existujúcich trás /helloworld:
Router::match(
['GET', 'POST'],
['/helloworld/notes', '/helloworld/notes/'],
'HelloWorld:Home@index2!',
Router::STATIC_ROUTE
);
initializeRoutes() už vracia /helloworld/*, takže nová cesta sa načíta spolu s modulom. ! v reťazci kontroléra vypne dependency injection; metóda dostane iba $request.
Krok 2: Layout
Vytvorte app/modules/HelloWorld/views/layouts/notes-heading.layout.php:
<h1>{{ var: $heading }}</h1>
Krok 3: View
Vytvorte app/modules/HelloWorld/views/notes.view.php. {{ formName(saveNote) }} je vo vnútri <fo-rm>. Formulár nemá action, takže sa odosiela na aktuálnu URL.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>{{ var: $title }}</title>
<link rel="stylesheet" href="/assets/modules/HelloWorld/css/hello.css" />
</head>
<body>
<p>{{ var: $lead }}</p>
{{ if $saved }}
<p>You submitted: {{ var: $saved }}</p>
{{ /if }}
<fo-rm method="POST" id="noteForm">
<label for="note">Note</label>
<input type="text" id="note" name="note" placeholder="Text to echo" />
{{ formName(saveNote) }}
<button type="submit">{{ var: $btnText }}</button>
</fo-rm>
<h2>Tips from foreach</h2>
<ul>
{{ foreach $tips as $tip }}
<li>{{ var: $tip }}</li>
{{ /foreach }}
</ul>
<p><a href="/helloworld">Back to Hello World</a></p>
<script src="/assets/dotapp/dotapp.js"></script>
</body>
</html>
Táto stránka nepoužíva AJAX, takže dotapp.js je pri klasickom POST voliteľný. Skript ponechajte, ak neskôr naviažete $dotapp().form('#noteForm') ako v ukážke zabezpečených formulárov.
Krok 4: Kontrolér
V app/modules/HelloWorld/Controllers/Home.php pridajte index2. Do form() vždy odovzdajte callback chyby. Odovzdajte $request->getPath(), aby sa šifrovaný handler zhodoval s odoslanou URL (s koncovou lomkou aj bez nej).
public static function index2($request)
{
$saved = '';
$request->form(['POST'], 'saveNote', function ($request) use (&$saved) {
$saved = (string) ($request->data()['note'] ?? '');
}, function () {
// Required. Runs when the name does not match or the signature is invalid.
}, $request->getPath());
$html = Renderer::new()
->module('HelloWorld')
->setView('notes')
->setViewVar('title', 'Notes')
->setViewVar('heading', 'Notes')
->setViewVar('lead', 'Submit a line of text. The next render shows it below the heading.')
->setViewVar('btnText', 'Save')
->setViewVar('saved', $saved)
->setViewVar('tips', [
'setView() before setViewVar()',
'formName stays between fo-rm tags',
'Empty renderView() means a missing file',
])
->renderView();
if ($html === '') {
Logger::use()->error('HelloWorld notes view produced empty output');
return new Response(500, 'Template error');
}
return $html;
}
$request->data() je XSS-chránená kolekcia, ktorú chcete vypísať. Použite $request->data(true), keď dešifrujete alebo porovnávate tajomstvá. HTML reťazce v kontroléri nestavajte — odovzdajte dáta a formátujte ich vo view.
Vyskúšajte
Z koreňa projektu:
php -S 127.0.0.1:8000
Otvorte http://127.0.0.1:8000/helloworld/notes. Mali by ste vidieť nadpis z layoutu, tri tipy z foreach a formulár. Odošlite text; stránka sa znova načíta a zobrazí chránenú hodnotu.
Ďalej: Vyskúšať naživo pre verejnú stránku Hello World, alebo úplná referencia šablónového systému (direktívy, assety, vlastné renderery, sandbox).
Vyskúšať naživo
Modul HelloWorld z tohto sprievodcu beží na tejto stránke. Na zobrazenie prvej stránky nepotrebujete lokálny server.
Hello World
Otvorte /helloworld. Ide o HelloWorld:Home@index!, ktoré vykresľuje views/hello.view.php pomocou Renderer::new().
Stránka poznámok (iba lokálne)
Cvičenie s formulárom a layoutom z predchádzajúcej sekcie (/helloworld/notes) tu nie je nasadené. Túto trasu pridajte vo vlastnej kópii a porovnajte ju s verejnou stránkou.
Čo čítať ďalej
- Šablónový systém — všetky direktívy, assety, vlastné renderery, sandbox.
- Zabezpečené formuláre —
fo-rm, CRC, šifrované polia. - Príklady — živé ukážky.