Bootstrap
Bootstrap je zagonska koda, ki inicializira okolje, ustvari vsebnik za vbrizgavanje odvisnosti (DI) in zažene aplikacijo. Obravnavali bomo:
- kako konfigurirati aplikacijo z datotekami NEON
- kako ravnati s produkcijskim in razvojnim načinom
- kako ustvariti vsebnik DI
Aplikacije, ne glede na to, ali temeljijo na spletu ali skripti ukazne vrstice, se začnejo z določeno obliko inicializacije
okolja. V starih časih je bila za to lahko odgovorna datoteka z imenom npr. include.inc.php
, ki je bila vključena
v začetno datoteko. V sodobnih aplikacijah Nette jo je nadomestil razred Bootstrap
, ki se kot del aplikacije
nahaja v datoteki app/Bootstrap.php
. Izgleda lahko na primer takole:
use Nette\Bootstrap\Configurator;
class Bootstrap
{
private Configurator $configurator;
private string $rootDir;
public function __construct()
{
$this->rootDir = dirname(__DIR__);
// Konfigurator je odgovoren za nastavitev okolja aplikacije in storitev.
$this->configurator = new Configurator;
// Nastavite imenik za začasne datoteke, ki jih ustvari Nette (npr. sestavljene predloge).
$this->configurator->setTempDirectory($this->rootDir . '/temp');
}
public function bootWebApplication(): Nette\DI\Container
{
$this->initializeEnvironment();
$this->setupContainer();
return $this->configurator->createContainer();
}
private function initializeEnvironment(): void
{
// Program Nette je pameten in razvojni način se vklopi samodejno,
// lahko pa ga za določen naslov IP omogočite tako, da odkomentirate naslednjo vrstico:
// $this->configurator->setDebugMode('secret@23.75.345.200');
// Omogoči Tracy: najboljše orodje za razhroščevanje "švicarskega noža".
$this->configurator->enableTracy($this->rootDir . '/log');
// RobotLoader: samodejno naloži vse razrede v danem imeniku
$this->configurator->createRobotLoader()
->addDirectory(__DIR__)
->register();
}
private function setupContainer(): void
{
// Nalaganje konfiguracijskih datotek
$this->configurator->addConfig($this->rootDir . '/config/common.neon');
}
}
index.php
Začetna datoteka za spletne aplikacije je index.php
, ki se nahaja v javnem imeniku www/
. Uporablja
razred Bootstrap
za inicializacijo okolja in ustvarjanje vsebnika DI. Nato iz vsebnika pridobi storitev
Application
, ki zažene spletno aplikacijo:
$bootstrap = new App\Bootstrap;
// Inicializacija okolja + ustvarjanje vsebnika DI
$container = $bootstrap->bootWebApplication();
// vsebnik DI ustvari objekt Nette\Application\Application
$application = $container->getByType(Nette\Application\Application::class);
// Zagnati aplikacijo Nette in obdelati vhodno zahtevo
$application->run();
Kot vidite, razred Nette\Bootstrap\Configurator, ki ga bomo zdaj podrobneje predstavili, pomaga pri vzpostavljanju okolja in ustvarjanju vsebnika za vbrizgavanje odvisnosti (DI).
Razvojni in produkcijski način
Nette razlikuje med dvema osnovnima načinoma izvajanja zahtevka: razvojnim in produkcijskim. Razvojni način je osredotočen na čim večje udobje programerja, prikazan je Tracy, predpomnilnik se samodejno posodablja ob spreminjanju predlog ali konfiguracije vsebnika DI itd. Produkcijski način je osredotočen na zmogljivost, Tracy beleži le napake, spremembe predlog in drugih datotek pa se ne preverjajo.
Izbira načina poteka s samodejnim zaznavanjem, zato običajno ni treba ničesar ročno konfigurirati ali preklapljati. Način
je razvojni, če aplikacija teče na lokalnem gostitelju (tj. naslov IP 127.0.0.1
ali ::1
) in ni
prisoten posrednik (tj. njegova glavička HTTP). V nasprotnem primeru deluje v produkcijskem načinu.
Če želite omogočiti razvojni način v drugih primerih, na primer za programerje, ki dostopajo z določenega naslova IP,
lahko uporabite setDebugMode()
:
$this->configurator->setDebugMode('23.75.345.200'); // enega ali več naslovov IP.
Vsekakor priporočamo kombinacijo naslova IP s piškotkom. V piškotek nette-debug
bomo shranili tajni žeton,
npr. secret1234
, razvojni način pa bo aktiviran za programerje s to kombinacijo IP in piškotka.
$this->configurator->setDebugMode('secret1234@23.75.345.200');
Razvojni način lahko tudi popolnoma izklopimo, tudi za lokalni gostitelj:
$this->configurator->setDebugMode(false);
Vrednost true
vklopi način za razvijalce, kar se na produkcijskem strežniku ne bi smelo zgoditi.
Orodje za razhroščevanje Tracy
Za lažje razhroščevanje bomo vklopili odlično orodje Tracy. V načinu za razvijalce vizualizira napake, v produkcijskem načinu pa napake beleži v določen imenik:
$this->configurator->enableTracy($this->rootDir . '/log');
Začasne datoteke
Nette uporablja predpomnilnik za vsebnik DI, RobotLoader, predloge itd. Zato je treba nastaviti pot do imenika, v katerem bo shranjen predpomnilnik:
$this->configurator->setTempDirectory($this->rootDir . '/temp');
V operacijskem sistemu Linux ali macOS nastavite dovoljenja za pisanje za imenike
log/
in temp/
.
RobotLoader
Običajno bomo želeli samodejno naložiti razrede z RobotLoaderjem, zato ga moramo zagnati in
mu omogočiti, da naloži razrede iz imenika, kjer se nahaja Bootstrap.php
(tj. __DIR__
), in vseh
njegovih podimenikov:
$this->configurator->createRobotLoader()
->addDirectory(__DIR__)
->register();
Druga možnost je, da uporabimo samo samodejno nalaganje Composer PSR-4.
Časovni pas
Configurator vam omogoča, da določite časovni pas za svojo aplikacijo.
$this->configurator->setTimeZone('Europe/Prague');
Konfiguracija zabojnika DI
Del zagonskega postopka je ustvarjanje vsebnika DI, tj. tovarne za predmete, ki je srce celotne aplikacije. To je pravzaprav razred PHP, ki ga ustvari Nette in je shranjen v imeniku predpomnilnika. Tovarna izdeluje ključne objekte aplikacije, konfiguracijske datoteke pa ji dajejo navodila, kako naj jih ustvari in konfigurira, s čimer vplivamo na obnašanje celotne aplikacije.
Konfiguracijske datoteke so običajno zapisane v formatu NEON. Kaj vse je mogoče konfigurirati, si lahko preberete tukaj.
V razvojnem načinu se vsebnik samodejno posodobi vsakič, ko spremenite kodo ali konfiguracijske datoteke. V produkcijskem načinu se ustvari samo enkrat, spremembe datotek pa se ne preverjajo, da bi povečali zmogljivost.
Konfiguracijske datoteke se naložijo z uporabo addConfig()
:
$this->configurator->addConfig($this->rootDir . '/config/common.neon');
Metodo addConfig()
lahko za dodajanje več datotek pokličete večkrat.
$configDir = $this->rootDir . '/config';
$this->configurator->addConfig($configDir . '/common.neon');
$this->configurator->addConfig($configDir . '/services.neon');
if (PHP_SAPI === 'cli') {
$this->configurator->addConfig($configDir . '/cli.php');
}
Ime cli.php
ni tiskarska napaka, konfiguracijo lahko zapišete tudi v datoteko PHP, ki jo vrne kot polje.
Druga možnost je, da z razdelkomincludes
naložimo več
konfiguracijskih datotek.
Če se v konfiguracijskih datotekah pojavijo elementi z enakimi ključi, se bodo prepisali ali združili v primeru polj. Kasneje vključena datoteka
ima višjo prioriteto kot prejšnja. Datoteka, v kateri je naveden razdelek includes
, ima višjo prednost kot
datoteke, ki so vanjo vključene.
Statični parametri
Parametre, ki se uporabljajo v konfiguracijskih datotekah, je mogoče opredeliti v razdelku parameters
in jih tudi posredovati (ali
prepisati) z metodo addStaticParameters()
(ima vzdevek addParameters()
). Pomembno je, da različne
vrednosti parametrov povzročijo generiranje dodatnih vsebnikov DI, tj. dodatnih razredov.
$this->configurator->addStaticParameters([
'projectId' => 23,
]);
V konfiguracijskih datotekah lahko zapišemo običajni zapis %projectId%
za dostop do parametra z imenom
projectId
.
Dinamični parametri
Kontejnerju lahko dodamo tudi dinamične parametre, katerih različne vrednosti za razliko od statičnih parametrov ne bodo povzročile generiranja novih DI kontejnerjev.
$this->configurator->addDynamicParameters([
'remoteIp' => $_SERVER['REMOTE_ADDR'],
]);
Spremenljivke okolja bi lahko preprosto dali na voljo z dinamičnimi parametri. Do njih lahko dostopamo prek spletne strani
%env.variable%
v konfiguracijskih datotekah.
$this->configurator->addDynamicParameters([
'env' => getenv(),
]);
Privzete parametre
V konfiguracijskih datotekah lahko uporabite naslednje statične parametre:
%appDir%
je absolutna pot do imenika datotekeBootstrap.php
.%wwwDir%
je absolutna pot do imenika, ki vsebuje vstopno datotekoindex.php
%tempDir%
je absolutna pot do imenika za začasne datoteke%vendorDir%
je absolutna pot do imenika, v katerega Composer namesti knjižnice%rootDir%
je absolutna pot do korenskega imenika projekta%debugMode%
označuje, ali je aplikacija v načinu odpravljanja napak%consoleMode%
označuje, ali je bila zahteva poslana prek ukazne vrstice
Uvožene storitve
Zdaj se bomo poglobili. Čeprav je namen vsebnika DI ustvarjanje objektov, se lahko izjemoma pojavi potreba po vstavitvi
obstoječega objekta v vsebnik. To storimo tako, da definiramo storitev z atributom imported: true
.
services:
myservice:
type: App\Model\MyCustomService
imported: true
Ustvarite nov primerek in ga vstavite v bootstrap:
$this->configurator->addServices([
'myservice' => new App\Model\MyCustomService('foobar'),
]);
Različna okolja
Ne oklevajte, če želite razred Bootstrap
prilagoditi svojim potrebam. Metodi bootWebApplication()
lahko dodate parametre za razlikovanje med spletnimi projekti. Lahko pa dodate tudi druge metode, na primer
bootTestEnvironment()
za inicializacijo okolja za teste enote, bootConsoleApplication()
za skripte, ki
se kličejo iz ukazne vrstice, in tako naprej.
public function bootTestEnvironment(): Nette\DI\Container
{
Tester\Environment::setup(); // Inicializacija Nette Testerja
$this->setupContainer();
return $this->configurator->createContainer();
}
public function bootConsoleApplication(): Nette\DI\Container
{
$this->configurator->setDebugMode(false);
$this->initializeEnvironment();
$this->setupContainer();
return $this->configurator->createContainer();
}