Nette Documentation Preview

syntax
Bootstrap
*********

<div class=perex>

Bootstrap este codul de pornire care inițializează mediul, creează un container de injecție a dependențelor (DI) și pornește aplicația. Vom discuta despre:

- cum să vă configurați aplicația utilizând fișiere NEON
- cum să gestionați modurile de producție și de dezvoltare
- cum să creați containerul DI

</div>


Aplicațiile, fie că sunt bazate pe web sau scripturi în linie de comandă, încep printr-o anumită formă de inițializare a mediului. În vremurile vechi, putea fi un fișier numit eg `include.inc.php` care se ocupa de acest lucru și care era inclus în fișierul inițial.
În aplicațiile moderne Nette, acesta a fost înlocuit de clasa `Bootstrap`, care, ca parte a aplicației, poate fi găsită în fișierul `app/Bootstrap.php`. Acesta ar putea arăta de exemplu astfel:

```php
use Nette\Bootstrap\Configurator;

class Bootstrap
{
	public static function boot(): Configurator
	{
		$appDir = dirname(__DIR__);
		$configurator = new Configurator;
		//$configurator->setDebugMode('secret@23.75.345.200');
		$configurator->enableTracy($appDir . '/log');
		$configurator->setTempDirectory($appDir . '/temp');
		$configurator->createRobotLoader()
			->addDirectory(__DIR__)
			->register();
		$configurator->addConfig($appDir . '/config/common.neon');
		return $configurator;
	}
}
```


index.php .[#toc-index-php]
===========================

În cazul aplicațiilor web, fișierul inițial este `index.php`, care se află în directorul public `www/`. Acesta permite clasei `Bootstrap` să inițializeze mediul și să returneze `$configurator` care creează containerul DI. Apoi se obține serviciul `Application`, care execută aplicația web:

```php
// inițializarea mediului + obținerea obiectului Configurator
$configurator = App\Bootstrap::boot();
// creați un container DI
$container = $configurator->createContainer();
// containerul DI creează un obiect Nette\Application\Application
$application = $container->getByType(Nette\Application\Application::class);
// pornește aplicația Nette
$application->run();
```

După cum puteți vedea, clasa [api:Nette\Bootstrap\Configurator], pe care o vom prezenta acum mai în detaliu, ajută la configurarea mediului și la crearea unui container de injecție a dependențelor (DI).


Modul de dezvoltare vs. modul de producție .[#toc-development-vs-production-mode]
=================================================================================

Nette face distincție între două moduri de bază în care este executată o cerere: dezvoltare și producție. Modul de dezvoltare este axat pe confortul maxim al programatorului, Tracy este afișat, memoria cache este actualizată automat atunci când se schimbă șabloanele sau configurația containerului DI etc. Modul de producție este axat pe performanță, Tracy înregistrează doar erorile, iar modificările șabloanelor și ale altor fișiere nu sunt verificate.

Selectarea modului se face prin autodetecție, astfel încât, de obicei, nu este nevoie să configurați sau să comutați nimic manual. Modul este dezvoltare dacă aplicația rulează pe localhost (adică adresa IP `127.0.0.1` sau `::1`) și nu este prezent niciun proxy (adică antetul său HTTP). În caz contrar, se execută în modul de producție.

Dacă doriți să activați modul de dezvoltare în alte cazuri, de exemplu, pentru programatorii care accesează de la o anumită adresă IP, puteți utiliza `setDebugMode()`:

```php
$configurator->setDebugMode('23.75.345.200'); // una sau mai multe adrese IP
```

Vă recomandăm cu siguranță să combinați o adresă IP cu un cookie. Vom stoca un token secret în cookie-ul `nette-debug`, de exemplu `secret1234`, iar modul de dezvoltare va fi activat pentru programatorii cu această combinație de IP și cookie.

```php
$configurator->setDebugMode('secret1234@23.75.345.200');
```

De asemenea, putem dezactiva complet modul de dezvoltare, chiar și pentru localhost:

```php
$configurator->setDebugMode(false);
```

Rețineți că valoarea `true` activează modul dezvoltator din greu, ceea ce nu ar trebui să se întâmple niciodată pe un server de producție.


Instrumentul de depanare Tracy .[#toc-debugging-tool-tracy]
===========================================================

Pentru o depanare mai ușoară, vom porni minunata unealtă [Tracy |tracy:]. În modul dezvoltator, acesta vizualizează erorile, iar în modul de producție înregistrează erorile în directorul specificat:

```php
$configurator->enableTracy($appDir . '/log');
```


Temporary Files .[#toc-temporary-files]
=======================================

Nette utilizează memoria cache pentru DI container, RobotLoader, șabloane etc. Prin urmare, este necesar să setați calea către directorul în care va fi stocată memoria cache:

```php
$configurator->setTempDirectory($appDir . '/temp');
```

Pe Linux sau macOS, setați [permisiunile de scriere |nette:troubleshooting#Setting directory permissions] pentru directoarele `log/` și `temp/`.


RobotLoader .[#toc-robotloader]
===============================

De obicei, vom dori să încărcăm automat clasele folosind [RobotLoader |robot-loader:], așa că trebuie să îl pornim și să îl lăsăm să încarce clasele din directorul în care se află `Bootstrap.php` (adică `__DIR__`) și din toate subdirectoarele sale:

```php
$configurator->createRobotLoader()
	->addDirectory(__DIR__)
	->register();
```

O modalitate alternativă este de a utiliza doar încărcarea automată [Composer |best-practices:composer] PSR-4.


Fusul orar .[#toc-timezone]
===========================

Configurator vă permite să specificați un fus orar pentru aplicația dumneavoastră.

```php
$configurator->setTimeZone('Europe/Prague');
```


Configurarea containerului DI .[#toc-di-container-configuration]
================================================================

O parte a procesului de pornire constă în crearea unui container DI, adică a unei fabrici de obiecte, care reprezintă inima întregii aplicații. Acesta este de fapt o clasă PHP generată de Nette și stocată într-un director de cache. Fabrica produce obiectele cheie ale aplicației, iar fișierele de configurare o instruiesc cum să le creeze și să le configureze și, astfel, influențăm comportamentul întregii aplicații.

Fișierele de configurare sunt de obicei scrise în [formatul NEON |neon:format]. Puteți citi [ce poate fi configurat aici |nette:configuring].

.[tip]
În modul de dezvoltare, containerul este actualizat automat de fiecare dată când modificați codul sau fișierele de configurare. În modul de producție, acesta este generat o singură dată, iar modificările fișierelor nu sunt verificate pentru a maximiza performanța.

Fișierele de configurare sunt încărcate utilizând `addConfig()`:

```php
$configurator->addConfig($appDir . '/config/common.neon');
```

Metoda `addConfig()` poate fi apelată de mai multe ori pentru a adăuga mai multe fișiere.

```php
$configurator->addConfig($appDir . '/config/common.neon');
$configurator->addConfig($appDir . '/config/services.neon');
if (PHP_SAPI === 'cli') {
	$configurator->addConfig($appDir . '/config/cli.php');
}
```

Numele `cli.php` nu este o greșeală de tipar, deoarece configurația poate fi scrisă și într-un fișier PHP, care o returnează sub forma unei matrice.

Alternativ, putem folosi [secțiunea`includes`  |dependency-injection:configuration#including files] pentru a încărca mai multe fișiere de configurare.

Dacă în fișierele de configurare apar elemente cu aceleași chei în cadrul fișierelor de configurare, acestea vor fi [suprascrise sau fuzionate |dependency-injection:configuration#Merging] în cazul array-urilor. Ultimul fișier inclus are o prioritate mai mare decât cel anterior. Fișierul în care este listată secțiunea `includes` are o prioritate mai mare decât fișierele incluse în el.


Parametrii statici .[#toc-static-parameters]
--------------------------------------------

Parametrii utilizați în fișierele de configurare pot fi definiți [în secțiunea `parameters` |dependency-injection:configuration#parameters] și, de asemenea, pot fi trecuți (sau suprascriși) prin metoda `addStaticParameters()` (are pseudonimul `addParameters()`). Este important ca valorile diferite ale parametrilor să determine generarea de containere DI suplimentare, adică de clase suplimentare.

```php
$configurator->addStaticParameters([
	'projectId' => 23,
]);
```

În fișierele de configurare, putem scrie notația obișnuită `%projectId%` pentru a accesa parametrul numit `projectId`.


Parametrii dinamici .[#toc-dynamic-parameters]
----------------------------------------------

De asemenea, putem adăuga parametri dinamici la container, valorile lor diferite, spre deosebire de parametrii statici, nu vor determina generarea de noi containere DI.

```php
$configurator->addDynamicParameters([
	'remoteIp' => $_SERVER['REMOTE_ADDR'],
]);
```

Variabilele de mediu ar putea fi puse cu ușurință la dispoziție prin intermediul parametrilor dinamici. Le putem accesa prin intermediul `%env.variable%` în fișierele de configurare.

```php
$configurator->addDynamicParameters([
	'env' => getenv(),
]);
```


Parametrii impliciți .[#toc-default-parameters]
-----------------------------------------------

Puteți utiliza următorii parametri statici în fișierele de configurare:

- `%appDir%` este calea absolută către directorul fișierului `Bootstrap.php`
- `%wwwDir%` este calea absolută către directorul care conține fișierul de intrare `index.php`
- `%tempDir%` este calea absolută către directorul pentru fișierele temporare
- `%vendorDir%` este calea absolută către directorul în care Composer instalează bibliotecile
- `%debugMode%` indică dacă aplicația se află în modul de depanare
- `%consoleMode%` indică dacă cererea a venit prin linia de comandă


Servicii importate .[#toc-imported-services]
--------------------------------------------

Acum mergem mai departe. Deși scopul unui container DI este acela de a crea obiecte, în mod excepțional poate fi nevoie să se introducă un obiect existent în container. Facem acest lucru prin definirea serviciului cu atributul `imported: true`.

```neon
services:
	myservice:
		type: App\Model\MyCustomService
		imported: true
```

Creați o nouă instanță și inserați-o în bootstrap:

```php
$configurator->addServices([
	'myservice' => new App\Model\MyCustomService('foobar'),
]);
```


Diferite medii .[#toc-different-environments]
=============================================

Nu ezitați să personalizați clasa `Bootstrap` pentru a se potrivi nevoilor dumneavoastră. Puteți adăuga parametri la metoda `boot()` pentru a diferenția proiectele web sau puteți adăuga alte metode, cum ar fi `bootForTests()`, care inițializează mediul pentru testele unitare, `bootForCli()` pentru scripturile apelate din linia de comandă și așa mai departe.

```php
public static function bootForTests(): Configurator
{
	$configurator = self::boot();
	Tester\Environment::setup(); // Inițializarea Nette Tester
	return $configurator;
}
```

Bootstrap

Bootstrap este codul de pornire care inițializează mediul, creează un container de injecție a dependențelor (DI) și pornește aplicația. Vom discuta despre:

  • cum să vă configurați aplicația utilizând fișiere NEON
  • cum să gestionați modurile de producție și de dezvoltare
  • cum să creați containerul DI

Aplicațiile, fie că sunt bazate pe web sau scripturi în linie de comandă, încep printr-o anumită formă de inițializare a mediului. În vremurile vechi, putea fi un fișier numit eg include.inc.php care se ocupa de acest lucru și care era inclus în fișierul inițial. În aplicațiile moderne Nette, acesta a fost înlocuit de clasa Bootstrap, care, ca parte a aplicației, poate fi găsită în fișierul app/Bootstrap.php. Acesta ar putea arăta de exemplu astfel:

use Nette\Bootstrap\Configurator;

class Bootstrap
{
	public static function boot(): Configurator
	{
		$appDir = dirname(__DIR__);
		$configurator = new Configurator;
		//$configurator->setDebugMode('secret@23.75.345.200');
		$configurator->enableTracy($appDir . '/log');
		$configurator->setTempDirectory($appDir . '/temp');
		$configurator->createRobotLoader()
			->addDirectory(__DIR__)
			->register();
		$configurator->addConfig($appDir . '/config/common.neon');
		return $configurator;
	}
}

index.php

În cazul aplicațiilor web, fișierul inițial este index.php, care se află în directorul public www/. Acesta permite clasei Bootstrap să inițializeze mediul și să returneze $configurator care creează containerul DI. Apoi se obține serviciul Application, care execută aplicația web:

// inițializarea mediului + obținerea obiectului Configurator
$configurator = App\Bootstrap::boot();
// creați un container DI
$container = $configurator->createContainer();
// containerul DI creează un obiect Nette\Application\Application
$application = $container->getByType(Nette\Application\Application::class);
// pornește aplicația Nette
$application->run();

După cum puteți vedea, clasa Nette\Bootstrap\Configurator, pe care o vom prezenta acum mai în detaliu, ajută la configurarea mediului și la crearea unui container de injecție a dependențelor (DI).

Modul de dezvoltare vs. modul de producție

Nette face distincție între două moduri de bază în care este executată o cerere: dezvoltare și producție. Modul de dezvoltare este axat pe confortul maxim al programatorului, Tracy este afișat, memoria cache este actualizată automat atunci când se schimbă șabloanele sau configurația containerului DI etc. Modul de producție este axat pe performanță, Tracy înregistrează doar erorile, iar modificările șabloanelor și ale altor fișiere nu sunt verificate.

Selectarea modului se face prin autodetecție, astfel încât, de obicei, nu este nevoie să configurați sau să comutați nimic manual. Modul este dezvoltare dacă aplicația rulează pe localhost (adică adresa IP 127.0.0.1 sau ::1) și nu este prezent niciun proxy (adică antetul său HTTP). În caz contrar, se execută în modul de producție.

Dacă doriți să activați modul de dezvoltare în alte cazuri, de exemplu, pentru programatorii care accesează de la o anumită adresă IP, puteți utiliza setDebugMode():

$configurator->setDebugMode('23.75.345.200'); // una sau mai multe adrese IP

Vă recomandăm cu siguranță să combinați o adresă IP cu un cookie. Vom stoca un token secret în cookie-ul nette-debug, de exemplu secret1234, iar modul de dezvoltare va fi activat pentru programatorii cu această combinație de IP și cookie.

$configurator->setDebugMode('secret1234@23.75.345.200');

De asemenea, putem dezactiva complet modul de dezvoltare, chiar și pentru localhost:

$configurator->setDebugMode(false);

Rețineți că valoarea true activează modul dezvoltator din greu, ceea ce nu ar trebui să se întâmple niciodată pe un server de producție.

Instrumentul de depanare Tracy

Pentru o depanare mai ușoară, vom porni minunata unealtă Tracy. În modul dezvoltator, acesta vizualizează erorile, iar în modul de producție înregistrează erorile în directorul specificat:

$configurator->enableTracy($appDir . '/log');

Temporary Files

Nette utilizează memoria cache pentru DI container, RobotLoader, șabloane etc. Prin urmare, este necesar să setați calea către directorul în care va fi stocată memoria cache:

$configurator->setTempDirectory($appDir . '/temp');

Pe Linux sau macOS, setați permisiunile de scriere pentru directoarele log/ și temp/.

RobotLoader

De obicei, vom dori să încărcăm automat clasele folosind RobotLoader, așa că trebuie să îl pornim și să îl lăsăm să încarce clasele din directorul în care se află Bootstrap.php (adică __DIR__) și din toate subdirectoarele sale:

$configurator->createRobotLoader()
	->addDirectory(__DIR__)
	->register();

O modalitate alternativă este de a utiliza doar încărcarea automată Composer PSR-4.

Fusul orar

Configurator vă permite să specificați un fus orar pentru aplicația dumneavoastră.

$configurator->setTimeZone('Europe/Prague');

Configurarea containerului DI

O parte a procesului de pornire constă în crearea unui container DI, adică a unei fabrici de obiecte, care reprezintă inima întregii aplicații. Acesta este de fapt o clasă PHP generată de Nette și stocată într-un director de cache. Fabrica produce obiectele cheie ale aplicației, iar fișierele de configurare o instruiesc cum să le creeze și să le configureze și, astfel, influențăm comportamentul întregii aplicații.

Fișierele de configurare sunt de obicei scrise în formatul NEON. Puteți citi ce poate fi configurat aici.

În modul de dezvoltare, containerul este actualizat automat de fiecare dată când modificați codul sau fișierele de configurare. În modul de producție, acesta este generat o singură dată, iar modificările fișierelor nu sunt verificate pentru a maximiza performanța.

Fișierele de configurare sunt încărcate utilizând addConfig():

$configurator->addConfig($appDir . '/config/common.neon');

Metoda addConfig() poate fi apelată de mai multe ori pentru a adăuga mai multe fișiere.

$configurator->addConfig($appDir . '/config/common.neon');
$configurator->addConfig($appDir . '/config/services.neon');
if (PHP_SAPI === 'cli') {
	$configurator->addConfig($appDir . '/config/cli.php');
}

Numele cli.php nu este o greșeală de tipar, deoarece configurația poate fi scrisă și într-un fișier PHP, care o returnează sub forma unei matrice.

Alternativ, putem folosi secțiuneaincludes pentru a încărca mai multe fișiere de configurare.

Dacă în fișierele de configurare apar elemente cu aceleași chei în cadrul fișierelor de configurare, acestea vor fi suprascrise sau fuzionate în cazul array-urilor. Ultimul fișier inclus are o prioritate mai mare decât cel anterior. Fișierul în care este listată secțiunea includes are o prioritate mai mare decât fișierele incluse în el.

Parametrii statici

Parametrii utilizați în fișierele de configurare pot fi definiți în secțiunea parameters și, de asemenea, pot fi trecuți (sau suprascriși) prin metoda addStaticParameters() (are pseudonimul addParameters()). Este important ca valorile diferite ale parametrilor să determine generarea de containere DI suplimentare, adică de clase suplimentare.

$configurator->addStaticParameters([
	'projectId' => 23,
]);

În fișierele de configurare, putem scrie notația obișnuită %projectId% pentru a accesa parametrul numit projectId.

Parametrii dinamici

De asemenea, putem adăuga parametri dinamici la container, valorile lor diferite, spre deosebire de parametrii statici, nu vor determina generarea de noi containere DI.

$configurator->addDynamicParameters([
	'remoteIp' => $_SERVER['REMOTE_ADDR'],
]);

Variabilele de mediu ar putea fi puse cu ușurință la dispoziție prin intermediul parametrilor dinamici. Le putem accesa prin intermediul %env.variable% în fișierele de configurare.

$configurator->addDynamicParameters([
	'env' => getenv(),
]);

Parametrii impliciți

Puteți utiliza următorii parametri statici în fișierele de configurare:

  • %appDir% este calea absolută către directorul fișierului Bootstrap.php
  • %wwwDir% este calea absolută către directorul care conține fișierul de intrare index.php
  • %tempDir% este calea absolută către directorul pentru fișierele temporare
  • %vendorDir% este calea absolută către directorul în care Composer instalează bibliotecile
  • %debugMode% indică dacă aplicația se află în modul de depanare
  • %consoleMode% indică dacă cererea a venit prin linia de comandă

Servicii importate

Acum mergem mai departe. Deși scopul unui container DI este acela de a crea obiecte, în mod excepțional poate fi nevoie să se introducă un obiect existent în container. Facem acest lucru prin definirea serviciului cu atributul imported: true.

services:
	myservice:
		type: App\Model\MyCustomService
		imported: true

Creați o nouă instanță și inserați-o în bootstrap:

$configurator->addServices([
	'myservice' => new App\Model\MyCustomService('foobar'),
]);

Diferite medii

Nu ezitați să personalizați clasa Bootstrap pentru a se potrivi nevoilor dumneavoastră. Puteți adăuga parametri la metoda boot() pentru a diferenția proiectele web sau puteți adăuga alte metode, cum ar fi bootForTests(), care inițializează mediul pentru testele unitare, bootForCli() pentru scripturile apelate din linia de comandă și așa mai departe.

public static function bootForTests(): Configurator
{
	$configurator = self::boot();
	Tester\Environment::setup(); // Inițializarea Nette Tester
	return $configurator;
}