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 se obnaša različno, odvisno od tega, ali deluje v razvojnem ali produkcijskem strežniku:
- 🛠️ Razvojni način
- Prikaže Tracyjev razhroščevalni niz z uporabnimi informacijami (npr. poizvedbe SQL, čas izvajanja, poraba pomnilnika).
- Prikaže podrobno stran z napakami s sledmi klicev funkcij in vsebino spremenljivk, ko pride do napake.
- Samodejno osveži predpomnilnik, ko se spremenijo predloge Latte, konfiguracijske datoteke itd.
- 🚀 Produkcijski način
- Ne prikaže nobenih informacij o odpravljanju napak; vse napake se zabeležijo.
- Prikaže stran
ErrorPresenter
ali splošno stran “Server Error” (Napaka strežnika), ko pride do napake. - Predpomnilnik se nikoli samodejno ne osveži!
- Optimizirano za hitrost in varnost.
Način se določi samodejno, zato ga v večini primerov ni treba ročno konfigurirati ali preklapljati:
- Razvojni način: (IP naslov
127.0.0.1
ali::1
), razen če je v uporabi posrednik (tj. na podlagi glave HTTP). - Produkcijski način: Aktivno povsod drugje.
Č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();
}